]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | /**\r |
2 | * This examples shows how heterogeneous models can be read into a TreeStore offering the\r | |
3 | * ability to have different entity types at different levels of a tree.\r | |
4 | *\r | |
5 | * This tree is loaded using a linear sequence of records which look just like the data\r | |
6 | * for a regular store. The tree structure is imposed by use of a parentId property in the node's data.\r | |
7 | *\r | |
8 | * The toolbar is aware of the type of the selected node and knows what kind of new entity\r | |
9 | * to add.\r | |
10 | */\r | |
11 | Ext.define('KitchenSink.view.tree.LinearDataTree', {\r | |
12 | extend: 'Ext.tree.Panel',\r | |
13 | \r | |
14 | xtype: 'lineardata-tree',\r | |
15 | \r | |
16 | //<example>\r | |
17 | exampleTitle: 'Linear Data Geographical Tree',\r | |
18 | otherContent: [{\r | |
19 | type: 'Store',\r | |
20 | path: 'classic/samples/store/LinearGeoData.js'\r | |
21 | },{\r | |
22 | type: 'Model',\r | |
23 | path: 'classic/samples/model/tree/Territory.js'\r | |
24 | },{\r | |
25 | type: 'Model',\r | |
26 | path: 'classic/samples/model/tree/Country.js'\r | |
27 | },{\r | |
28 | type: 'Model',\r | |
29 | path: 'classic/samples/model/tree/City.js'\r | |
30 | },{\r | |
31 | type: 'Data',\r | |
32 | path: 'classic/samples/data/LinearGeoData.js'\r | |
33 | }],\r | |
34 | //</example>\r | |
35 | store: 'LinearGeoData',\r | |
36 | rootVisible: false,\r | |
37 | animate: false,\r | |
38 | frame: true,\r | |
39 | title: 'Linear Data Geographical Tree',\r | |
40 | width: 650,\r | |
41 | height: 400,\r | |
42 | reserveScrollbar: true,\r | |
43 | columns: [{\r | |
44 | xtype: 'treecolumn',\r | |
45 | text: 'Name',\r | |
46 | dataIndex: 'name',\r | |
47 | flex: 1,\r | |
48 | sortable: true\r | |
49 | }, {\r | |
50 | text: 'Type',\r | |
51 | renderer: function(v, cellValues, record) {\r | |
52 | return record.entityName;\r | |
53 | }\r | |
54 | }, {\r | |
55 | xtype: 'actioncolumn',\r | |
56 | iconCls: 'lineardata-tree-area-info',\r | |
57 | width: 25,\r | |
58 | getTip: function(value, meta, rec, rowIdx, colIdx, store, view) {\r | |
59 | // Go up from the view to the owning TreePanel\r | |
60 | var panel = view.up('');\r | |
61 | return panel.getActionTip.apply(panel, arguments);\r | |
62 | },\r | |
63 | handler: function(view) {\r | |
64 | // Go up from the view to the owning TreePanel\r | |
65 | var panel = view.up('');\r | |
66 | panel.onDrillAction.apply(panel, arguments);\r | |
67 | }\r | |
68 | }],\r | |
69 | \r | |
70 | selModel: {\r | |
71 | allowDeselect: true,\r | |
72 | listeners: {\r | |
73 | selectionchange: function(selModel, selection) {\r | |
74 | // Go up from the view to the owning TreePanel\r | |
75 | var panel = selModel.view.up('');\r | |
76 | panel.onSelectionChange.apply(panel, arguments);\r | |
77 | }\r | |
78 | },\r | |
79 | onKeyEnter: function() {\r | |
80 | // Go up from the view to the owning TreePanel\r | |
81 | var panel = this.view.up('');\r | |
82 | panel.down('#new-name').focus();\r | |
83 | }\r | |
84 | },\r | |
85 | \r | |
86 | bbar: [{\r | |
87 | xtype: 'textfield',\r | |
88 | itemId: 'new-name',\r | |
89 | enableKeyEvents: true,\r | |
90 | listeners: {\r | |
91 | keydown: function(inputField, e) {\r | |
92 | // Go up from the view to the owning TreePanel\r | |
93 | var panel = inputField.up('treepanel');\r | |
94 | if (e.keyCode === Ext.EventObject.ENTER) {\r | |
95 | if (!panel.down('#add-button').isDisabled()) {\r | |
96 | panel.addClick();\r | |
97 | }\r | |
98 | } else if (e.keyCode === Ext.EventObject.TAB && e.shiftKey) {\r | |
99 | e.stopEvent();\r | |
100 | panel.view.focusRow(panel.selModel.getSelection()[0] || 0);\r | |
101 | }\r | |
102 | }\r | |
103 | }\r | |
104 | }, {\r | |
105 | itemId: 'add-button',\r | |
106 | text: 'Add Territory',\r | |
107 | handler: function(button) {\r | |
108 | // Go up from the view to the owning TreePanel\r | |
109 | var panel = button.up('treepanel');\r | |
110 | panel.addClick();\r | |
111 | }\r | |
112 | }],\r | |
113 | \r | |
114 | addClick: function() {\r | |
115 | var target = this.selModel.getSelection()[0] || this.getRootNode(),\r | |
116 | inputField = this.down('#new-name'),\r | |
117 | value = inputField && inputField.getValue(),\r | |
118 | store = this.getStore(),\r | |
119 | node;\r | |
120 | \r | |
121 | if (value) {\r | |
122 | if (store.getNodeById(value)) {\r | |
123 | Ext.Msg.alert('Error', 'A node with this name already exists.');\r | |
124 | return;\r | |
125 | }\r | |
126 | node = {\r | |
127 | name: value\r | |
128 | };\r | |
129 | \r | |
130 | if (target.isRoot() ) {\r | |
131 | //Nothing selected -- adding new Territory\r | |
132 | node.children = [];\r | |
133 | node.mtype = 'Territory';\r | |
134 | } else if (target instanceof KitchenSink.model.tree.Territory) {\r | |
135 | // Programatically added - must not try to load over Ajax\r | |
136 | node.children = [];\r | |
137 | node.mtype = 'Country';\r | |
138 | } else if (target instanceof KitchenSink.model.tree.Country) {\r | |
139 | // Adding to the Country level - that is our leaf level\r | |
140 | node.leaf = true;\r | |
141 | node.mtype = 'City';\r | |
142 | }\r | |
143 | \r | |
144 | node = target.appendChild(node);\r | |
145 | \r | |
146 | // User might want to see what they've just added!\r | |
147 | if (!target.isExpanded()) {\r | |
148 | target.expand(false);\r | |
149 | }\r | |
150 | this.selModel.select(node);\r | |
151 | inputField.reset();\r | |
152 | }\r | |
153 | },\r | |
154 | \r | |
155 | onSelectionChange: function(selModel, selection) {\r | |
156 | var button = this.down('#add-button'),\r | |
157 | selectedNode;\r | |
158 | \r | |
159 | if (selection.length) {\r | |
160 | selectedNode = selection[0];\r | |
161 | if (selectedNode instanceof KitchenSink.model.tree.Territory) {\r | |
162 | this.addClass = KitchenSink.model.tree.Country;\r | |
163 | button.setText('Add Country');\r | |
164 | button.enable();\r | |
165 | } else if (selectedNode instanceof KitchenSink.model.tree.Country) {\r | |
166 | this.addClass = KitchenSink.model.tree.City;\r | |
167 | button.setText('Add City');\r | |
168 | button.enable();\r | |
169 | } else {\r | |
170 | button.disable();\r | |
171 | }\r | |
172 | } else {\r | |
173 | this.addClass = KitchenSink.model.tree.Territory;\r | |
174 | button.setText('Add Territory');\r | |
175 | button.enable();\r | |
176 | }\r | |
177 | },\r | |
178 | \r | |
179 | getActionTip: function(value, meta, rec, rowIdx, colIdx, store, view) {\r | |
180 | var dataType;\r | |
181 | switch (Ext.ClassManager.getName(rec)) {\r | |
182 | case "KitchenSink.model.tree.Territory":\r | |
183 | dataType = 'territory';\r | |
184 | break;\r | |
185 | case "KitchenSink.model.tree.Country":\r | |
186 | dataType = 'country';\r | |
187 | break;\r | |
188 | case "KitchenSink.model.tree.City":\r | |
189 | dataType = 'city';\r | |
190 | }\r | |
191 | return 'Click for info on ' + dataType;\r | |
192 | },\r | |
193 | \r | |
194 | onDrillAction: function(view, rowIndex, colIndex, row, event, rec) {\r | |
195 | var dataType;\r | |
196 | switch (Ext.ClassManager.getName(rec)) {\r | |
197 | case "KitchenSink.model.tree.Territory":\r | |
198 | dataType = 'territory';\r | |
199 | break;\r | |
200 | case "KitchenSink.model.tree.Country":\r | |
201 | dataType = 'country';\r | |
202 | break;\r | |
203 | case "KitchenSink.model.tree.City":\r | |
204 | dataType = 'city';\r | |
205 | }\r | |
206 | Ext.Msg.alert('Action', 'Drill into ' + dataType + ' details');\r | |
207 | }\r | |
208 | });\r |