Project

General

Profile

Download (11.3 KB) Statistics
| Branch: | Tag: | Revision:
1
// see also https://github.com/geetarista/jquery-plugin-template/blob/master/jquery.plugin-template.js
2

    
3
/**
4
 * Expected DOM structure:
5
 *
6
 * <div id="cdm_taxontree_parent">
7
 *      <div class="cdm_taxontree_scroller_xy">
8
 *              <ul class="cdm_taxontree">
9
 *                  <li class="leaf filter_included">
10
 *                      <a href="/d7/test/cdm_dataportal/taxon/996dc2b4-e73d-4d40-99f9-fac18b503d1c"></a>
11
 *                  </li>
12
 *                  ...
13
 *              </ul>
14
 *      </div>
15
 * </div>
16
 */
17
;(function($, document, window, undefined) {
18

    
19
    $.fn.cdm_taxontree = function(options) {
20

    
21
    var opts = $.extend({}, $.fn.cdm_taxontree.defaults, options);
22

    
23
    var vertical_scroller_selector = 'cdm_taxontree_scroller_xy';
24

    
25
    var cdm_taxontree_parent = $(this);
26
    var cdm_taxontree_list = cdm_taxontree_parent.find('ul.cdm_taxontree');
27

    
28
      /* ----------- magicbox ---------- */
29
      if (opts.magicbox) {
30
        cdm_taxontree_parent.cdm_taxontree_magicbox();
31
        vertical_sroller_selector =  'cdm_taxontree_scroller_x';
32
      }
33

    
34
      /* ----------- tree browser ---------- */
35
      cdm_taxontree_list.delegate("li:not(.invisible)", "click", function(event) {
36
              handle_taxon_node_click(event);
37
          }
38
      );
39
      // Stop event propagation for links (unclear why this is nessecary,
40
      // was this needed for the filter buttons?)
41
      cdm_taxontree_list.delegate("li a", "click", function(event) {
42
              event.stopPropagation();
43
          }
44
      );
45

    
46
      /* ----------- widget ------------------- */
47
      if (opts.widget) {
48
        var widget = cdm_taxontree_parent.find('.cdm_taxontree_widget');
49
        var optionList = widget.find('select');
50

    
51
        // Keep all options unselected.
52
        optionList.change(function() {
53
            cdm_taxontree_list.children("[@selected]").remove();
54
            cdm_taxontree_list.children().removeAttr('selected');
55
        });
56
        optionList.children("[@selected]").click(function() {
57
            cdm_taxontree_list.remove();
58
        });
59
        // Select all options onsubmit.
60
        optionList.parents('form').submit(function() {
61
          optionList.children().attr('selected', 'selected');
62
        });
63

    
64
        bind_select_click(optionList, cdm_taxontree_list, opts.multiselect);
65
      };
66

    
67
      // finally scroll to the focused element
68
      scrollToFocused();
69

    
70
    /**
71
     * handler function for clicks on the li elelements which
72
     * represent CDM TaxonNodes. The click will load the
73
     * nodes children via an AHAH call to the CdmdataPortal
74
     * and expands the clicked node.
75
     *
76
     * @param event
77
     *   The javascript event object of the click event
78
     */
79
    function handle_taxon_node_click(event){
80

    
81
        event.stopPropagation();
82
        var li = $(event.target);
83
        if (li.hasClass('collapsed')) {
84
          var bindChildren = (li.find('ul').length == 0);
85
          if (bindChildren) {
86
            var url = li.attr('data-cdm-ahah-url');
87
            if (url != undefined) {
88
              li.removeAttr('data-cdm-ahah-url');
89
              var parent_li = li;
90
              li.set_background_image('loading_subtree.gif');
91

    
92
              // Load DOM subtree via AHAH and append it.
93
              $.get(url, function(html) {
94
                parent_li.set_background_image('minus.png');
95
                if (opts.magicbox) {
96
                  // Preserve scroll positions.
97
                  var tmp_scroller_y_left = parent_li.parents('div.cdm_taxontree_container').children().scrollTop();
98

    
99
                  parent_li.append(html);
100

    
101
                  // Resize parent container.
102
                  cdm_taxontree_container_resize(tree_container);
103

    
104
                  // Restore scroll positions.
105
                  tree_container.children().scrollTop(tmp_scroller_y_left);
106
                } else {
107
                  parent_li.append(html);
108
                }
109
              });
110
            }
111
          } else {
112
            li.set_background_image('minus.png');
113
          }
114
          li.removeClass('collapsed').addClass('expanded').children(
115
              'ul').css('display', 'block');
116
        } else if (li.hasClass('expanded')) {
117
          li.removeClass('expanded').addClass('collapsed').children(
118
              'ul').css('display', 'none');
119
          li.set_background_image('plus.png');
120
        }
121
    };
122

    
123
    /**
124
     *
125
     */
126
    function bind_select_click(optionList, treelist, isMultiselect) {
127
      treelist.find('li .widget_select').click(
128
          function(event) {
129
            event.stopPropagation();
130
            var li_widget_select = $(event.target);
131
            var value = li_widget_select.attr('alt');
132
            if (optionList.children('[value=' + value + ']').length > 0) {
133
              // Remove from select.
134
              optionList.children('[value=' + value + ']').remove();
135
            } else {
136
              // Add to select.
137
              if (!isMultiselect) {
138
                // Remove all from select
139
                optionList.children().remove();
140
              }
141
              optionList.append('<option value="' + value + '">'
142
                  + li_widget_select.attr('title') + '</option>');
143

    
144
              // Fix bug in IE.
145
              if (jQuery.browser['msie']) {
146
                if (jQuery.browser['version'].charAt(0) <= '6') {
147
                  return;
148
                }
149
              }
150
              // optionList.children().removeAttr('selected'); // Yields a bug
151
              // in IE6, @see
152
              // http://gimp4you.eu.org/sandbox/js/test/removeAttr.html
153
              optionList.children("[@selected]").attr('selected', '');
154
            }
155
          });
156
    } // END bind_select_click()
157

    
158
    /**
159
     *
160
     */
161
    function scrollToFocused() {
162
        var focusedElement = cdm_taxontree_parent.find('.focused');
163
        if(focusedElement.length > 0){
164
            var lineHeight = focusedElement.css('line-height');
165
            lineHeight = lineHeight.replace('px', '');
166
            lineHeight = lineHeight.length == 0 ? 18 : lineHeight;
167
            cdm_taxontree_parent.find('div.' + vertical_scroller_selector).scrollTo(focusedElement, {duration: 400, axis:'y', offset:-2 * lineHeight});
168
        }
169

    
170
    }
171

    
172
  }; // END cdm_taxontree()
173

    
174
})(jQuery, document, window);
175

    
176
/**
177
 * helper function to set the background image as jQuery extension
178
 */
179
jQuery.fn.set_background_image = function(imageFile) {
180
  var bg_image_tmp = jQuery(this).css('background-image');
181
  var bg_image_new = bg_image_tmp.replace(/^(.*)(\/.*)(\))$/, '$1/' + imageFile + '$3');
182
  if (jQuery.browser.mozilla) {
183
    // Special bug handling for mozilla: strip of last closing bracket.
184
    bg_image_new = bg_image_new.substr(0, bg_image_new.length - 1);
185
  }
186
  jQuery(this).css('background-image', bg_image_new);
187
};
188

    
189
jQuery.fn.cdm_taxontree.defaults = { // Set up default options.
190
        widget : false, // True = enable widget mode.
191
        magicbox : false, // True = enable quirky magicbox.
192
        element_name : 'widgetval',
193
        multiselect : false // True = enable selection of multiple.
194
};
195

    
196

    
197
// ====================================================================================== //
198

    
199
/**
200
 * jQuery function which implements the Magicbox behavior for the taxontree.
201
 * A Magicbox the container of the taxon tree will extend on mouse over
202
 * events in order to show the entrys without truncation through cropping.
203
 */
204
jQuery.fn.cdm_taxontree_magicbox = function() {
205
  // Exclude IE6 and lower versions.
206
  if (!(jQuery.browser['msie'] && jQuery.browser['version'].charAt(0) < '7')) {
207

    
208
    var container = $(this).parent().parent('div.cdm_taxontree_container');
209
    if (container[0] != undefined) {
210
        container.hover(
211
            function(event) {
212
                handle_mouseOver(event);
213
            },
214
            function(event) {
215
                handle_mouseOut(event);
216
            }
217
        );
218
    }
219
  } // END exclude IE6
220

    
221
  /**
222
   * expands the box on mouse over events the
223
   */
224
  function handle_mouseOver(event){
225
      var taxontree_container = $(event.target);
226
      var scroller_x = taxontree_container.parent();
227
      var scroller_y = taxontree_container.children('.cdm_taxontree_scroller_y');
228
      var container = scroller_x.parent();
229

    
230
      var h = parseFloat(scroller_x.height());
231
      var scroll_top = scroller_x.scrollTop();
232
      var border_color = scroller_x.css('border-top-color');
233

    
234
      // Store scroll_left of scroller_x so that it can be restored on mouseOut.
235
      scroller_x.append('<div class="_scrollLeft" style="display: none;" title="'
236
              + scroller_x.scrollLeft() + '"></div>');
237

    
238
      var newWidth = cdm_taxontree_container_resize(taxontree_container);
239

    
240
      var shift_left = '0';
241
      if (scroller_x.hasClass('expand-left')) {
242
        shift_left = container.outerWidth({margin : true}) - newWidth;
243
      }
244

    
245
      scroller_y.css('overflow-y', 'auto')
246
          .css('border-color', border_color)
247
          .scrollTop(scroll_top);
248
      scroller_x.css('overflow-y', 'visible')
249
          .css('overflow-x', 'visible')
250
          .css('margin-left', shift_left)
251
          .css('border-color', 'transparent')
252
          .height(h);
253
  };
254

    
255
  /**
256
   * Restores the original appearance on mouse out events
257
   */
258
  function handle_mouseOut(event){
259

    
260
      var taxontree_container = $(event.target);
261
      var scroller_x = taxontree_container.parent('.cdm_taxontree_scroller_x');
262
      var scroller_y = taxontree_container.children('.cdm_taxontree_scroller_y');
263
      var border_color = scroller_y.css('border-top-color');
264

    
265
      var scroll_top = scroller_y.scrollTop();
266
      scroller_y.css('overflow-y', 'visible')
267
          .css('border-color', 'transparent');
268
      scroller_x.css('overflow-y', 'auto').css('margin-left', '0').css(
269
          'border-color', border_color).width('auto').scrollTop(scroll_top);
270

    
271
      // Restore scroll_left of scroller_x.
272
      var scrollLeft = scroller_x.children('._scrollLeft').attr('title');
273
      scroller_x.scrollLeft(scrollLeft);
274
      scroller_x.children('._scrollLeft').remove();
275
  };
276

    
277
  /**
278
   * Resizes the taxontree_container and returns the new outerWidth
279
   */
280
  function taxontree_container_resize(taxontree_container) {
281
    var current_w = taxontree_container.parent().width();
282

    
283
    // Determine max horizontal extent of any children.
284
    var tree_list = taxontree_container.find('.cdm_taxontree_scroller_y > ul');
285
    var w = tree_list.css('position', 'absolute').outerWidth({
286
      margin : true
287
    });
288
    tree_list.css('position', 'static');
289

    
290
    // Other Browsers than Firefox.
291
    if (jQuery.browser['msie']) {
292
      if (jQuery.browser['version'].charAt(0) == '7') {
293
        w = w + 17;
294
      }
295
      if (jQuery.browser['version'].charAt(0) <= '6') {
296
        return;
297
      }
298
    }
299

    
300
    if (current_w < w) {
301
        taxontree_container.parent().width(w);
302
        taxontree_container.children().width(w);
303
    }
304
    return taxontree_container.children().outerWidth();
305
  };
306

    
307
  /**
308
   * Debug function, currently unused
309
   */
310
  function cdm_taxontree_container_debug_size(taxontree_container, msg) {
311
      var out = msg + '<br />    scoll_x: ' + taxontree_container.parent().width()
312
          + '<br />    container: ' + taxontree_container.width() + '<br />    scoll_y: '
313
          + taxontree_container.children().width() + '<br />    ul: '
314
          + taxontree_container.find('.cdm_taxontree_scroller_y > ul').width() + '<br />';
315
      jQuery('#DEBUG_JS').append(out);
316
  };
317
};
318

    
319
//====================================================================================== //
(1-1/5)