Last active
August 22, 2016 11:15
-
-
Save Eccenux/a112c72b9b88af359eea to your computer and use it in GitHub Desktop.
ExtJS Restore filters grid plugin
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* global Ext */ | |
/** | |
* Restore filters grid plugin. | |
* | |
* To use this plugin just add to your grid | |
* 1. `'Ext.ux.grid.RestoreFilters'` in `requires` property | |
* 2. `ptype: 'gridrestorefilters'` in `plugins` property | |
* 3. and `restoreableFilters` array as a setting for the plugin (see below) | |
* | |
* Note! If you change `extraParams` after the grid was render (e.g. set extraParams state from URL hash) | |
* then you MUST use `extraParamsChanged` event | |
* @example Firering event after changing params: | |
* store.getProxy().extraParams = newParams; | |
* store.load(); | |
* store.fireEvent('extraParamsChanged'); | |
* | |
* Filters that can be restored: | |
* <li>simple filter (text) | |
* <li>xtype: 'combobox' | |
* | |
* Filters that CANNOT be restored: | |
* <li>type: 'combo' -- will probably fail because it expects a restricted set of values | |
* (might still work if you support it server side) | |
* | |
* @author Maciej "Nux" Jaros | |
* @license CC-BY | |
* https://gist.github.com/Eccenux/a112c72b9b88af359eea/ | |
* | |
* Tested on ExtJS 6.0 | |
*/ | |
Ext.define('Ext.ux.grid.RestoreFilters', { | |
extend: 'Ext.AbstractPlugin', | |
alias: 'plugin.gridrestorefilters', | |
mixins: { | |
observable: 'Ext.util.Observable' | |
}, | |
/** | |
* Extended grid object. | |
*/ | |
grid : null, | |
/** | |
* array of dataIndexes of filters of which state can be restored | |
*/ | |
restoreableFilters : null, | |
/** | |
* Plugin init. | |
* @param {Ext.grid.Panel} grid | |
*/ | |
init: function(grid) { | |
var me = this; | |
//var config = this.getInitialConfig(); | |
this.grid = grid; | |
// this is fine on first load | |
grid.on('beforeshow', function(){ | |
console.log('RestoreFilters:grid.beforeshow'); | |
me.restoreFiltersFromParms(); | |
// this is for store.proxy.extraParams change (e.g. by hash change) | |
grid.store.on('extraParamsChanged', function() { | |
console.log('RestoreFilters:grid.store.extraParamsChanged'); | |
me.restoreFiltersFromParms(); | |
}); | |
}); | |
}, | |
/** | |
* Restore filter state from extra params set in store's proxy. | |
* | |
* @note assumes `extraParams` are in form 'filter.dataIndex' | |
* | |
* @example the key of a column with `dataIndex:'status'` must be 'filter.status'. | |
* | |
* @warning Works for IE11+ (because of `element.dispatchEvent` and `Object.keys`) | |
*/ | |
restoreFiltersFromParms: function() { | |
if (this.restoreableFilters === null) { | |
console.warn('restoreableFilters MUST be set in plugins object in the grid'); | |
return; | |
} | |
// initial check | |
var grid = this.grid; | |
var store = grid.store; | |
if (!('extraParams' in store.proxy) || Object.keys(store.proxy.extraParams).length < 1) { | |
return; | |
} | |
// debug | |
console.log('extraParams: ', store.proxy.extraParams); | |
// set filters state | |
var filtersColumns = grid.filterBar.columns; | |
var filterdFields = grid.filterBar.fields; | |
var params = store.proxy.extraParams; | |
for (var i = 0; i < this.restoreableFilters.length; i++) { | |
var dataIndex = this.restoreableFilters[i]; | |
var key = 'filter.' + dataIndex; | |
if (key in params) { | |
var value = params[key]; | |
var index = filtersColumns.findIndex('dataIndex', dataIndex); | |
if (index >= 0) { | |
var el = filtersColumns.items[index].el.dom; | |
var input = el.querySelector('input'); | |
// make sure to ignore values that are already set | |
if (input && input.value != value) { | |
filterdFields.items[index].setValue(value); | |
} | |
} | |
} | |
} | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Ext.define('App.view.MyGrid', { | |
extend: 'Ext.grid.Panel', | |
requires: [ | |
'Ext.ux.grid.RestoreFilters' | |
], | |
plugins: [ | |
{ | |
ptype: 'gridrestorefilters', | |
restoreableFilters : [ | |
'name' | |
] | |
} | |
], | |
columns: { | |
defaults: { | |
menuDisabled: false, | |
sortable: true, | |
filter: true | |
}, | |
items: [ | |
{ | |
text: 'name', | |
dataIndex: 'name' | |
} | |
//... you can have more columns of which filters cannot be restored | |
// (unless you add their `dataIndex` name to `restoreableFilters` array above) | |
] | |
} | |
//... | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
This example is based on: http://docs.sencha.com/extjs/4.2.2/extjs-build/examples/history/ | |
But I'm using hash-bang here. | |
Note that you probably would need to change at least `restoreState` function to better fit your needs. | |
Details depend on how your main Viewport looks, how many panels it has and so on. | |
*/ | |
Ext.define('App.controller.Viewport', { | |
extend: 'Ext.app.Controller', | |
/** | |
* Last token that was registered | |
* | |
* Used to ommit needless state restore. | |
*/ | |
lastRegisteredToken: null, | |
init: function() { | |
this.control({ | |
'viewport': { | |
afterrender: this.afterrenderViewport | |
} | |
}); | |
var me = this; | |
Ext.History.init(); | |
Ext.History.on('change', function(token) { | |
me.restoreStateFromToken(token); | |
}); | |
}, | |
afterrenderViewport: function(viewport) { | |
// restore state from hash (initial load) | |
if (location.hash.length) { | |
this.restoreStateFromToken(location.hash); | |
} | |
}, | |
/** | |
* Restore main panel state | |
* | |
* @private | |
* | |
* @param {type} panelId ID of the panel to restore. | |
* @param {type} panelParams Params for the panel's store. | |
*/ | |
restoreState: function(panelId, panelParams) { | |
if (panelParams && panelParams.length) { | |
var view = Ext.ComponentQuery.query("#" + panelId).pop(); | |
for (var i = 0; i<panelParams.length; i++) { | |
view.getStore().getProxy().extraParams[panelParams[i].name] = panelParams[i].value; | |
} | |
view.getStore().load(); | |
} | |
Ext.ComponentQuery.query('#viewportCards').pop().getLayout().setActiveItem(panelId); | |
}, | |
/** | |
* Save the viewport state. | |
* | |
* @private | |
* | |
* @param {type} panelId ID of the panel to restore. | |
* @param {type} panelParams Params for the panel's store. | |
*/ | |
registerState: function(panelId, panelParams) { | |
// generate token | |
var newToken = '?panel='+panelId; | |
if (panelParams) { | |
for (var i = 0; i<panelParams.length; i++) { | |
newToken += '&'+panelParams[i].name+'='+panelParams[i].value; | |
} | |
} | |
// add if different | |
var oldToken = Ext.History.getToken(); | |
if (oldToken === null || oldToken !== newToken) { | |
this.lastRegisteredToken = newToken; | |
Ext.History.add(newToken); | |
} | |
}, | |
/** | |
* Set the viewport state. | |
* | |
* @note It also saves the state. | |
* | |
* @param {type} panelId ID of the panel to restore. | |
* @param {type} panelParams Params for the panel's store. | |
*/ | |
setState: function(panelId, panelParams) { | |
this.registerState(panelId, panelParams); | |
this.restoreState(panelId, panelParams); | |
}, | |
/** | |
* Restore main panel state. | |
* | |
* @private | |
* | |
* @param {String} historyToken token taken from the history. | |
*/ | |
parseStateToken: function(historyToken){ | |
var panelParams = []; | |
var panelId = 'mygrid'; // default panel name | |
if (historyToken) { | |
historyToken.replace(/[?&]([^=]+)=([^&]*)/g, function(a, name, value){ | |
if (name === 'panel') { | |
panelId = value; | |
return; | |
} | |
panelParams.push({'name':name, 'value': value}); | |
}); | |
} | |
return { | |
panelParams: panelParams, | |
panelId: panelId | |
}; | |
}, | |
/** | |
* Restore the viewport state from token. | |
* | |
* @note If you have some menu of which state needs to you could add it's state restore call here. | |
* | |
* @param {String} token Token taken from the history or from hash (without the "#" character) | |
*/ | |
restoreStateFromToken: function(token) { | |
if (this.lastRegisteredToken && this.lastRegisteredToken === token) { | |
return; | |
} | |
var stateToken = this.parseStateToken(token); | |
this.restoreState(stateToken.panelId, stateToken.panelParams); | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment