Project

General

Profile

Download (11.9 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="taxon-nodes">
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
    // firebug console stub (avoids errors if firebug is not active)
22
    if(typeof console === "undefined") {
23
      console = { log: function() { } };
24
    }
25

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

    
28
    var vertical_scroller_selector = 'cdm_taxontree_scroller_xy';
29

    
30
    var cdm_taxontree_parent = $(this);
31
    var cdm_taxontree_list = cdm_taxontree_parent.find('ul.taxon-nodes');
32

    
33
      /* ----------- magicbox ---------- */
34
      if (opts.magicbox) {
35
        cdm_taxontree_parent.cdm_taxontree_magicbox();
36
        vertical_sroller_selector =  'cdm_taxontree_scroller_x';
37
      }
38

    
39
      /* ----------- tree browser ---------- */
40
      cdm_taxontree_list.delegate("li:not(.invisible)", "click", function(event) {
41
              handle_taxon_node_click(event);
42
          }
43
      );
44
      // Stop event propagation for links (unclear why this is necessary,
45
      // was this needed for the filter buttons?)
46
      cdm_taxontree_list.delegate("li a", "click", function(event) {
47
              event.stopPropagation();
48
          }
49
      );
50

    
51
      /* ----------- widget ------------------- */
52
      if (opts.widget) {
53
        var widget = cdm_taxontree_parent.find('.cdm_taxontree_widget');
54
        var optionList = widget.find('select');
55

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

    
69
        bind_select_click(optionList, cdm_taxontree_list, opts.multiselect);
70
      };
71

    
72
      // finally scroll to the focused element
73
      scrollToFocused();
74

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

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

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

    
104
                  parent_li.append(html);
105

    
106
                  // Resize parent container.
107
                  cdm_taxontree_container_resize(tree_container);
108

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

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

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

    
163
    /**
164
     *
165
     */
166
    function scrollToFocused() {
167
        var focusedElement = cdm_taxontree_parent.find('.focused');
168
        if(focusedElement.length > 0){
169
          var lineHeight = focusedElement.css('line-height');
170
          lineHeight = lineHeight.replace('px', '');
171
          lineHeight = lineHeight.length == 0 ? 18 : lineHeight;
172
          console.log("cdm_taxontree.scrollToFocused() - lineHeight:" + lineHeight);
173
          console.log("cdm_taxontree.scrollToFocused() -  focusedElement.position().top: " + focusedElement.position().top);
174

    
175
          // IMPORTANT !!!!!!
176
          // In some cases (cichorieae theme related?) the scroll to moves the div to a wrong position
177
          // Doing it twice, solves the problem
178
          cdm_taxontree_parent.find('div.' + vertical_scroller_selector).scrollTop(focusedElement.position().top - (4 * lineHeight));
179
          cdm_taxontree_parent.find('div.' + vertical_scroller_selector).scrollTop(focusedElement.position().top - (4 * lineHeight));
180
        }
181

    
182
    }
183

    
184
  }; // END cdm_taxontree()
185

    
186
})(jQuery, document, window);
187

    
188
/**
189
 * helper function to set the background image as jQuery extension
190
 */
191
jQuery.fn.set_background_image = function(imageFile) {
192
  var bg_image_tmp = jQuery(this).css('background-image');
193
  var bg_image_new = bg_image_tmp.replace(/^(.*)(\/.*)(\))$/, '$1/' + imageFile + '$3');
194
  if (jQuery.browser.mozilla) {
195
    // Special bug handling for mozilla: strip of last closing bracket.
196
    bg_image_new = bg_image_new.substr(0, bg_image_new.length - 1);
197
  }
198
  jQuery(this).css('background-image', bg_image_new);
199
};
200

    
201
jQuery.fn.cdm_taxontree.defaults = { // Set up default options.
202
        widget : false, // True = enable widget mode.
203
        magicbox : false, // True = enable quirky magicbox.
204
        element_name : 'widgetval',
205
        multiselect : false // True = enable selection of multiple.
206
};
207

    
208

    
209
// ====================================================================================== //
210

    
211
/**
212
 * jQuery function which implements the Magicbox behavior for the taxontree.
213
 * A Magicbox the container of the taxon tree will extend on mouse over
214
 * events in order to show the entrys without truncation through cropping.
215
 */
216
jQuery.fn.cdm_taxontree_magicbox = function() {
217
  // Exclude IE6 and lower versions.
218
  if (!(jQuery.browser['msie'] && jQuery.browser['version'].charAt(0) < '7')) {
219

    
220
    var container = $(this).parent().parent('div.cdm_taxontree_container');
221
    if (container[0] != undefined) {
222
        container.hover(
223
            function(event) {
224
                handle_mouseOver(event);
225
            },
226
            function(event) {
227
                handle_mouseOut(event);
228
            }
229
        );
230
    }
231
  } // END exclude IE6
232

    
233
  /**
234
   * expands the box on mouse over events the
235
   */
236
  function handle_mouseOver(event){
237
      var taxontree_container = $(event.target);
238
      var scroller_x = taxontree_container.parent();
239
      var scroller_y = taxontree_container.children('.cdm_taxontree_scroller_y');
240
      var container = scroller_x.parent();
241

    
242
      var h = parseFloat(scroller_x.height());
243
      var scroll_top = scroller_x.scrollTop();
244
      var border_color = scroller_x.css('border-top-color');
245

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

    
250
      var newWidth = cdm_taxontree_container_resize(taxontree_container);
251

    
252
      var shift_left = '0';
253
      if (scroller_x.hasClass('expand-left')) {
254
        shift_left = container.outerWidth({margin : true}) - newWidth;
255
      }
256

    
257
      scroller_y.css('overflow-y', 'auto')
258
          .css('border-color', border_color)
259
          .scrollTop(scroll_top);
260
      scroller_x.css('overflow-y', 'visible')
261
          .css('overflow-x', 'visible')
262
          .css('margin-left', shift_left)
263
          .css('border-color', 'transparent')
264
          .height(h);
265
  };
266

    
267
  /**
268
   * Restores the original appearance on mouse out events
269
   */
270
  function handle_mouseOut(event){
271

    
272
      var taxontree_container = $(event.target);
273
      var scroller_x = taxontree_container.parent('.cdm_taxontree_scroller_x');
274
      var scroller_y = taxontree_container.children('.cdm_taxontree_scroller_y');
275
      var border_color = scroller_y.css('border-top-color');
276

    
277
      var scroll_top = scroller_y.scrollTop();
278
      scroller_y.css('overflow-y', 'visible')
279
          .css('border-color', 'transparent');
280
      scroller_x.css('overflow-y', 'auto').css('margin-left', '0').css(
281
          'border-color', border_color).width('auto').scrollTop(scroll_top);
282

    
283
      // Restore scroll_left of scroller_x.
284
      var scrollLeft = scroller_x.children('._scrollLeft').attr('title');
285
      scroller_x.scrollLeft(scrollLeft);
286
      scroller_x.children('._scrollLeft').remove();
287
  };
288

    
289
  /**
290
   * Resizes the taxontree_container and returns the new outerWidth
291
   */
292
  function taxontree_container_resize(taxontree_container) {
293
    var current_w = taxontree_container.parent().width();
294

    
295
    // Determine max horizontal extent of any children.
296
    var tree_list = taxontree_container.find('.cdm_taxontree_scroller_y > ul');
297
    var w = tree_list.css('position', 'absolute').outerWidth({
298
      margin : true
299
    });
300
    tree_list.css('position', 'static');
301

    
302
    // Other Browsers than Firefox.
303
    if (jQuery.browser['msie']) {
304
      if (jQuery.browser['version'].charAt(0) == '7') {
305
        w = w + 17;
306
      }
307
      if (jQuery.browser['version'].charAt(0) <= '6') {
308
        return;
309
      }
310
    }
311

    
312
    if (current_w < w) {
313
        taxontree_container.parent().width(w);
314
        taxontree_container.children().width(w);
315
    }
316
    return taxontree_container.children().outerWidth();
317
  };
318

    
319
  /**
320
   * Debug function, currently unused
321
   */
322
  function cdm_taxontree_container_debug_size(taxontree_container, msg) {
323
      var out = msg + '<br />    scoll_x: ' + taxontree_container.parent().width()
324
          + '<br />    container: ' + taxontree_container.width() + '<br />    scoll_y: '
325
          + taxontree_container.children().width() + '<br />    ul: '
326
          + taxontree_container.find('.cdm_taxontree_scroller_y > ul').width() + '<br />';
327
      jQuery('#DEBUG_JS').append(out);
328
  };
329
};
330

    
331
//====================================================================================== //
    (1-1/1)