/*!
- * Ext JS Library 3.1.0
- * Copyright(c) 2006-2009 Ext JS, LLC
+ * Ext JS Library 3.1.1
+ * Copyright(c) 2006-2010 Ext JS, LLC
* licensing@extjs.com
* http://www.extjs.com/license
*/
* The filter collection binds to the\r
* <code>{@link Ext.grid.GridPanel#beforestaterestore beforestaterestore}</code>\r
* and <code>{@link Ext.grid.GridPanel#beforestatesave beforestatesave}</code>\r
- * events in order to be stateful. \r
+ * events in order to be stateful.\r
* </div></li>\r
* <li><b>Grid Changes</b> :\r
* <div class="sub-desc"><ul>\r
* </ul></div></li>\r
* </ul></div>\r
* <p><b><u>Example usage:</u></b></p>\r
- * <pre><code> \r
+ * <pre><code>\r
var store = new Ext.data.GroupingStore({\r
...\r
});\r
- \r
+\r
var filters = new Ext.ux.grid.GridFilters({\r
autoReload: false, //don't reload automatically\r
local: true, //only filter locally\r
var cm = new Ext.grid.ColumnModel([{\r
...\r
}]);\r
- \r
+\r
var grid = new Ext.grid.GridPanel({\r
ds: store,\r
cm: cm,\r
init : function (grid) {\r
if (grid instanceof Ext.grid.GridPanel) {\r
this.grid = grid;\r
- \r
+\r
this.bindStore(this.grid.getStore(), true);\r
// assumes no filters were passed in the constructor, so try and use ones from the colModel\r
if(this.filters.getCount() == 0){\r
this.addFilters(this.grid.getColumnModel());\r
}\r
- \r
+\r
this.grid.filters = this;\r
- \r
+\r
this.grid.addEvents({'filterupdate': true});\r
- \r
+\r
grid.on({\r
scope: this,\r
beforestaterestore: this.applyState,\r
beforedestroy: this.destroy,\r
reconfigure: this.onReconfigure\r
});\r
- \r
+\r
if (grid.rendered){\r
this.onRender();\r
} else {\r
render: this.onRender\r
});\r
}\r
- \r
+\r
} else if (grid instanceof Ext.PagingToolbar) {\r
this.toolbar = grid;\r
}\r
},\r
- \r
+\r
/**\r
* @private\r
* Handler for the grid's beforestaterestore event (fires before the state of the\r
* grid is restored).\r
* @param {Object} grid The grid object\r
* @param {Object} state The hash of state values returned from the StateProvider.\r
- */ \r
+ */\r
applyState : function (grid, state) {\r
var key, filter;\r
this.applyingState = true;\r
}\r
delete this.applyingState;\r
},\r
- \r
+\r
/**\r
* Saves the state of all active filters\r
* @param {Object} grid\r
});\r
return (state.filters = filters);\r
},\r
- \r
+\r
/**\r
* @private\r
* Handler called when the grid is rendered\r
- */ \r
+ */\r
onRender : function () {\r
this.grid.getView().on('refresh', this.onRefresh, this);\r
this.createMenu();\r
/**\r
* @private\r
* Handler called by the grid 'beforedestroy' event\r
- */ \r
+ */\r
destroy : function () {\r
this.removeAll();\r
this.purgeListeners();\r
if(this.filterMenu){\r
Ext.menu.MenuMgr.unregister(this.filterMenu);\r
this.filterMenu.destroy();\r
- this.filterMenu = this.menu.menu = null; \r
+ this.filterMenu = this.menu.menu = null;\r
}\r
},\r
\r
/**\r
* Remove all filters, permanently destroying them.\r
- */ \r
+ */\r
removeAll : function () {\r
if(this.filters){\r
Ext.destroy.apply(Ext, this.filters.items);\r
- // remove all items from the collection \r
+ // remove all items from the collection\r
this.filters.clear();\r
}\r
},\r
/**\r
* @private\r
* Handler called when the grid reconfigure event fires\r
- */ \r
+ */\r
onReconfigure : function () {\r
this.bindStore(this.grid.getStore());\r
this.store.clearFilter();\r
hmenu = view.hmenu;\r
\r
if (this.showMenu && hmenu) {\r
- \r
+\r
this.sep = hmenu.addSeparator();\r
this.filterMenu = new Ext.menu.Menu({\r
id: this.grid.id + '-filters-menu'\r
- }); \r
+ });\r
this.menu = hmenu.add({\r
checked: false,\r
itemId: 'filters',\r
/**\r
* @private\r
* Handler called by the grid's hmenu beforeshow event\r
- */ \r
+ */\r
onMenu : function (filterMenu) {\r
var filter = this.getMenuFilter();\r
\r
if (filter) {\r
-/* \r
+/*\r
TODO: lazy rendering\r
if (!filter.menu) {\r
filter.menu = filter.createMenu();\r
// disable the menu if filter.disabled explicitly set to true\r
this.menu.setDisabled(filter.disabled === true);\r
}\r
- \r
+\r
this.menu.setVisible(filter !== undefined);\r
this.sep.setVisible(filter !== undefined);\r
},\r
- \r
+\r
/** @private */\r
onCheckChange : function (item, value) {\r
this.getMenuFilter().setActive(value);\r
},\r
- \r
+\r
/** @private */\r
onBeforeCheck : function (check, value) {\r
return !value || this.getMenuFilter().isActivatable();\r
* Handler for all events on filters.\r
* @param {String} event Event name\r
* @param {Object} filter Standard signature of the event before the event is fired\r
- */ \r
+ */\r
onStateChange : function (event, filter) {\r
if (event === 'serialize') {\r
return;\r
this.deferredUpdate.delay(this.updateBuffer);\r
}\r
this.updateColumnHeadings();\r
- \r
+\r
if (!this.applyingState) {\r
this.grid.saveState();\r
- } \r
+ }\r
this.grid.fireEvent('filterupdate', this, filter);\r
},\r
- \r
+\r
/**\r
* @private\r
* Handler for store's beforeload event when configured for remote filtering\r
*/\r
onBeforeLoad : function (store, options) {\r
options.params = options.params || {};\r
- this.cleanParams(options.params); \r
+ this.cleanParams(options.params);\r
var params = this.buildQuery(this.getFilterData());\r
Ext.apply(options.params, params);\r
},\r
- \r
+\r
/**\r
* @private\r
* Handler for store's load event when configured for local filtering\r
/**\r
* @private\r
* Handler called when the grid's view is refreshed\r
- */ \r
+ */\r
onRefresh : function () {\r
this.updateColumnHeadings();\r
},\r
\r
/**\r
* Update the styles for the header row based on the active filters\r
- */ \r
+ */\r
updateColumnHeadings : function () {\r
var view = this.grid.getView(),\r
- hds, i, len, filter;\r
+ i, len, filter;\r
if (view.mainHd) {\r
- hds = view.mainHd.select('td').removeClass(this.filterCls);\r
for (i = 0, len = view.cm.config.length; i < len; i++) {\r
filter = this.getFilter(view.cm.config[i].dataIndex);\r
- if (filter && filter.active) {\r
- hds.item(i).addClass(this.filterCls);\r
- }\r
+ Ext.fly(view.getHeaderCell(i))[filter && filter.active ? 'addClass' : 'removeClass'](this.filterCls);\r
}\r
}\r
},\r
- \r
+\r
/** @private */\r
reload : function () {\r
if (this.local) {\r
store.reload();\r
}\r
},\r
- \r
+\r
/**\r
* Method factory that generates a record validator for the filters active at the time\r
* of invokation.\r
f.push(filter);\r
}\r
});\r
- \r
+\r
len = f.length;\r
return function (record) {\r
for (i = 0; i < len; i++) {\r
return true;\r
};\r
},\r
- \r
+\r
/**\r
* Adds a filter to the collection and observes it for state change.\r
* @param {Object/Ext.ux.grid.filter.Filter} config A filter configuration or a filter object.\r
var Cls = this.getFilterClass(config.type),\r
filter = config.menu ? config : (new Cls(config));\r
this.filters.add(filter);\r
- \r
+\r
Ext.util.Observable.capture(filter, this.onStateChange, this);\r
return filter;\r
},\r
* @param {Array/Ext.grid.ColumnModel} filters Either an Array of\r
* filter configuration objects or an Ext.grid.ColumnModel. The columns\r
* of a passed Ext.grid.ColumnModel will be examined for a <code>filter</code>\r
- * property and, if present, will be used as the filter configuration object. \r
+ * property and, if present, will be used as the filter configuration object.\r
*/\r
addFilters : function (filters) {\r
if (filters) {\r
// filter type is specified in order of preference:\r
// filter type specified in config\r
// type specified in store's field's type config\r
- filter.type = filter.type || this.store.fields.get(dI).type; \r
+ filter.type = filter.type || this.store.fields.get(dI).type;\r
}\r
} else {\r
filter = filters[i];\r
}\r
- // if filter config found add filter for the column \r
+ // if filter config found add filter for the column\r
if (filter) {\r
this.addFilter(filter);\r
}\r
}\r
}\r
},\r
- \r
+\r
/**\r
* Returns a filter for the given dataIndex, if one exists.\r
* @param {String} dataIndex The dataIndex of the desired filter object.\r
});\r
return filters;\r
},\r
- \r
+\r
/**\r
* Function to take the active filters data and build it into a query.\r
* The format of the query depends on the <code>{@link #encode}</code>\r
* configuration:\r
* <div class="mdetail-params"><ul>\r
- * \r
+ *\r
* <li><b><tt>false</tt></b> : <i>Default</i>\r
* <div class="sub-desc">\r
* Flatten into query string of the form (assuming <code>{@link #paramPrefix}='filters'</code>:\r
filters[0][data][value]="someValue3"&\r
* </code></pre>\r
* </div></li>\r
- * <li><b><tt>true</tt></b> : \r
+ * <li><b><tt>true</tt></b> :\r
* <div class="sub-desc">\r
* JSON encode the filter data\r
* <pre><code>\r
f = filters[i];\r
root = [this.paramPrefix, '[', i, ']'].join('');\r
p[root + '[field]'] = f.field;\r
- \r
+\r
dataPrefix = root + '[data]';\r
for (key in f.data) {\r
p[[dataPrefix, '[', key, ']'].join('')] = f.data[key];\r
f.data\r
));\r
}\r
- // only build if there is active filter \r
+ // only build if there is active filter\r
if (tmp.length > 0){\r
p[this.paramPrefix] = Ext.util.JSON.encode(tmp);\r
}\r
}\r
return p;\r
},\r
- \r
+\r
/**\r
* Removes filter related query parameters from the provided object.\r
* @param {Object} p Query parameters that may contain filter related fields.\r
}\r
}\r
},\r
- \r
+\r
/**\r
* Function for locating filter classes, overwrite this with your favorite\r
* loader to provide dynamic filter loading.\r
* @param {String} type The type of filter to load ('Filter' is automatically\r
* appended to the passed type; eg, 'string' becomes 'StringFilter').\r
- * @return {Class} The Ext.ux.grid.filter.Class \r
+ * @return {Class} The Ext.ux.grid.filter.Class\r
*/\r
getFilterClass : function (type) {\r
// map the supported Ext.data.Field type values into a supported filter\r