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