make sure the README will appear on github
[extjs.git] / examples / multiselect / ItemSelector.js
1 /*\r
2  * Ext JS Library 2.2.1\r
3  * Copyright(c) 2006-2009, Ext JS, LLC.\r
4  * licensing@extjs.com\r
5  * \r
6  * http://extjs.com/license\r
7  */\r
8 \r
9 /*\r
10  * Note that this control will most likely remain as an example, and not as a core Ext form\r
11  * control.  However, the API will be changing in a future release and so should not yet be\r
12  * treated as a final, stable API at this time.\r
13  */\r
14  \r
15 /** \r
16  * @class Ext.ux.ItemSelector\r
17  * @extends Ext.form.Field\r
18  * A control that allows selection of between two Ext.ux.MultiSelect controls.\r
19  * \r
20  *  @history\r
21  *    2008-06-19 bpm Original code contributed by Toby Stuart (with contributions from Robert Williams)\r
22  * \r
23  * @constructor\r
24  * Create a new ItemSelector\r
25  * @param {Object} config Configuration options\r
26  */\r
27 Ext.ux.ItemSelector = Ext.extend(Ext.form.Field,  {\r
28     msWidth:200,\r
29     msHeight:300,\r
30     hideNavIcons:false,\r
31     imagePath:"",\r
32     iconUp:"up2.gif",\r
33     iconDown:"down2.gif",\r
34     iconLeft:"left2.gif",\r
35     iconRight:"right2.gif",\r
36     iconTop:"top2.gif",\r
37     iconBottom:"bottom2.gif",\r
38     drawUpIcon:true,\r
39     drawDownIcon:true,\r
40     drawLeftIcon:true,\r
41     drawRightIcon:true,\r
42     drawTopIcon:true,\r
43     drawBotIcon:true,\r
44     fromStore:null,\r
45     toStore:null,\r
46     fromData:null, \r
47     toData:null,\r
48     displayField:0,\r
49     valueField:1,\r
50     switchToFrom:false,\r
51     allowDup:false,\r
52     focusClass:undefined,\r
53     delimiter:',',\r
54     readOnly:false,\r
55     toLegend:null,\r
56     fromLegend:null,\r
57     toSortField:null,\r
58     fromSortField:null,\r
59     toSortDir:'ASC',\r
60     fromSortDir:'ASC',\r
61     toTBar:null,\r
62     fromTBar:null,\r
63     bodyStyle:null,\r
64     border:false,\r
65     defaultAutoCreate:{tag: "div"},\r
66     \r
67     initComponent: function(){\r
68         Ext.ux.ItemSelector.superclass.initComponent.call(this);\r
69         this.addEvents({\r
70             'rowdblclick' : true,\r
71             'change' : true\r
72         });         \r
73     },\r
74 \r
75     onRender: function(ct, position){\r
76         Ext.ux.ItemSelector.superclass.onRender.call(this, ct, position);\r
77 \r
78         this.fromMultiselect = new Ext.ux.Multiselect({\r
79             legend: this.fromLegend,\r
80             delimiter: this.delimiter,\r
81             allowDup: this.allowDup,\r
82             copy: this.allowDup,\r
83             allowTrash: this.allowDup,\r
84             dragGroup: this.readOnly ? null : "drop2-"+this.el.dom.id,\r
85             dropGroup: this.readOnly ? null : "drop1-"+this.el.dom.id,\r
86             width: this.msWidth,\r
87             height: this.msHeight,\r
88             dataFields: this.dataFields,\r
89             data: this.fromData,\r
90             displayField: this.displayField,\r
91             valueField: this.valueField,\r
92             store: this.fromStore,\r
93             isFormField: false,\r
94             tbar: this.fromTBar,\r
95             appendOnly: true,\r
96             sortField: this.fromSortField,\r
97             sortDir: this.fromSortDir\r
98         });\r
99         this.fromMultiselect.on('dblclick', this.onRowDblClick, this);\r
100 \r
101         if (!this.toStore) {\r
102             this.toStore = new Ext.data.SimpleStore({\r
103                 fields: this.dataFields,\r
104                 data : this.toData\r
105             });\r
106         }\r
107         this.toStore.on('add', this.valueChanged, this);\r
108         this.toStore.on('remove', this.valueChanged, this);\r
109         this.toStore.on('load', this.valueChanged, this);\r
110 \r
111         this.toMultiselect = new Ext.ux.Multiselect({\r
112             legend: this.toLegend,\r
113             delimiter: this.delimiter,\r
114             allowDup: this.allowDup,\r
115             dragGroup: this.readOnly ? null : "drop1-"+this.el.dom.id,\r
116             //dropGroup: this.readOnly ? null : "drop2-"+this.el.dom.id+(this.toSortField ? "" : ",drop1-"+this.el.dom.id),\r
117             dropGroup: this.readOnly ? null : "drop2-"+this.el.dom.id+",drop1-"+this.el.dom.id,\r
118             width: this.msWidth,\r
119             height: this.msHeight,\r
120             displayField: this.displayField,\r
121             valueField: this.valueField,\r
122             store: this.toStore,\r
123             isFormField: false,\r
124             tbar: this.toTBar,\r
125             sortField: this.toSortField,\r
126             sortDir: this.toSortDir\r
127         });\r
128         this.toMultiselect.on('dblclick', this.onRowDblClick, this);\r
129                 \r
130         var p = new Ext.Panel({\r
131             bodyStyle:this.bodyStyle,\r
132             border:this.border,\r
133             layout:"table",\r
134             layoutConfig:{columns:3}\r
135         });\r
136         p.add(this.switchToFrom ? this.toMultiselect : this.fromMultiselect);\r
137         var icons = new Ext.Panel({header:false});\r
138         p.add(icons);\r
139         p.add(this.switchToFrom ? this.fromMultiselect : this.toMultiselect);\r
140         p.render(this.el);\r
141         icons.el.down('.'+icons.bwrapCls).remove();\r
142 \r
143         if (this.imagePath!="" && this.imagePath.charAt(this.imagePath.length-1)!="/")\r
144             this.imagePath+="/";\r
145         this.iconUp = this.imagePath + (this.iconUp || 'up2.gif');\r
146         this.iconDown = this.imagePath + (this.iconDown || 'down2.gif');\r
147         this.iconLeft = this.imagePath + (this.iconLeft || 'left2.gif');\r
148         this.iconRight = this.imagePath + (this.iconRight || 'right2.gif');\r
149         this.iconTop = this.imagePath + (this.iconTop || 'top2.gif');\r
150         this.iconBottom = this.imagePath + (this.iconBottom || 'bottom2.gif');\r
151         var el=icons.getEl();\r
152         if (!this.toSortField) {\r
153             this.toTopIcon = el.createChild({tag:'img', src:this.iconTop, style:{cursor:'pointer', margin:'2px'}});\r
154             el.createChild({tag: 'br'});\r
155             this.upIcon = el.createChild({tag:'img', src:this.iconUp, style:{cursor:'pointer', margin:'2px'}});\r
156             el.createChild({tag: 'br'});\r
157         }\r
158         this.addIcon = el.createChild({tag:'img', src:this.switchToFrom?this.iconLeft:this.iconRight, style:{cursor:'pointer', margin:'2px'}});\r
159         el.createChild({tag: 'br'});\r
160         this.removeIcon = el.createChild({tag:'img', src:this.switchToFrom?this.iconRight:this.iconLeft, style:{cursor:'pointer', margin:'2px'}});\r
161         el.createChild({tag: 'br'});\r
162         if (!this.toSortField) {\r
163             this.downIcon = el.createChild({tag:'img', src:this.iconDown, style:{cursor:'pointer', margin:'2px'}});\r
164             el.createChild({tag: 'br'});\r
165             this.toBottomIcon = el.createChild({tag:'img', src:this.iconBottom, style:{cursor:'pointer', margin:'2px'}});\r
166         }\r
167         if (!this.readOnly) {\r
168             if (!this.toSortField) {\r
169                 this.toTopIcon.on('click', this.toTop, this);\r
170                 this.upIcon.on('click', this.up, this);\r
171                 this.downIcon.on('click', this.down, this);\r
172                 this.toBottomIcon.on('click', this.toBottom, this);\r
173             }\r
174             this.addIcon.on('click', this.fromTo, this);\r
175             this.removeIcon.on('click', this.toFrom, this);\r
176         }\r
177         if (!this.drawUpIcon || this.hideNavIcons) { this.upIcon.dom.style.display='none'; }\r
178         if (!this.drawDownIcon || this.hideNavIcons) { this.downIcon.dom.style.display='none'; }\r
179         if (!this.drawLeftIcon || this.hideNavIcons) { this.addIcon.dom.style.display='none'; }\r
180         if (!this.drawRightIcon || this.hideNavIcons) { this.removeIcon.dom.style.display='none'; }\r
181         if (!this.drawTopIcon || this.hideNavIcons) { this.toTopIcon.dom.style.display='none'; }\r
182         if (!this.drawBotIcon || this.hideNavIcons) { this.toBottomIcon.dom.style.display='none'; }\r
183 \r
184         var tb = p.body.first();\r
185         this.el.setWidth(p.body.first().getWidth());\r
186         p.body.removeClass();\r
187         \r
188         this.hiddenName = this.name;\r
189         var hiddenTag={tag: "input", type: "hidden", value: "", name:this.name};\r
190         this.hiddenField = this.el.createChild(hiddenTag);\r
191         this.valueChanged(this.toStore);\r
192     },\r
193     \r
194     initValue:Ext.emptyFn,\r
195     \r
196     toTop : function() {\r
197         var selectionsArray = this.toMultiselect.view.getSelectedIndexes();\r
198         var records = [];\r
199         if (selectionsArray.length > 0) {\r
200             selectionsArray.sort();\r
201             for (var i=0; i<selectionsArray.length; i++) {\r
202                 record = this.toMultiselect.view.store.getAt(selectionsArray[i]);\r
203                 records.push(record);\r
204             }\r
205             selectionsArray = [];\r
206             for (var i=records.length-1; i>-1; i--) {\r
207                 record = records[i];\r
208                 this.toMultiselect.view.store.remove(record);\r
209                 this.toMultiselect.view.store.insert(0, record);\r
210                 selectionsArray.push(((records.length - 1) - i));\r
211             }\r
212         }\r
213         this.toMultiselect.view.refresh();\r
214         this.toMultiselect.view.select(selectionsArray);\r
215     },\r
216 \r
217     toBottom : function() {\r
218         var selectionsArray = this.toMultiselect.view.getSelectedIndexes();\r
219         var records = [];\r
220         if (selectionsArray.length > 0) {\r
221             selectionsArray.sort();\r
222             for (var i=0; i<selectionsArray.length; i++) {\r
223                 record = this.toMultiselect.view.store.getAt(selectionsArray[i]);\r
224                 records.push(record);\r
225             }\r
226             selectionsArray = [];\r
227             for (var i=0; i<records.length; i++) {\r
228                 record = records[i];\r
229                 this.toMultiselect.view.store.remove(record);\r
230                 this.toMultiselect.view.store.add(record);\r
231                 selectionsArray.push((this.toMultiselect.view.store.getCount()) - (records.length - i));\r
232             }\r
233         }\r
234         this.toMultiselect.view.refresh();\r
235         this.toMultiselect.view.select(selectionsArray);\r
236     },\r
237     \r
238     up : function() {\r
239         var record = null;\r
240         var selectionsArray = this.toMultiselect.view.getSelectedIndexes();\r
241         selectionsArray.sort();\r
242         var newSelectionsArray = [];\r
243         if (selectionsArray.length > 0) {\r
244             for (var i=0; i<selectionsArray.length; i++) {\r
245                 record = this.toMultiselect.view.store.getAt(selectionsArray[i]);\r
246                 if ((selectionsArray[i] - 1) >= 0) {\r
247                     this.toMultiselect.view.store.remove(record);\r
248                     this.toMultiselect.view.store.insert(selectionsArray[i] - 1, record);\r
249                     newSelectionsArray.push(selectionsArray[i] - 1);\r
250                 }\r
251             }\r
252             this.toMultiselect.view.refresh();\r
253             this.toMultiselect.view.select(newSelectionsArray);\r
254         }\r
255     },\r
256 \r
257     down : function() {\r
258         var record = null;\r
259         var selectionsArray = this.toMultiselect.view.getSelectedIndexes();\r
260         selectionsArray.sort();\r
261         selectionsArray.reverse();\r
262         var newSelectionsArray = [];\r
263         if (selectionsArray.length > 0) {\r
264             for (var i=0; i<selectionsArray.length; i++) {\r
265                 record = this.toMultiselect.view.store.getAt(selectionsArray[i]);\r
266                 if ((selectionsArray[i] + 1) < this.toMultiselect.view.store.getCount()) {\r
267                     this.toMultiselect.view.store.remove(record);\r
268                     this.toMultiselect.view.store.insert(selectionsArray[i] + 1, record);\r
269                     newSelectionsArray.push(selectionsArray[i] + 1);\r
270                 }\r
271             }\r
272             this.toMultiselect.view.refresh();\r
273             this.toMultiselect.view.select(newSelectionsArray);\r
274         }\r
275     },\r
276     \r
277     fromTo : function() {\r
278         var selectionsArray = this.fromMultiselect.view.getSelectedIndexes();\r
279         var records = [];\r
280         if (selectionsArray.length > 0) {\r
281             for (var i=0; i<selectionsArray.length; i++) {\r
282                 record = this.fromMultiselect.view.store.getAt(selectionsArray[i]);\r
283                 records.push(record);\r
284             }\r
285             if(!this.allowDup)selectionsArray = [];\r
286             for (var i=0; i<records.length; i++) {\r
287                 record = records[i];\r
288                 if(this.allowDup){\r
289                     var x=new Ext.data.Record();\r
290                     record.id=x.id;\r
291                     delete x;   \r
292                     this.toMultiselect.view.store.add(record);\r
293                 }else{\r
294                     this.fromMultiselect.view.store.remove(record);\r
295                     this.toMultiselect.view.store.add(record);\r
296                     selectionsArray.push((this.toMultiselect.view.store.getCount() - 1));\r
297                 }\r
298             }\r
299         }\r
300         this.toMultiselect.view.refresh();\r
301         this.fromMultiselect.view.refresh();\r
302         if(this.toSortField)this.toMultiselect.store.sort(this.toSortField, this.toSortDir);\r
303         if(this.allowDup)this.fromMultiselect.view.select(selectionsArray);\r
304         else this.toMultiselect.view.select(selectionsArray);\r
305     },\r
306     \r
307     toFrom : function() {\r
308         var selectionsArray = this.toMultiselect.view.getSelectedIndexes();\r
309         var records = [];\r
310         if (selectionsArray.length > 0) {\r
311             for (var i=0; i<selectionsArray.length; i++) {\r
312                 record = this.toMultiselect.view.store.getAt(selectionsArray[i]);\r
313                 records.push(record);\r
314             }\r
315             selectionsArray = [];\r
316             for (var i=0; i<records.length; i++) {\r
317                 record = records[i];\r
318                 this.toMultiselect.view.store.remove(record);\r
319                 if(!this.allowDup){\r
320                     this.fromMultiselect.view.store.add(record);\r
321                     selectionsArray.push((this.fromMultiselect.view.store.getCount() - 1));\r
322                 }\r
323             }\r
324         }\r
325         this.fromMultiselect.view.refresh();\r
326         this.toMultiselect.view.refresh();\r
327         if(this.fromSortField)this.fromMultiselect.store.sort(this.fromSortField, this.fromSortDir);\r
328         this.fromMultiselect.view.select(selectionsArray);\r
329     },\r
330     \r
331     valueChanged: function(store) {\r
332         var record = null;\r
333         var values = [];\r
334         for (var i=0; i<store.getCount(); i++) {\r
335             record = store.getAt(i);\r
336             values.push(record.get(this.valueField));\r
337         }\r
338         this.hiddenField.dom.value = values.join(this.delimiter);\r
339         this.fireEvent('change', this, this.getValue(), this.hiddenField.dom.value);\r
340     },\r
341     \r
342     getValue : function() {\r
343         return this.hiddenField.dom.value;\r
344     },\r
345     \r
346     onRowDblClick : function(vw, index, node, e) {\r
347         return this.fireEvent('rowdblclick', vw, index, node, e);\r
348     },\r
349     \r
350     reset: function(){\r
351         range = this.toMultiselect.store.getRange();\r
352         this.toMultiselect.store.removeAll();\r
353         if (!this.allowDup) {\r
354             this.fromMultiselect.store.add(range);\r
355             this.fromMultiselect.store.sort(this.displayField,'ASC');\r
356         }\r
357         this.valueChanged(this.toMultiselect.store);\r
358     }\r
359 });\r
360 \r
361 Ext.reg("itemselector", Ext.ux.ItemSelector);