X-Git-Url: http://git.ithinksw.org/extjs.git/blobdiff_plain/25ef3491bd9ae007ff1fc2b0d7943e6eaaccf775..6e39d509471fe9b4e2660e0d1631b350d0c66f40:/docs/source/GridFilters.html?ds=sidebyside diff --git a/docs/source/GridFilters.html b/docs/source/GridFilters.html deleted file mode 100644 index fab10ac2..00000000 --- a/docs/source/GridFilters.html +++ /dev/null @@ -1,738 +0,0 @@ - -
-Ext.namespace('Ext.ux.grid'); - -/** - * @class Ext.ux.grid.GridFilters - * @extends Ext.util.Observable - *- - \ No newline at end of fileGridFilter is a plugin (
- *ptype='gridfilters'
) for grids that - * allow for a slightly more robust representation of filtering than what is - * provided by the default store.Filtering is adjusted by the user using the grid's column header menu - * (this menu can be disabled through configuration). Through this menu users - * can configure, enable, and disable filters for each column.
- *Features:
- *- *- *
- Filtering implementations : - *
- *- * Default filtering for Strings, Numeric Ranges, Date Ranges, Lists (which can - * be backed by a Ext.data.Store), and Boolean. Additional custom filter types - * and menus are easily created by extending Ext.ux.grid.filter.Filter. - *- Graphical indicators : - *
- *- * Columns that are filtered have {@link #filterCls a configurable css class} - * applied to the column headers. - *- Paging : - *
- *- * If specified as a plugin to the grid's configured PagingToolbar, the current page - * will be reset to page 1 whenever you update the filters. - *- Automatic Reconfiguration : - *
- *- * Filters automatically reconfigure when the grid 'reconfigure' event fires. - *- Stateful : - * Filter information will be persisted across page loads by specifying a - *
- *stateId
in the Grid configuration. - *- * The filter collection binds to the - *{@link Ext.grid.GridPanel#beforestaterestore beforestaterestore}
- * and{@link Ext.grid.GridPanel#beforestatesave beforestatesave}
- * events in order to be stateful. - *- Grid Changes : - *
- *- *
- A
- *filters
property is added to the grid pointing to - * this plugin.- A
- *filterupdate
event is added to the grid and is - * fired upon onStateChange completion.- Server side code examples : - *
- *- *
- PHP - (Thanks VinylFox)
- *- Ruby on Rails - (Thanks Zyclops)
- *- Ruby on Rails - (Thanks Rotomaul)
- *- Python - (Thanks Matt)
- *- Grails - (Thanks Mike)
- *Example usage:
- *- */ -Ext.ux.grid.GridFilters = Ext.extend(Ext.util.Observable, { - /** - * @cfg {Boolean} autoReload - * Defaults to true, reloading the datasource when a filter change happens. - * Set this to false to prevent the datastore from being reloaded if there - * are changes to the filters. See-var store = new Ext.data.GroupingStore({ - ... -}); - -var filters = new Ext.ux.grid.GridFilters({ - autoReload: false, //don't reload automatically - local: true, //only filter locally - // filters may be configured through the plugin, - // or in the column definition within the column model configuration - filters: [{ - type: 'numeric', - dataIndex: 'id' - }, { - type: 'string', - dataIndex: 'name' - }, { - type: 'numeric', - dataIndex: 'price' - }, { - type: 'date', - dataIndex: 'dateAdded' - }, { - type: 'list', - dataIndex: 'size', - options: ['extra small', 'small', 'medium', 'large', 'extra large'], - phpMode: true - }, { - type: 'boolean', - dataIndex: 'visible' - }] -}); -var cm = new Ext.grid.ColumnModel([{ - ... -}]); - -var grid = new Ext.grid.GridPanel({ - ds: store, - cm: cm, - view: new Ext.grid.GroupingView(), - plugins: [filters], - height: 400, - width: 700, - bbar: new Ext.PagingToolbar({ - store: store, - pageSize: 15, - plugins: [filters] //reset page to page 1 if filters change - }) - }); - -store.load({params: {start: 0, limit: 15}}); - -// a filters property is added to the grid -grid.filters - *
{@link updateBuffer}
. - */ - autoReload : true, - /** - * @cfg {Boolean} encode - * Specify true for {@link #buildQuery} to use Ext.util.JSON.encode to - * encode the filter query parameter sent with a remote request. - * Defaults to false. - */ - /** - * @cfg {Array} filters - * An Array of filters config objects. Refer to each filter type class for - * configuration details specific to each filter type. Filters for Strings, - * Numeric Ranges, Date Ranges, Lists, and Boolean are the standard filters - * available. - */ - /** - * @cfg {String} filterCls - * The css class to be applied to column headers with active filters. - * Defaults to 'ux-filterd-column'. - */ - filterCls : 'ux-filtered-column', - /** - * @cfg {Boolean} local - * true to use Ext.data.Store filter functions (local filtering) - * instead of the default (false) server side filtering. - */ - local : false, - /** - * @cfg {String} menuFilterText - * defaults to 'Filters'. - */ - menuFilterText : 'Filters', - /** - * @cfg {String} paramPrefix - * The url parameter prefix for the filters. - * Defaults to 'filter'. - */ - paramPrefix : 'filter', - /** - * @cfg {Boolean} showMenu - * Defaults to true, including a filter submenu in the default header menu. - */ - showMenu : true, - /** - * @cfg {String} stateId - * Name of the value to be used to store state information. - */ - stateId : undefined, - /** - * @cfg {Integer} updateBuffer - * Number of milliseconds to defer store updates since the last filter change. - */ - updateBuffer : 500, - - /** @private */ - constructor : function (config) { - this.deferredUpdate = new Ext.util.DelayedTask(this.reload, this); - this.filters = new Ext.util.MixedCollection(); - this.filters.getKey = function (o) { - return o ? o.dataIndex : null; - }; - this.addFilters(config.filters); - delete config.filters; - Ext.apply(this, config); - }, - - /** @private */ - init : function (grid) { - if (grid instanceof Ext.grid.GridPanel) { - this.grid = grid; - - this.bindStore(this.grid.getStore(), true); - - this.grid.filters = this; - - this.grid.addEvents({'filterupdate': true}); - - grid.on({ - scope: this, - beforestaterestore: this.applyState, - beforestatesave: this.saveState, - beforedestroy: this.destroy, - reconfigure: this.onReconfigure - }); - - if (grid.rendered){ - this.onRender(); - } else { - grid.on({ - scope: this, - single: true, - render: this.onRender - }); - } - - } else if (grid instanceof Ext.PagingToolbar) { - this.toolbar = grid; - } - }, - - /** - * @private - * Handler for the grid's beforestaterestore event (fires before the state of the - * grid is restored). - * @param {Object} grid The grid object - * @param {Object} state The hash of state values returned from the StateProvider. - */ - applyState : function (grid, state) { - var key, filter; - this.applyingState = true; - this.clearFilters(); - if (state.filters) { - for (key in state.filters) { - filter = this.filters.get(key); - if (filter) { - filter.setValue(state.filters[key]); - filter.setActive(true); - } - } - } - this.deferredUpdate.cancel(); - if (this.local) { - this.reload(); - } - delete this.applyingState; - }, - - /** - * Saves the state of all active filters - * @param {Object} grid - * @param {Object} state - * @return {Boolean} - */ - saveState : function (grid, state) { - var filters = {}; - this.filters.each(function (filter) { - if (filter.active) { - filters[filter.dataIndex] = filter.getValue(); - } - }); - return (state.filters = filters); - }, - - /** - * @private - * Handler called when the grid is rendered - */ - onRender : function () { - this.grid.getView().on('refresh', this.onRefresh, this); - this.createMenu(); - }, - - /** - * @private - * Handler called by the grid 'beforedestroy' event - */ - destroy : function () { - this.removeAll(); - this.purgeListeners(); - - if(this.filterMenu){ - Ext.menu.MenuMgr.unregister(this.filterMenu); - this.filterMenu.destroy(); - this.filterMenu = this.menu.menu = null; - } - }, - - /** - * Remove all filters, permanently destroying them. - */ - removeAll : function () { - if(this.filters){ - Ext.destroy.apply(Ext, this.filters.items); - // remove all items from the collection - this.filters.clear(); - } - }, - - - /** - * Changes the data store bound to this view and refreshes it. - * @param {Store} store The store to bind to this view - */ - bindStore : function(store, initial){ - if(!initial && this.store){ - if (this.local) { - store.un('load', this.onLoad, this); - } else { - store.un('beforeload', this.onBeforeLoad, this); - } - } - if(store){ - if (this.local) { - store.on('load', this.onLoad, this); - } else { - store.on('beforeload', this.onBeforeLoad, this); - } - } - this.store = store; - }, - - /** - * @private - * Handler called when the grid reconfigure event fires - */ - onReconfigure : function () { - this.bindStore(this.grid.getStore()); - this.store.clearFilter(); - this.removeAll(); - this.addFilters(this.grid.getColumnModel()); - this.updateColumnHeadings(); - }, - - createMenu : function () { - var view = this.grid.getView(), - hmenu = view.hmenu; - - if (this.showMenu && hmenu) { - - this.sep = hmenu.addSeparator(); - this.filterMenu = new Ext.menu.Menu({ - id: this.grid.id + '-filters-menu' - }); - this.menu = hmenu.add({ - checked: false, - itemId: 'filters', - text: this.menuFilterText, - menu: this.filterMenu - }); - - this.menu.on({ - scope: this, - checkchange: this.onCheckChange, - beforecheckchange: this.onBeforeCheck - }); - hmenu.on('beforeshow', this.onMenu, this); - } - this.updateColumnHeadings(); - }, - - /** - * @private - * Get the filter menu from the filters MixedCollection based on the clicked header - */ - getMenuFilter : function () { - var view = this.grid.getView(); - if (!view || view.hdCtxIndex === undefined) { - return null; - } - return this.filters.get( - view.cm.config[view.hdCtxIndex].dataIndex - ); - }, - - /** - * @private - * Handler called by the grid's hmenu beforeshow event - */ - onMenu : function (filterMenu) { - var filter = this.getMenuFilter(); - - if (filter) { -/* -TODO: lazy rendering - if (!filter.menu) { - filter.menu = filter.createMenu(); - } -*/ - this.menu.menu = filter.menu; - this.menu.setChecked(filter.active, false); - // disable the menu if filter.disabled explicitly set to true - this.menu.setDisabled(filter.disabled === true); - } - - this.menu.setVisible(filter !== undefined); - this.sep.setVisible(filter !== undefined); - }, - - /** @private */ - onCheckChange : function (item, value) { - this.getMenuFilter().setActive(value); - }, - - /** @private */ - onBeforeCheck : function (check, value) { - return !value || this.getMenuFilter().isActivatable(); - }, - - /** - * @private - * Handler for all events on filters. - * @param {String} event Event name - * @param {Object} filter Standard signature of the event before the event is fired - */ - onStateChange : function (event, filter) { - if (event === 'serialize') { - return; - } - - if (filter == this.getMenuFilter()) { - this.menu.setChecked(filter.active, false); - } - - if ((this.autoReload || this.local) && !this.applyingState) { - this.deferredUpdate.delay(this.updateBuffer); - } - this.updateColumnHeadings(); - - if (!this.applyingState) { - this.grid.saveState(); - } - this.grid.fireEvent('filterupdate', this, filter); - }, - - /** - * @private - * Handler for store's beforeload event when configured for remote filtering - * @param {Object} store - * @param {Object} options - */ - onBeforeLoad : function (store, options) { - options.params = options.params || {}; - this.cleanParams(options.params); - var params = this.buildQuery(this.getFilterData()); - Ext.apply(options.params, params); - }, - - /** - * @private - * Handler for store's load event when configured for local filtering - * @param {Object} store - * @param {Object} options - */ - onLoad : function (store, options) { - store.filterBy(this.getRecordFilter()); - }, - - /** - * @private - * Handler called when the grid's view is refreshed - */ - onRefresh : function () { - this.updateColumnHeadings(); - }, - - /** - * Update the styles for the header row based on the active filters - */ - updateColumnHeadings : function () { - var view = this.grid.getView(), - hds, i, len, filter; - if (view.mainHd) { - hds = view.mainHd.select('td').removeClass(this.filterCls); - for (i = 0, len = view.cm.config.length; i < len; i++) { - filter = this.getFilter(view.cm.config[i].dataIndex); - if (filter && filter.active) { - hds.item(i).addClass(this.filterCls); - } - } - } - }, - - /** @private */ - reload : function () { - if (this.local) { - this.grid.store.clearFilter(true); - this.grid.store.filterBy(this.getRecordFilter()); - } else { - var start, - store = this.grid.store; - this.deferredUpdate.cancel(); - if (this.toolbar) { - start = store.paramNames.start; - if (store.lastOptions && store.lastOptions.params && store.lastOptions.params[start]) { - store.lastOptions.params[start] = 0; - } - } - store.reload(); - } - }, - - /** - * Method factory that generates a record validator for the filters active at the time - * of invokation. - * @private - */ - getRecordFilter : function () { - var f = [], len, i; - this.filters.each(function (filter) { - if (filter.active) { - f.push(filter); - } - }); - - len = f.length; - return function (record) { - for (i = 0; i < len; i++) { - if (!f[i].validateRecord(record)) { - return false; - } - } - return true; - }; - }, - - /** - * Adds a filter to the collection and observes it for state change. - * @param {Object/Ext.ux.grid.filter.Filter} config A filter configuration or a filter object. - * @return {Ext.ux.grid.filter.Filter} The existing or newly created filter object. - */ - addFilter : function (config) { - var Cls = this.getFilterClass(config.type), - filter = config.menu ? config : (new Cls(config)); - this.filters.add(filter); - - Ext.util.Observable.capture(filter, this.onStateChange, this); - return filter; - }, - - /** - * Adds filters to the collection. - * @param {Array/Ext.grid.ColumnModel} filters Either an Array of - * filter configuration objects or an Ext.grid.ColumnModel. The columns - * of a passed Ext.grid.ColumnModel will be examined for afilter
- * property and, if present, will be used as the filter configuration object. - */ - addFilters : function (filters) { - if (filters) { - var i, len, filter, cm = false, dI; - if (filters instanceof Ext.grid.ColumnModel) { - filters = filters.config; - cm = true; - } - for (i = 0, len = filters.length; i < len; i++) { - filter = false; - if (cm) { - dI = filters[i].dataIndex; - filter = filters[i].filter || filters[i].filterable; - if (filter){ - filter = (filter === true) ? {} : filter; - Ext.apply(filter, {dataIndex:dI}); - // filter type is specified in order of preference: - // filter type specified in config - // type specified in store's field's type config - filter.type = filter.type || this.store.fields.get(dI).type; - } - } else { - filter = filters[i]; - } - // if filter config found add filter for the column - if (filter) { - this.addFilter(filter); - } - } - } - }, - - /** - * Returns a filter for the given dataIndex, if one exists. - * @param {String} dataIndex The dataIndex of the desired filter object. - * @return {Ext.ux.grid.filter.Filter} - */ - getFilter : function (dataIndex) { - return this.filters.get(dataIndex); - }, - - /** - * Turns all filters off. This does not clear the configuration information - * (see {@link #removeAll}). - */ - clearFilters : function () { - this.filters.each(function (filter) { - filter.setActive(false); - }); - }, - - /** - * Returns an Array of the currently active filters. - * @return {Array} filters Array of the currently active filters. - */ - getFilterData : function () { - var filters = [], i, len; - - this.filters.each(function (f) { - if (f.active) { - var d = [].concat(f.serialize()); - for (i = 0, len = d.length; i < len; i++) { - filters.push({ - field: f.dataIndex, - data: d[i] - }); - } - } - }); - return filters; - }, - - /** - * Function to take the active filters data and build it into a query. - * The format of the query depends on the{@link #encode}
- * configuration: - *- * Override this method to customize the format of the filter query for remote requests. - * @param {Array} filters A collection of objects representing active filters and their configuration. - * Each element will take the form of {field: dataIndex, data: filterConf}. dataIndex is not assured - * to be unique as any one filter may be a composite of more basic filters for the same dataIndex. - * @return {Object} Query keys and values - */ - buildQuery : function (filters) { - var p = {}, i, f, root, dataPrefix, key, tmp, - len = filters.length; - - if (!this.encode){ - for (i = 0; i < len; i++) { - f = filters[i]; - root = [this.paramPrefix, '[', i, ']'].join(''); - p[root + '[field]'] = f.field; - - dataPrefix = root + '[data]'; - for (key in f.data) { - p[[dataPrefix, '[', key, ']'].join('')] = f.data[key]; - } - } - } else { - tmp = []; - for (i = 0; i < len; i++) { - f = filters[i]; - tmp.push(Ext.apply( - {}, - {field: f.field}, - f.data - )); - } - // only build if there is active filter - if (tmp.length > 0){ - p[this.paramPrefix] = Ext.util.JSON.encode(tmp); - } - } - return p; - }, - - /** - * Removes filter related query parameters from the provided object. - * @param {Object} p Query parameters that may contain filter related fields. - */ - cleanParams : function (p) { - // if encoding just delete the property - if (this.encode) { - delete p[this.paramPrefix]; - // otherwise scrub the object of filter data - } else { - var regex, key; - regex = new RegExp('^' + this.paramPrefix + '\[[0-9]+\]'); - for (key in p) { - if (regex.test(key)) { - delete p[key]; - } - } - } - }, - - /** - * Function for locating filter classes, overwrite this with your favorite - * loader to provide dynamic filter loading. - * @param {String} type The type of filter to load ('Filter' is automatically - * appended to the passed type; eg, 'string' becomes 'StringFilter'). - * @return {Class} The Ext.ux.grid.filter.Class - */ - getFilterClass : function (type) { - // map the supported Ext.data.Field type values into a supported filter - switch(type) { - case 'auto': - type = 'string'; - break; - case 'int': - case 'float': - type = 'numeric'; - break; - } - return Ext.ux.grid.filter[type.substr(0, 1).toUpperCase() + type.substr(1) + 'Filter']; - } -}); - -// register ptype -Ext.preg('gridfilters', Ext.ux.grid.GridFilters); -- * - *
- false : Default - *
- *- * Flatten into query string of the form (assuming{@link #paramPrefix}='filters'
: - *- *-filters[0][field]="someDataIndex"& -filters[0][data][comparison]="someValue1"& -filters[0][data][type]="someValue2"& -filters[0][data][value]="someValue3"& - *
- true : - *
- *- * JSON encode the filter data - *- *-filters[0][field]="someDataIndex"& -filters[0][data][comparison]="someValue1"& -filters[0][data][type]="someValue2"& -filters[0][data][value]="someValue3"& - *