Upgrade to ExtJS 4.0.7 - Released 10/19/2011
[extjs.git] / docs / source / NodeStore.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4   <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
5   <title>The source code</title>
6   <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
7   <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
8   <style type="text/css">
9     .highlight { display: block; background-color: #ddd; }
10   </style>
11   <script type="text/javascript">
12     function highlight() {
13       document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
14     }
15   </script>
16 </head>
17 <body onload="prettyPrint(); highlight();">
18   <pre class="prettyprint lang-js"><span id='Ext-data-NodeStore'>/**
19 </span> * @class Ext.data.NodeStore
20  * @extends Ext.data.AbstractStore
21  * Node Store
22  * @ignore
23  */
24 Ext.define('Ext.data.NodeStore', {
25     extend: 'Ext.data.Store',
26     alias: 'store.node',
27     requires: ['Ext.data.NodeInterface'],
28     
29 <span id='Ext-data-NodeStore-cfg-node'>    /**
30 </span>     * @cfg {Ext.data.Model} node
31      * The Record you want to bind this Store to. Note that
32      * this record will be decorated with the Ext.data.NodeInterface if this is not the
33      * case yet.
34      */
35     node: null,
36     
37 <span id='Ext-data-NodeStore-cfg-recursive'>    /**
38 </span>     * @cfg {Boolean} recursive
39      * Set this to true if you want this NodeStore to represent
40      * all the descendents of the node in its flat data collection. This is useful for
41      * rendering a tree structure to a DataView and is being used internally by
42      * the TreeView. Any records that are moved, removed, inserted or appended to the
43      * node at any depth below the node this store is bound to will be automatically
44      * updated in this Store's internal flat data structure.
45      */
46     recursive: false,
47     
48 <span id='Ext-data-NodeStore-cfg-rootVisible'>    /** 
49 </span>     * @cfg {Boolean} rootVisible
50      * False to not include the root node in this Stores collection.
51      */    
52     rootVisible: false,
53     
54     constructor: function(config) {
55         var me = this,
56             node;
57             
58         config = config || {};
59         Ext.apply(me, config);
60         
61         //&lt;debug&gt;
62         if (Ext.isDefined(me.proxy)) {
63             Ext.Error.raise(&quot;A NodeStore cannot be bound to a proxy. Instead bind it to a record &quot; +
64                             &quot;decorated with the NodeInterface by setting the node config.&quot;);
65         }
66         //&lt;/debug&gt;
67
68         config.proxy = {type: 'proxy'};
69         me.callParent([config]);
70
71         me.addEvents('expand', 'collapse', 'beforeexpand', 'beforecollapse');
72         
73         node = me.node;
74         if (node) {
75             me.node = null;
76             me.setNode(node);
77         }
78     },
79     
80     setNode: function(node) {
81         var me = this;
82         
83         if (me.node &amp;&amp; me.node != node) {
84             // We want to unbind our listeners on the old node
85             me.mun(me.node, {
86                 expand: me.onNodeExpand,
87                 collapse: me.onNodeCollapse,
88                 append: me.onNodeAppend,
89                 insert: me.onNodeInsert,
90                 remove: me.onNodeRemove,
91                 sort: me.onNodeSort,
92                 scope: me
93             });
94             me.node = null;
95         }
96         
97         if (node) {
98             Ext.data.NodeInterface.decorate(node);
99             me.removeAll();
100             if (me.rootVisible) {
101                 me.add(node);
102             }
103             me.mon(node, {
104                 expand: me.onNodeExpand,
105                 collapse: me.onNodeCollapse,
106                 append: me.onNodeAppend,
107                 insert: me.onNodeInsert,
108                 remove: me.onNodeRemove,
109                 sort: me.onNodeSort,
110                 scope: me
111             });
112             me.node = node;
113             if (node.isExpanded() &amp;&amp; node.isLoaded()) {
114                 me.onNodeExpand(node, node.childNodes, true);
115             }
116         }
117     },
118     
119     onNodeSort: function(node, childNodes) {
120         var me = this;
121         
122         if ((me.indexOf(node) !== -1 || (node === me.node &amp;&amp; !me.rootVisible) &amp;&amp; node.isExpanded())) {
123             me.onNodeCollapse(node, childNodes, true);
124             me.onNodeExpand(node, childNodes, true);
125         }
126     },
127     
128     onNodeExpand: function(parent, records, suppressEvent) {
129         var me = this,
130             insertIndex = me.indexOf(parent) + 1,
131             ln = records ? records.length : 0,
132             i, record;
133             
134         if (!me.recursive &amp;&amp; parent !== me.node) {
135             return;
136         }
137         
138         if (!me.isVisible(parent)) {
139             return;
140         }
141
142         if (!suppressEvent &amp;&amp; me.fireEvent('beforeexpand', parent, records, insertIndex) === false) {
143             return;
144         }
145         
146         if (ln) {
147             me.insert(insertIndex, records);
148             for (i = 0; i &lt; ln; i++) {
149                 record = records[i];
150                 if (record.isExpanded()) {
151                     if (record.isLoaded()) {
152                         // Take a shortcut                        
153                         me.onNodeExpand(record, record.childNodes, true);
154                     }
155                     else {
156                         record.set('expanded', false);
157                         record.expand();
158                     }
159                 }
160             }
161         }
162
163         if (!suppressEvent) {
164             me.fireEvent('expand', parent, records);
165         }
166     },
167
168     onNodeCollapse: function(parent, records, suppressEvent) {
169         var me = this,
170             ln = records.length,
171             collapseIndex = me.indexOf(parent) + 1,
172             i, record;
173             
174         if (!me.recursive &amp;&amp; parent !== me.node) {
175             return;
176         }
177         
178         if (!suppressEvent &amp;&amp; me.fireEvent('beforecollapse', parent, records, collapseIndex) === false) {
179             return;
180         }
181
182         for (i = 0; i &lt; ln; i++) {
183             record = records[i];
184             me.remove(record);
185             if (record.isExpanded()) {
186                 me.onNodeCollapse(record, record.childNodes, true);
187             }
188         }
189         
190         if (!suppressEvent) {
191             me.fireEvent('collapse', parent, records, collapseIndex);
192         }
193     },
194     
195     onNodeAppend: function(parent, node, index) {
196         var me = this,
197             refNode, sibling;
198
199         if (me.isVisible(node)) {
200             if (index === 0) {
201                 refNode = parent;
202             } else {
203                 sibling = node.previousSibling;
204                 while (sibling.isExpanded() &amp;&amp; sibling.lastChild) {
205                     sibling = sibling.lastChild;
206                 }
207                 refNode = sibling;
208             }
209             me.insert(me.indexOf(refNode) + 1, node);
210             if (!node.isLeaf() &amp;&amp; node.isExpanded()) {
211                 if (node.isLoaded()) {
212                     // Take a shortcut                        
213                     me.onNodeExpand(node, node.childNodes, true);
214                 }
215                 else {
216                     node.set('expanded', false);
217                     node.expand();
218                 }
219             }
220         } 
221     },
222     
223     onNodeInsert: function(parent, node, refNode) {
224         var me = this,
225             index = this.indexOf(refNode);
226             
227         if (index != -1 &amp;&amp; me.isVisible(node)) {
228             me.insert(index, node);
229             if (!node.isLeaf() &amp;&amp; node.isExpanded()) {
230                 if (node.isLoaded()) {
231                     // Take a shortcut                        
232                     me.onNodeExpand(node, node.childNodes, true);
233                 }
234                 else {
235                     node.set('expanded', false);
236                     node.expand();
237                 }
238             }
239         }
240     },
241     
242     onNodeRemove: function(parent, node, index) {
243         var me = this;
244         if (me.indexOf(node) != -1) {
245             if (!node.isLeaf() &amp;&amp; node.isExpanded()) {
246                 me.onNodeCollapse(node, node.childNodes, true);
247             }            
248             me.remove(node);
249         }
250     },
251     
252     isVisible: function(node) {
253         var parent = node.parentNode;
254         while (parent) {
255             if (parent === this.node &amp;&amp; !this.rootVisible &amp;&amp; parent.isExpanded()) {
256                 return true;
257             }
258             
259             if (this.indexOf(parent) === -1 || !parent.isExpanded()) {
260                 return false;
261             }
262             
263             parent = parent.parentNode;
264         }
265         return true;
266     }
267 });</pre>
268 </body>
269 </html>