dojo/dnd/Selector.js

  • Provides:

    • dojo.dnd.Selector
  • dojo.dnd.__SelectorArgs

    • type
      Function
    • chains:
      • dojo.dnd.__ContainerArgs: (prototype)
      • dojo.dnd.__ContainerArgs: (call)
    • summary
  • dojo.dnd.__SelectorArgs.singular

    • type
      Boolean
    • summary
      allows selection of only one element, if true
  • dojo.dnd.__SelectorArgs.autoSync

    • type
      Boolean
    • summary
      autosynchronizes the source with its list of DnD nodes,
  • dojo.dnd.Selector

    • type
      Function
    • chains:
      • dojo.dnd.Container: (prototype)
      • dojo.dnd.Container: (call)
    • summary
      constructor of the Selector
    • parameters:
      • node: (typeof Node||String)
        node or node's id to build the selector on
      • params: (typeof dojo.dnd.__SelectorArgs)
        a dictionary of parameters
    • source: [view]
        if(!params){ params = {}; }
        this.singular = params.singular;
        this.autoSync = params.autoSync;
        // class-specific variables
        this.selection = {};
        this.anchor = null;
        this.simpleSelection = false;
        // set up events
        this.events.push(
         dojo.connect(this.node, "onmousedown", this, "onMouseDown"),
         dojo.connect(this.node, "onmouseup", this, "onMouseUp"));
  • dojo.dnd.Selector.selection

    • type
      Object
    • summary
  • dojo.dnd.Selector.singular

    • summary
  • dojo.dnd.Selector.getSelectedNodes

    • type
      Function
    • source: [view]
        var t = new dojo.NodeList();
        var e = dojo.dnd._empty;
        for(var i in this.selection){
         if(i in e){ continue; }
         t.push(dojo.byId(i));
        }
        return t; // NodeList
    • summary
      returns a list (an array) of selected nodes
    • returns
      NodeList
  • dojo.dnd.Selector.selectNone

    • type
      Function
    • source: [view]
        return this._removeSelection()._removeAnchor(); // self
    • summary
      unselects all items
    • returns
      self
  • dojo.dnd.Selector.selectAll

    • type
      Function
    • source: [view]
        this.forInItems(function(data, id){
         this._addItemClass(dojo.byId(id), "Selected");
         this.selection[id] = 1;
        }, this);
        return this._removeAnchor(); // self
    • summary
      selects all items
    • returns
      self
  • dojo.dnd.Selector.deleteSelectedNodes

    • type
      Function
    • source: [view]
        var e = dojo.dnd._empty;
        for(var i in this.selection){
         if(i in e){ continue; }
         var n = dojo.byId(i);
         this.delItem(i);
         dojo.destroy(n);
        }
        this.anchor = null;
        this.selection = {};
        return this; // self
    • summary
      deletes all selected items
    • returns
      self
  • dojo.dnd.Selector.forInSelectedItems

    • type
      Function
    • parameters:
      • f: (typeof Function)
      • o: (typeof Object)
    • source: [view]
        o = o || dojo.global;
        var s = this.selection, e = dojo.dnd._empty;
        for(var i in s){
         if(i in e){ continue; }
         f.call(o, this.getItem(i), i, this);
        }
    • summary
      iterates over selected items;
      see `dojo.dnd.Container.forInItems()` for details
  • dojo.dnd.Selector.sync

    • type
      Function
    • source: [view]
        dojo.dnd.Selector.superclass.sync.call(this);

        
        // fix the anchor
        if(this.anchor){
         if(!this.getItem(this.anchor.id)){
          this.anchor = null;
         }
        }

        
        // fix the selection
        var t = [], e = dojo.dnd._empty;
        for(var i in this.selection){
         if(i in e){ continue; }
         if(!this.getItem(i)){
          t.push(i);
         }
        }
        dojo.forEach(t, function(i){
         delete this.selection[i];
        }, this);

        
        return this; // self
    • summary
      sync up the node list with the data map
    • returns
      self
    • chains:
      • dojo.dnd.Selector.superclass.sync: (call)
  • dojo.dnd.Selector.insertNodes

    • type
      Function
    • parameters:
      • addSelected: (typeof Boolean)
        all new nodes will be added to selected items, if true, no selection change otherwise
      • data: (typeof Array)
        a list of data items, which should be processed by the creator function
      • before: (typeof Boolean)
        insert before the anchor, if true, and after the anchor otherwise
      • anchor: (typeof Node)
        the anchor node to be used as a point of insertion
    • source: [view]
        var oldCreator = this._normalizedCreator;
        this._normalizedCreator = function(item, hint){
         var t = oldCreator.call(this, item, hint);
         if(addSelected){
          if(!this.anchor){
           this.anchor = t.node;
           this._removeItemClass(t.node, "Selected");
           this._addItemClass(this.anchor, "Anchor");
          }else if(this.anchor != t.node){
           this._removeItemClass(t.node, "Anchor");
           this._addItemClass(t.node, "Selected");
          }
          this.selection[t.node.id] = 1;
         }else{
          this._removeItemClass(t.node, "Selected");
          this._removeItemClass(t.node, "Anchor");
         }
         return t;
        };
        dojo.dnd.Selector.superclass.insertNodes.call(this, data, before, anchor);
        this._normalizedCreator = oldCreator;
        return this; // self
    • summary
      inserts new data items (see `dojo.dnd.Container.insertNodes()` method for details)
    • returns
      self
    • chains:
      • dojo.dnd.Selector.superclass.insertNodes: (call)
  • dojo.dnd.Selector.destroy

    • type
      Function
    • source: [view]
        dojo.dnd.Selector.superclass.destroy.call(this);
        this.selection = this.anchor = null;
    • summary
      prepares the object to be garbage-collected
    • chains:
      • dojo.dnd.Selector.superclass.destroy: (call)
  • dojo.dnd.Selector.markupFactory

    • type
      Function
    • parameters:
      • params: (typeof )
      • node: (typeof )
    • source: [view]
        params._skipStartup = true;
        return new dojo.dnd.Selector(node, params);
    • summary
  • dojo.dnd.Selector.onMouseDown

    • type
      Function
    • parameters:
      • e: (typeof Event)
        mouse event
    • source: [view]
        if(this.autoSync){ this.sync(); }
        if(!this.current){ return; }
        if(!this.singular && !dojo.isCopyKey(e) && !e.shiftKey && (this.current.id in this.selection)){
         this.simpleSelection = true;
         if(e.button === dojo.mouseButtons.LEFT){
          // accept the left button and stop the event
          // for IE we don't stop event when multiple buttons are pressed
          dojo.stopEvent(e);
         }
         return;
        }
        if(!this.singular && e.shiftKey){
         if(!dojo.isCopyKey(e)){
          this._removeSelection();
         }
         var c = this.getAllNodes();
         if(c.length){
          if(!this.anchor){
           this.anchor = c[0];
           this._addItemClass(this.anchor, "Anchor");
          }
          this.selection[this.anchor.id] = 1;
          if(this.anchor != this.current){
           var i = 0;
           for(; i < c.length; ++i){
            var node = c[i];
            if(node == this.anchor || node == this.current){ break; }
           }
           for(++i; i < c.length; ++i){
            var node = c[i];
            if(node == this.anchor || node == this.current){ break; }
            this._addItemClass(node, "Selected");
            this.selection[node.id] = 1;
           }
           this._addItemClass(this.current, "Selected");
           this.selection[this.current.id] = 1;
          }
         }
        }else{
         if(this.singular){
          if(this.anchor == this.current){
           if(dojo.isCopyKey(e)){
            this.selectNone();
           }
          }else{
           this.selectNone();
           this.anchor = this.current;
           this._addItemClass(this.anchor, "Anchor");
           this.selection[this.current.id] = 1;
          }
         }else{
          if(dojo.isCopyKey(e)){
           if(this.anchor == this.current){
            delete this.selection[this.anchor.id];
            this._removeAnchor();
           }else{
            if(this.current.id in this.selection){
             this._removeItemClass(this.current, "Selected");
             delete this.selection[this.current.id];
            }else{
             if(this.anchor){
              this._removeItemClass(this.anchor, "Anchor");
              this._addItemClass(this.anchor, "Selected");
             }
             this.anchor = this.current;
             this._addItemClass(this.current, "Anchor");
             this.selection[this.current.id] = 1;
            }
           }
          }else{
           if(!(this.current.id in this.selection)){
            this.selectNone();
            this.anchor = this.current;
            this._addItemClass(this.current, "Anchor");
            this.selection[this.current.id] = 1;
           }
          }
         }
        }
        dojo.stopEvent(e);
    • summary
      event processor for onmousedown
  • dojo.dnd.Selector.onMouseUp

    • type
      Function
    • parameters:
      • e: (typeof Event)
        mouse event
    • source: [view]
        if(!this.simpleSelection){ return; }
        this.simpleSelection = false;
        this.selectNone();
        if(this.current){
         this.anchor = this.current;
         this._addItemClass(this.anchor, "Anchor");
         this.selection[this.current.id] = 1;
        }
    • summary
      event processor for onmouseup
  • dojo.dnd.Selector.onMouseMove

    • type
      Function
    • parameters:
      • e: (typeof )
    • source: [view]
      define("dojo/dnd/Selector", ["dojo", "dojo/dnd/common", "dojo/dnd/Container"], function(dojo) {


      /*
       Container item states:
        ""   - an item is not selected
        "Selected" - an item is selected
        "Anchor" - an item is selected, and is an anchor for a "shift" selection
      */




      dojo.declare("dojo.dnd.__SelectorArgs", [dojo.dnd.__ContainerArgs], {
       // singular: Boolean
       //  allows selection of only one element, if true
       singular: false,


       // autoSync: Boolean
       //  autosynchronizes the source with its list of DnD nodes,
       autoSync: false
      });




      dojo.declare("dojo.dnd.Selector", dojo.dnd.Container, {
       // summary:
       //  a Selector object, which knows how to select its children

       

       
       // selection: Set
       //  The set of id's that are currently selected, such that this.selection[id] == 1
       //  if the node w/that id is selected. Can iterate over selected node's id's like:
       // |  for(var id in this.selection)
       selection: {},

       


       constructor: function(node, params){
        // summary:
        //  constructor of the Selector
        // node: Node||String
        //  node or node's id to build the selector on
        // params: dojo.dnd.__SelectorArgs?
        //  a dictionary of parameters
        if(!params){ params = {}; }
        this.singular = params.singular;
        this.autoSync = params.autoSync;
        // class-specific variables
        this.selection = {};
        this.anchor = null;
        this.simpleSelection = false;
        // set up events
        this.events.push(
         dojo.connect(this.node, "onmousedown", this, "onMouseDown"),
         dojo.connect(this.node, "onmouseup", this, "onMouseUp"));
       },

       
       // object attributes (for markup)
       singular: false, // is singular property

       
       // methods
       getSelectedNodes: function(){
        // summary:
        //  returns a list (an array) of selected nodes
        var t = new dojo.NodeList();
        var e = dojo.dnd._empty;
        for(var i in this.selection){
         if(i in e){ continue; }
         t.push(dojo.byId(i));
        }
        return t; // NodeList
       },
       selectNone: function(){
        // summary:
        //  unselects all items
        return this._removeSelection()._removeAnchor(); // self
       },
       selectAll: function(){
        // summary:
        //  selects all items
        this.forInItems(function(data, id){
         this._addItemClass(dojo.byId(id), "Selected");
         this.selection[id] = 1;
        }, this);
        return this._removeAnchor(); // self
       },
       deleteSelectedNodes: function(){
        // summary:
        //  deletes all selected items
        var e = dojo.dnd._empty;
        for(var i in this.selection){
         if(i in e){ continue; }
         var n = dojo.byId(i);
         this.delItem(i);
         dojo.destroy(n);
        }
        this.anchor = null;
        this.selection = {};
        return this; // self
       },
       forInSelectedItems: function(/*Function*/ f, /*Object?*/ o){
        // summary:
        //  iterates over selected items;
        //  see `dojo.dnd.Container.forInItems()` for details
        o = o || dojo.global;
        var s = this.selection, e = dojo.dnd._empty;
        for(var i in s){
         if(i in e){ continue; }
         f.call(o, this.getItem(i), i, this);
        }
       },
       sync: function(){
        // summary:
        //  sync up the node list with the data map

        
        dojo.dnd.Selector.superclass.sync.call(this);

        
        // fix the anchor
        if(this.anchor){
         if(!this.getItem(this.anchor.id)){
          this.anchor = null;
         }
        }

        
        // fix the selection
        var t = [], e = dojo.dnd._empty;
        for(var i in this.selection){
         if(i in e){ continue; }
         if(!this.getItem(i)){
          t.push(i);
         }
        }
        dojo.forEach(t, function(i){
         delete this.selection[i];
        }, this);

        
        return this; // self
       },
       insertNodes: function(addSelected, data, before, anchor){
        // summary:
        //  inserts new data items (see `dojo.dnd.Container.insertNodes()` method for details)
        // addSelected: Boolean
        //  all new nodes will be added to selected items, if true, no selection change otherwise
        // data: Array
        //  a list of data items, which should be processed by the creator function
        // before: Boolean
        //  insert before the anchor, if true, and after the anchor otherwise
        // anchor: Node
        //  the anchor node to be used as a point of insertion
        var oldCreator = this._normalizedCreator;
        this._normalizedCreator = function(item, hint){
         var t = oldCreator.call(this, item, hint);
         if(addSelected){
          if(!this.anchor){
           this.anchor = t.node;
           this._removeItemClass(t.node, "Selected");
           this._addItemClass(this.anchor, "Anchor");
          }else if(this.anchor != t.node){
           this._removeItemClass(t.node, "Anchor");
           this._addItemClass(t.node, "Selected");
          }
          this.selection[t.node.id] = 1;
         }else{
          this._removeItemClass(t.node, "Selected");
          this._removeItemClass(t.node, "Anchor");
         }
         return t;
        };
        dojo.dnd.Selector.superclass.insertNodes.call(this, data, before, anchor);
        this._normalizedCreator = oldCreator;
        return this; // self
       },
       destroy: function(){
        // summary:
        //  prepares the object to be garbage-collected
        dojo.dnd.Selector.superclass.destroy.call(this);
        this.selection = this.anchor = null;
       },


       // markup methods
       markupFactory: function(params, node){
        params._skipStartup = true;
        return new dojo.dnd.Selector(node, params);
       },


       // mouse events
       onMouseDown: function(e){
        // summary:
        //  event processor for onmousedown
        // e: Event
        //  mouse event
        if(this.autoSync){ this.sync(); }
        if(!this.current){ return; }
        if(!this.singular && !dojo.isCopyKey(e) && !e.shiftKey && (this.current.id in this.selection)){
         this.simpleSelection = true;
         if(e.button === dojo.mouseButtons.LEFT){
          // accept the left button and stop the event
          // for IE we don't stop event when multiple buttons are pressed
          dojo.stopEvent(e);
         }
         return;
        }
        if(!this.singular && e.shiftKey){
         if(!dojo.isCopyKey(e)){
          this._removeSelection();
         }
         var c = this.getAllNodes();
         if(c.length){
          if(!this.anchor){
           this.anchor = c[0];
           this._addItemClass(this.anchor, "Anchor");
          }
          this.selection[this.anchor.id] = 1;
          if(this.anchor != this.current){
           var i = 0;
           for(; i < c.length; ++i){
            var node = c[i];
            if(node == this.anchor || node == this.current){ break; }
           }
           for(++i; i < c.length; ++i){
            var node = c[i];
            if(node == this.anchor || node == this.current){ break; }
            this._addItemClass(node, "Selected");
            this.selection[node.id] = 1;
           }
           this._addItemClass(this.current, "Selected");
           this.selection[this.current.id] = 1;
          }
         }
        }else{
         if(this.singular){
          if(this.anchor == this.current){
           if(dojo.isCopyKey(e)){
            this.selectNone();
           }
          }else{
           this.selectNone();
           this.anchor = this.current;
           this._addItemClass(this.anchor, "Anchor");
           this.selection[this.current.id] = 1;
          }
         }else{
          if(dojo.isCopyKey(e)){
           if(this.anchor == this.current){
            delete this.selection[this.anchor.id];
            this._removeAnchor();
           }else{
            if(this.current.id in this.selection){
             this._removeItemClass(this.current, "Selected");
             delete this.selection[this.current.id];
            }else{
             if(this.anchor){
              this._removeItemClass(this.anchor, "Anchor");
              this._addItemClass(this.anchor, "Selected");
             }
             this.anchor = this.current;
             this._addItemClass(this.current, "Anchor");
             this.selection[this.current.id] = 1;
            }
           }
          }else{
           if(!(this.current.id in this.selection)){
            this.selectNone();
            this.anchor = this.current;
            this._addItemClass(this.current, "Anchor");
            this.selection[this.current.id] = 1;
           }
          }
         }
        }
        dojo.stopEvent(e);
       },
       onMouseUp: function(e){
        // summary:
        //  event processor for onmouseup
        // e: Event
        //  mouse event
        if(!this.simpleSelection){ return; }
        this.simpleSelection = false;
        this.selectNone();
        if(this.current){
         this.anchor = this.current;
         this._addItemClass(this.anchor, "Anchor");
         this.selection[this.current.id] = 1;
        }
       },
       onMouseMove: function(e){
        // summary
        //  event processor for onmousemove
        // e: Event
        //  mouse event
        this.simpleSelection = false;
    • returns
      NodeList|self
    • summary
  • dojo.dnd.Selector.onOverEvent

    • type
      Function
    • source: [view]
        this.onmousemoveEvent = dojo.connect(this.node, "onmousemove", this, "onMouseMove");
    • summary
      this function is called once, when mouse is over our container
  • dojo.dnd.Selector.onOutEvent

    • type
      Function
    • source: [view]
        dojo.disconnect(this.onmousemoveEvent);
        delete this.onmousemoveEvent;
    • summary
      this function is called once, when mouse is out of our container
  • dojo.dnd.Selector._removeSelection

    • type
      Function
    • source: [view]
        var e = dojo.dnd._empty;
        for(var i in this.selection){
         if(i in e){ continue; }
         var node = dojo.byId(i);
         if(node){ this._removeItemClass(node, "Selected"); }
        }
        this.selection = {};
        return this; // self
    • summary
      unselects all items
    • returns
      self
  • dojo.dnd.Selector._removeAnchor

    • type
      Function
    • source: [view]
        if(this.anchor){
         this._removeItemClass(this.anchor, "Anchor");
         this.anchor = null;
        }
        return this; // self
    • returns
      self
    • summary
  • dojo.dnd.Selector.anchor

    • summary
  • dojo.dnd.Selector._normalizedCreator

    • summary
  • dojo.dnd.Selector.insertNodes._normalizedCreator

    • type
      Function
    • parameters:
      • item: (typeof )
      • hint: (typeof )
    • source: [view]
         var t = oldCreator.call(this, item, hint);
         if(addSelected){
          if(!this.anchor){
           this.anchor = t.node;
           this._removeItemClass(t.node, "Selected");
           this._addItemClass(this.anchor, "Anchor");
          }else if(this.anchor != t.node){
           this._removeItemClass(t.node, "Anchor");
           this._addItemClass(t.node, "Selected");
          }
          this.selection[t.node.id] = 1;
         }else{
          this._removeItemClass(t.node, "Selected");
          this._removeItemClass(t.node, "Anchor");
         }
         return t;
    • chains:
      • oldCreator: (call)
    • summary
  • dojo.dnd.Selector.insertNodes.anchor

    • type
      Node
    • summary
      the anchor node to be used as a point of insertion
  • dojo.dnd.Selector.simpleSelection

    • summary
  • dojo.dnd.Selector.onmousemoveEvent

    • summary
  • dojo.dnd.Selector.autoSync

    • summary
  • dojo.dnd

    • type
      Object
    • summary
  • dojo

    • type
      Object
    • summary