Thomas Bruederli
2014-05-28 586ed69aa8f9df34076f4e3bb5e1ecf0cfc6581a
Add method to make a treelist widget become a jQuery UI droppable with support for auto-scrolling and auto-expanding
1 files modified
43 ■■■■■ changed files
program/js/treelist.js 43 ●●●●● patch | view | raw | blame | history
program/js/treelist.js
@@ -64,6 +64,7 @@
    scroll_timer,
    searchfield,
    tree_state,
    ui_droppable,
    list_id = (container.attr('id') || p.id_prefix || '0'),
    me = this;
@@ -79,6 +80,7 @@
  this.drag_start = drag_start;
  this.drag_end = drag_end;
  this.intersects = intersects;
  this.droppable = droppable;
  this.update = update_node;
  this.insert = insert;
  this.remove = remove;
@@ -521,7 +523,8 @@
    var li = $('<li>')
      .attr('id', p.id_prefix + (p.id_encode ? p.id_encode(node.id) : node.id))
      .addClass((node.classes || []).join(' '));
      .addClass((node.classes || []).join(' '))
      .data('id', node.id);
    if (replace)
      replace.replaceWith(li);
@@ -594,6 +597,7 @@
        selection = node.id;
      }
      li.data('id', node.id);
      result.push(node);
      indexbyid[node.id] = node;
    })
@@ -802,7 +806,8 @@
    // no intersection with list bounding box
    if (mouse.x < box_coords.x1 || mouse.x >= box_coords.x2 || mouse.top < box_coords.y1 || mouse.top >= box_coords.y2) {
      // TODO: optimize performance for this operation
      $('li.droptarget', container).removeClass('droptarget');
      if (highlight)
        $('li.droptarget', container).removeClass('droptarget');
      return result;
    }
@@ -823,6 +828,8 @@
            expand(autoexpand_item);
            drag_start();  // re-calculate item coords
            autoexpand_item = null;
            if (ui_droppable)
              $.ui.ddmanager.prepareOffsets($.ui.ddmanager.current, null);
          }, p.autoexpand);
        }
        else if (autoexpand_timer && autoexpand_item != id) {
@@ -851,6 +858,38 @@
    return result;
  }
  /**
   * Wrapper for jQuery.UI.droppable() activation on this widget
   *
   * @param object Options as passed to regular .droppable() function
   */
  function droppable(opts)
  {
    var my_opts = $.extend({ greedy: true, hoverClass: 'droptarget', addClasses:false }, opts);
    my_opts.activate = function(e, ui) {
      drag_start();
      ui_droppable = ui;
      if (opts.activate)
        opts.activate(e, ui);
    };
    my_opts.deactivate = function(e, ui) {
      drag_end();
      ui_droppable = null;
      if (opts.deactivate)
        opts.deactivate(e, ui);
    };
    my_opts.over = function(e, ui) {
      intersects(rcube_event.get_mouse_pos(e), false);
      if (opts.over)
        opts.over(e, ui);
    };
    $('li:not(.virtual)', container).droppable(my_opts);
  }
}
// use event processing functions from Roundcube's rcube_event_engine