NOBUG: Fixed file access permissions
[moodle.git] / lib / yuilib / 3.13.0 / tree-selectable / tree-selectable-debug.js
blobfd1c7064cdf58d8dfc6d2af8ab30f3b1c4e385cd
1 /*
2 YUI 3.13.0 (build 508226d)
3 Copyright 2013 Yahoo! Inc. All rights reserved.
4 Licensed under the BSD License.
5 http://yuilibrary.com/license/
6 */
8 YUI.add('tree-selectable', function (Y, NAME) {
10 /*jshint expr:true, onevar:false */
12 /**
13 Extension for `Tree` that adds the concept of selection state for nodes.
15 @module tree
16 @submodule tree-selectable
17 @main tree-selectable
18 **/
20 var Do = Y.Do;
22 /**
23 Extension for `Tree` that adds the concept of selection state for nodes.
25 @class Tree.Selectable
26 @constructor
27 @extensionfor Tree
28 **/
30 /**
31 Fired when a node is selected.
33 @event select
34 @param {Tree.Node} node Node being selected.
35 @preventable _defSelectFn
36 **/
37 var EVT_SELECT = 'select';
39 /**
40 Fired when a node is unselected.
42 @event unselect
43 @param {Tree.Node} node Node being unselected.
44 @preventable _defUnselectFn
45 **/
46 var EVT_UNSELECT = 'unselect';
48 function Selectable() {}
50 Selectable.prototype = {
51     // -- Protected Properties -------------------------------------------------
53     /**
54     Mapping of node ids to node instances for nodes in this tree that are
55     currently selected.
57     @property {Object} _selectedMap
58     @protected
59     **/
61     // -- Lifecycle ------------------------------------------------------------
62     initializer: function () {
63         this.nodeExtensions = this.nodeExtensions.concat(Y.Tree.Node.Selectable);
64         this._selectedMap   = {};
66         Do.after(this._selectableAfterDefAddFn, this, '_defAddFn');
67         Do.after(this._selectableAfterDefClearFn, this, '_defClearFn');
68         Do.after(this._selectableAfterDefRemoveFn, this, '_defRemoveFn');
70         this._selectableEvents = [
71             this.after('multiSelectChange', this._afterMultiSelectChange)
72         ];
73     },
75     destructor: function () {
76         (new Y.EventHandle(this._selectableEvents)).detach();
78         this._selectableEvents = null;
79         this._selectedMap      = null;
80     },
82     // -- Public Methods -------------------------------------------------------
84     /**
85     Returns an array of nodes that are currently selected.
87     @method getSelectedNodes
88     @return {Tree.Node.Selectable[]} Array of selected nodes.
89     **/
90     getSelectedNodes: function () {
91         return Y.Object.values(this._selectedMap);
92     },
94     /**
95     Selects the specified node.
97     @method selectNode
98     @param {Tree.Node.Selectable} node Node to select.
99     @param {Object} [options] Options.
100         @param {Boolean} [options.silent=false] If `true`, the `select` event
101             will be suppressed.
102         @param {String} [options.src] Source of the change, to be passed along
103             to the event facade of the resulting event. This can be used to
104             distinguish between changes triggered by a user and changes
105             triggered programmatically, for example.
106     @chainable
107     **/
108     selectNode: function (node, options) {
109         // Instead of calling node.isSelected(), we look for the node in this
110         // tree's selectedMap, which ensures that the `select` event will fire
111         // in cases such as a node being added to this tree with its selected
112         // state already set to true.
113         if (!this._selectedMap[node.id]) {
114             this._fireTreeEvent(EVT_SELECT, {
115                 node: node,
116                 src : options && options.src
117             }, {
118                 defaultFn: this._defSelectFn,
119                 silent   : options && options.silent
120             });
121         }
123         return this;
124     },
126     /**
127     Unselects all selected nodes.
129     @method unselect
130     @param {Object} [options] Options.
131         @param {Boolean} [options.silent=false] If `true`, the `unselect` event
132             will be suppressed.
133         @param {String} [options.src] Source of the change, to be passed along
134             to the event facade of the resulting event. This can be used to
135             distinguish between changes triggered by a user and changes
136             triggered programmatically, for example.
137     @chainable
138     **/
139     unselect: function (options) {
140         for (var id in this._selectedMap) {
141             if (this._selectedMap.hasOwnProperty(id)) {
142                 this.unselectNode(this._selectedMap[id], options);
143             }
144         }
146         return this;
147     },
149     /**
150     Unselects the specified node.
152     @method unselectNode
153     @param {Tree.Node.Selectable} node Node to unselect.
154     @param {Object} [options] Options.
155         @param {Boolean} [options.silent=false] If `true`, the `unselect` event
156             will be suppressed.
157         @param {String} [options.src] Source of the change, to be passed along
158             to the event facade of the resulting event. This can be used to
159             distinguish between changes triggered by a user and changes
160             triggered programmatically, for example.
161     @chainable
162     **/
163     unselectNode: function (node, options) {
164         if (node.isSelected() || this._selectedMap[node.id]) {
165             this._fireTreeEvent(EVT_UNSELECT, {
166                 node: node,
167                 src : options && options.src
168             }, {
169                 defaultFn: this._defUnselectFn,
170                 silent   : options && options.silent
171             });
172         }
174         return this;
175     },
177     // -- Protected Methods ----------------------------------------------------
178     _selectableAfterDefAddFn: function (e) {
179         // If the node is marked as selected, we need go through the select
180         // flow.
181         if (e.node.isSelected()) {
182             this.selectNode(e.node);
183         }
184     },
186     _selectableAfterDefClearFn: function () {
187         this._selectedMap = {};
188     },
190     _selectableAfterDefRemoveFn: function (e) {
191         delete e.node.state.selected;
192         delete this._selectedMap[e.node.id];
193     },
195     // -- Protected Event Handlers ---------------------------------------------
196     _afterMultiSelectChange: function () {
197         this.unselect();
198     },
200     _defSelectFn: function (e) {
201         if (!this.get('multiSelect')) {
202             this.unselect();
203         }
205         e.node.state.selected = true;
206         this._selectedMap[e.node.id] = e.node;
207     },
209     _defUnselectFn: function (e) {
210         delete e.node.state.selected;
211         delete this._selectedMap[e.node.id];
212     }
215 Selectable.ATTRS = {
216     /**
217     Whether or not to allow multiple nodes to be selected at once.
219     @attribute {Boolean} multiSelect
220     @default false
221     **/
222     multiSelect: {
223         value: false
224     }
227 Y.Tree.Selectable = Selectable;
229 @module tree
230 @submodule tree-selectable
234 `Tree.Node` extension that adds methods useful for nodes in trees that use the
235 `Tree.Selectable` extension.
237 @class Tree.Node.Selectable
238 @constructor
239 @extensionfor Tree.Node
242 function NodeSelectable() {}
244 NodeSelectable.prototype = {
245     /**
246     Returns `true` if this node is currently selected.
248     @method isSelected
249     @return {Boolean} `true` if this node is currently selected, `false`
250         otherwise.
251     **/
252     isSelected: function () {
253         return !!this.state.selected;
254     },
256     /**
257     Selects this node.
259     @method select
260     @param {Object} [options] Options.
261         @param {Boolean} [options.silent=false] If `true`, the `select` event
262             will be suppressed.
263         @param {String} [options.src] Source of the change, to be passed along
264             to the event facade of the resulting event. This can be used to
265             distinguish between changes triggered by a user and changes
266             triggered programmatically, for example.
267     @chainable
268     **/
269     select: function (options) {
270         this.tree.selectNode(this, options);
271         return this;
272     },
274     /**
275     Unselects this node.
277     @method unselect
278     @param {Object} [options] Options.
279         @param {Boolean} [options.silent=false] If `true`, the `unselect` event
280             will be suppressed.
281         @param {String} [options.src] Source of the change, to be passed along
282             to the event facade of the resulting event. This can be used to
283             distinguish between changes triggered by a user and changes
284             triggered programmatically, for example.
285     @chainable
286     **/
287     unselect: function (options) {
288         this.tree.unselectNode(this, options);
289         return this;
290     }
293 Y.Tree.Node.Selectable = NodeSelectable;
296 }, '3.13.0', {"requires": ["tree"]});