provide installation instructions
[extjs.git] / examples / grid-filtering / grid / filter / ListFilter.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 Ext.grid.filter.ListFilter = Ext.extend(Ext.grid.filter.Filter, {\r
10         labelField:  'text',\r
11         loadingText: 'Loading...',\r
12         loadOnShow:  true,\r
13         value:       [],\r
14         loaded:      false,\r
15         phpMode:     false,\r
16         \r
17         init: function(){\r
18                 this.menu.add('<span class="loading-indicator">' + this.loadingText + '</span>');\r
19                 \r
20                 if(this.store && this.loadOnShow) {\r
21                   this.menu.on('show', this.onMenuLoad, this);\r
22                 } else if(this.options) {\r
23                         var options = [];\r
24                         for(var i=0, len=this.options.length; i<len; i++) {\r
25                                 var value = this.options[i];\r
26                                 switch(Ext.type(value)) {\r
27                                         case 'array':  \r
28             options.push(value);\r
29             break;\r
30                                         case 'object':\r
31             options.push([value.id, value[this.labelField]]);\r
32             break;\r
33                                         case 'string':\r
34             options.push([value, value]);\r
35             break;\r
36                                 }\r
37                         }\r
38                         \r
39                         this.store = new Ext.data.Store({\r
40                                 reader: new Ext.data.ArrayReader({id: 0}, ['id', this.labelField])\r
41                         });\r
42                         this.options = options;\r
43                         this.menu.on('show', this.onMenuLoad, this);\r
44                 }\r
45     \r
46                 this.store.on('load', this.onLoad, this);\r
47                 this.bindShowAdapter();\r
48         },\r
49         \r
50         /**\r
51          * Lists will initially show a 'loading' item while the data is retrieved from the store. In some cases the\r
52          * loaded data will result in a list that goes off the screen to the right (as placement calculations were done\r
53          * with the loading item). This adaptor will allow show to be called with no arguments to show with the previous\r
54          * arguments and thusly recalculate the width and potentially hang the menu from the left.\r
55          * \r
56          */\r
57         bindShowAdapter: function() {\r
58                 var oShow = this.menu.show;\r
59                 var lastArgs = null;\r
60                 this.menu.show = function() {\r
61                         if(arguments.length == 0) {\r
62                                 oShow.apply(this, lastArgs);\r
63                         } else {\r
64                                 lastArgs = arguments;\r
65                                 oShow.apply(this, arguments);\r
66                         }\r
67                 };\r
68         },\r
69         \r
70         onMenuLoad: function() {\r
71                 if(!this.loaded) {\r
72                         if(this.options) {\r
73                                 this.store.loadData(this.options);\r
74       } else {\r
75                                 this.store.load();\r
76       }\r
77                 }\r
78         },\r
79         \r
80         onLoad: function(store, records) {\r
81                 var visible = this.menu.isVisible();\r
82                 this.menu.hide(false);\r
83                 \r
84                 this.menu.removeAll();\r
85                 \r
86                 var gid = this.single ? Ext.id() : null;\r
87                 for(var i=0, len=records.length; i<len; i++) {\r
88                         var item = new Ext.menu.CheckItem({\r
89                                 text: records[i].get(this.labelField), \r
90                                 group: gid, \r
91                                 checked: this.value.indexOf(records[i].id) > -1,\r
92                                 hideOnClick: false\r
93       });\r
94                         \r
95                         item.itemId = records[i].id;\r
96                         item.on('checkchange', this.checkChange, this);\r
97                                                 \r
98                         this.menu.add(item);\r
99                 }\r
100                 \r
101                 this.setActive(this.isActivatable());\r
102                 this.loaded = true;\r
103                 \r
104                 if(visible) {\r
105                         this.menu.show(); //Adaptor will re-invoke with previous arguments\r
106     }\r
107         },\r
108         \r
109         checkChange: function(item, checked) {\r
110                 var value = [];\r
111                 this.menu.items.each(function(item) {\r
112                         if(item.checked) {\r
113                                 value.push(item.itemId);\r
114       }\r
115                 },this);\r
116                 this.value = value;\r
117                 \r
118                 this.setActive(this.isActivatable());\r
119                 this.fireEvent("update", this);\r
120         },\r
121         \r
122         isActivatable: function() {\r
123                 return this.value.length > 0;\r
124         },\r
125         \r
126         setValue: function(value) {\r
127                 var value = this.value = [].concat(value);\r
128 \r
129                 if(this.loaded) {\r
130                         this.menu.items.each(function(item) {\r
131                                 item.setChecked(false, true);\r
132                                 for(var i=0, len=value.length; i<len; i++) {\r
133                                         if(item.itemId == value[i]) {\r
134                                                 item.setChecked(true, true);\r
135           }\r
136         }\r
137                         }, this);\r
138     }\r
139                         \r
140                 this.fireEvent("update", this);\r
141         },\r
142         \r
143         getValue: function() {\r
144                 return this.value;\r
145         },\r
146         \r
147         serialize: function() {\r
148     var args = {type: 'list', value: this.phpMode ? this.value.join(',') : this.value};\r
149     this.fireEvent('serialize', args, this);\r
150                 return args;\r
151         },\r
152         \r
153         validateRecord: function(record) {\r
154                 return this.getValue().indexOf(record.get(this.dataIndex)) > -1;\r
155         }\r
156 });