TreeSelectionModel.js
上传用户:dawnssy
上传日期:2022-08-06
资源大小:9345k
文件大小:10k
源码类别:

JavaScript

开发平台:

JavaScript

  1. /*!  * Ext JS Library 3.1.0  * Copyright(c) 2006-2009 Ext JS, LLC  * licensing@extjs.com  * http://www.extjs.com/license  */ /**
  2.  * @class Ext.tree.DefaultSelectionModel
  3.  * @extends Ext.util.Observable
  4.  * The default single selection for a TreePanel.
  5.  */
  6. Ext.tree.DefaultSelectionModel = function(config){
  7.    this.selNode = null;
  8.    
  9.    this.addEvents(
  10.        /**
  11.         * @event selectionchange
  12.         * Fires when the selected node changes
  13.         * @param {DefaultSelectionModel} this
  14.         * @param {TreeNode} node the new selection
  15.         */
  16.        'selectionchange',
  17.        /**
  18.         * @event beforeselect
  19.         * Fires before the selected node changes, return false to cancel the change
  20.         * @param {DefaultSelectionModel} this
  21.         * @param {TreeNode} node the new selection
  22.         * @param {TreeNode} node the old selection
  23.         */
  24.        'beforeselect'
  25.    );
  26.     Ext.apply(this, config);
  27.     Ext.tree.DefaultSelectionModel.superclass.constructor.call(this);
  28. };
  29. Ext.extend(Ext.tree.DefaultSelectionModel, Ext.util.Observable, {
  30.     init : function(tree){
  31.         this.tree = tree;
  32.         tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this);
  33.         tree.on('click', this.onNodeClick, this);
  34.     },
  35.     
  36.     onNodeClick : function(node, e){
  37.         this.select(node);
  38.     },
  39.     
  40.     /**
  41.      * Select a node.
  42.      * @param {TreeNode} node The node to select
  43.      * @return {TreeNode} The selected node
  44.      */
  45.     select : function(node, /* private*/ selectNextNode){
  46.         // If node is hidden, select the next node in whatever direction was being moved in.
  47.         if (!Ext.fly(node.ui.wrap).isVisible() && selectNextNode) {
  48.             return selectNextNode.call(this, node);
  49.         }
  50.         var last = this.selNode;
  51.         if(node == last){
  52.             node.ui.onSelectedChange(true);
  53.         }else if(this.fireEvent('beforeselect', this, node, last) !== false){
  54.             if(last && last.ui){
  55.                 last.ui.onSelectedChange(false);
  56.             }
  57.             this.selNode = node;
  58.             node.ui.onSelectedChange(true);
  59.             this.fireEvent('selectionchange', this, node, last);
  60.         }
  61.         return node;
  62.     },
  63.     
  64.     /**
  65.      * Deselect a node.
  66.      * @param {TreeNode} node The node to unselect
  67.      * @param {Boolean} silent True to stop the selectionchange event from firing.
  68.      */
  69.     unselect : function(node, silent){
  70.         if(this.selNode == node){
  71.             this.clearSelections(silent);
  72.         }    
  73.     },
  74.     
  75.     /**
  76.      * Clear all selections
  77.      * @param {Boolean} silent True to stop the selectionchange event from firing.
  78.      */
  79.     clearSelections : function(silent){
  80.         var n = this.selNode;
  81.         if(n){
  82.             n.ui.onSelectedChange(false);
  83.             this.selNode = null;
  84.             if(silent !== true){
  85.                 this.fireEvent('selectionchange', this, null);
  86.             }
  87.         }
  88.         return n;
  89.     },
  90.     
  91.     /**
  92.      * Get the selected node
  93.      * @return {TreeNode} The selected node
  94.      */
  95.     getSelectedNode : function(){
  96.         return this.selNode;    
  97.     },
  98.     
  99.     /**
  100.      * Returns true if the node is selected
  101.      * @param {TreeNode} node The node to check
  102.      * @return {Boolean}
  103.      */
  104.     isSelected : function(node){
  105.         return this.selNode == node;  
  106.     },
  107.     /**
  108.      * Selects the node above the selected node in the tree, intelligently walking the nodes
  109.      * @return TreeNode The new selection
  110.      */
  111.     selectPrevious : function(/* private */ s){
  112.         if(!(s = s || this.selNode || this.lastSelNode)){
  113.             return null;
  114.         }
  115.         // Here we pass in the current function to select to indicate the direction we're moving
  116.         var ps = s.previousSibling;
  117.         if(ps){
  118.             if(!ps.isExpanded() || ps.childNodes.length < 1){
  119.                 return this.select(ps, this.selectPrevious);
  120.             } else{
  121.                 var lc = ps.lastChild;
  122.                 while(lc && lc.isExpanded() && Ext.fly(lc.ui.wrap).isVisible() && lc.childNodes.length > 0){
  123.                     lc = lc.lastChild;
  124.                 }
  125.                 return this.select(lc, this.selectPrevious);
  126.             }
  127.         } else if(s.parentNode && (this.tree.rootVisible || !s.parentNode.isRoot)){
  128.             return this.select(s.parentNode, this.selectPrevious);
  129.         }
  130.         return null;
  131.     },
  132.     /**
  133.      * Selects the node above the selected node in the tree, intelligently walking the nodes
  134.      * @return TreeNode The new selection
  135.      */
  136.     selectNext : function(/* private */ s){
  137.         if(!(s = s || this.selNode || this.lastSelNode)){
  138.             return null;
  139.         }
  140.         // Here we pass in the current function to select to indicate the direction we're moving
  141.         if(s.firstChild && s.isExpanded() && Ext.fly(s.ui.wrap).isVisible()){
  142.              return this.select(s.firstChild, this.selectNext);
  143.          }else if(s.nextSibling){
  144.              return this.select(s.nextSibling, this.selectNext);
  145.          }else if(s.parentNode){
  146.             var newS = null;
  147.             s.parentNode.bubble(function(){
  148.                 if(this.nextSibling){
  149.                     newS = this.getOwnerTree().selModel.select(this.nextSibling, this.selectNext);
  150.                     return false;
  151.                 }
  152.             });
  153.             return newS;
  154.          }
  155.         return null;
  156.     },
  157.     onKeyDown : function(e){
  158.         var s = this.selNode || this.lastSelNode;
  159.         // undesirable, but required
  160.         var sm = this;
  161.         if(!s){
  162.             return;
  163.         }
  164.         var k = e.getKey();
  165.         switch(k){
  166.              case e.DOWN:
  167.                  e.stopEvent();
  168.                  this.selectNext();
  169.              break;
  170.              case e.UP:
  171.                  e.stopEvent();
  172.                  this.selectPrevious();
  173.              break;
  174.              case e.RIGHT:
  175.                  e.preventDefault();
  176.                  if(s.hasChildNodes()){
  177.                      if(!s.isExpanded()){
  178.                          s.expand();
  179.                      }else if(s.firstChild){
  180.                          this.select(s.firstChild, e);
  181.                      }
  182.                  }
  183.              break;
  184.              case e.LEFT:
  185.                  e.preventDefault();
  186.                  if(s.hasChildNodes() && s.isExpanded()){
  187.                      s.collapse();
  188.                  }else if(s.parentNode && (this.tree.rootVisible || s.parentNode != this.tree.getRootNode())){
  189.                      this.select(s.parentNode, e);
  190.                  }
  191.              break;
  192.         };
  193.     }
  194. });
  195. /**
  196.  * @class Ext.tree.MultiSelectionModel
  197.  * @extends Ext.util.Observable
  198.  * Multi selection for a TreePanel.
  199.  */
  200. Ext.tree.MultiSelectionModel = function(config){
  201.    this.selNodes = [];
  202.    this.selMap = {};
  203.    this.addEvents(
  204.        /**
  205.         * @event selectionchange
  206.         * Fires when the selected nodes change
  207.         * @param {MultiSelectionModel} this
  208.         * @param {Array} nodes Array of the selected nodes
  209.         */
  210.        'selectionchange'
  211.    );
  212.     Ext.apply(this, config);
  213.     Ext.tree.MultiSelectionModel.superclass.constructor.call(this);
  214. };
  215. Ext.extend(Ext.tree.MultiSelectionModel, Ext.util.Observable, {
  216.     init : function(tree){
  217.         this.tree = tree;
  218.         tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this);
  219.         tree.on('click', this.onNodeClick, this);
  220.     },
  221.     
  222.     onNodeClick : function(node, e){
  223.         if(e.ctrlKey && this.isSelected(node)){
  224.             this.unselect(node);
  225.         }else{
  226.             this.select(node, e, e.ctrlKey);
  227.         }
  228.     },
  229.     
  230.     /**
  231.      * Select a node.
  232.      * @param {TreeNode} node The node to select
  233.      * @param {EventObject} e (optional) An event associated with the selection
  234.      * @param {Boolean} keepExisting True to retain existing selections
  235.      * @return {TreeNode} The selected node
  236.      */
  237.     select : function(node, e, keepExisting){
  238.         if(keepExisting !== true){
  239.             this.clearSelections(true);
  240.         }
  241.         if(this.isSelected(node)){
  242.             this.lastSelNode = node;
  243.             return node;
  244.         }
  245.         this.selNodes.push(node);
  246.         this.selMap[node.id] = node;
  247.         this.lastSelNode = node;
  248.         node.ui.onSelectedChange(true);
  249.         this.fireEvent('selectionchange', this, this.selNodes);
  250.         return node;
  251.     },
  252.     
  253.     /**
  254.      * Deselect a node.
  255.      * @param {TreeNode} node The node to unselect
  256.      */
  257.     unselect : function(node){
  258.         if(this.selMap[node.id]){
  259.             node.ui.onSelectedChange(false);
  260.             var sn = this.selNodes;
  261.             var index = sn.indexOf(node);
  262.             if(index != -1){
  263.                 this.selNodes.splice(index, 1);
  264.             }
  265.             delete this.selMap[node.id];
  266.             this.fireEvent('selectionchange', this, this.selNodes);
  267.         }
  268.     },
  269.     
  270.     /**
  271.      * Clear all selections
  272.      */
  273.     clearSelections : function(suppressEvent){
  274.         var sn = this.selNodes;
  275.         if(sn.length > 0){
  276.             for(var i = 0, len = sn.length; i < len; i++){
  277.                 sn[i].ui.onSelectedChange(false);
  278.             }
  279.             this.selNodes = [];
  280.             this.selMap = {};
  281.             if(suppressEvent !== true){
  282.                 this.fireEvent('selectionchange', this, this.selNodes);
  283.             }
  284.         }
  285.     },
  286.     
  287.     /**
  288.      * Returns true if the node is selected
  289.      * @param {TreeNode} node The node to check
  290.      * @return {Boolean}
  291.      */
  292.     isSelected : function(node){
  293.         return this.selMap[node.id] ? true : false;  
  294.     },
  295.     
  296.     /**
  297.      * Returns an array of the selected nodes
  298.      * @return {Array}
  299.      */
  300.     getSelectedNodes : function(){
  301.         return this.selNodes;    
  302.     },
  303.     onKeyDown : Ext.tree.DefaultSelectionModel.prototype.onKeyDown,
  304.     selectNext : Ext.tree.DefaultSelectionModel.prototype.selectNext,
  305.     selectPrevious : Ext.tree.DefaultSelectionModel.prototype.selectPrevious
  306. });