PDA

View Full Version : Ext.ux.GridSearch



slammer
23 Jul 2011, 3:47 AM
simply based on this plugin http://gridsearch.extjs.eu/

JS

Ext.define('Ext.ux.GridSearch', {
extend: 'Ext.util.Observable',
alias: 'widget.gridsearch',
requires: ['Ext.form.field.VTypes'],

searchText: 'Search',
selectAllText: 'Select all',
clearIconCls: 'x-form-clear-icon',
iconCls: 'icon-search',
width: 100,
minChars: 2,
mode: 'local',

init: function(grid) {
this.grid = grid;
grid.on('render', this.onRender, this, {single: true});
grid.on('render', this.reconfigure, this, {single: true});
},

onRender: function(grid) {
var ptb = Ext.ComponentQuery.query('pagingtoolbar', grid)[0];
var tb = Ext.ComponentQuery.query('toolbar', grid)[0];

if(ptb) {
this.tb = ptb;
} else if(tb) {
this.tb = tb;
} else {
grid.addDocked({ xtype: 'toolbar', dock: 'bottom' });
this.tb = Ext.ComponentQuery.query('toolbar', grid)[0];
}

if(0 < this.tb.items.getCount()) {
this.tb.add('-');
}

//menu
this.menu = new Ext.menu.Menu();
this.tb.add({
text: this.searchText,
menu: this.menu,
iconCls: this.iconCls
})

//field
this.field = new Ext.form.TriggerField({
width: this.width,
selectOnFocus: true,
triggerCls : this.clearIconCls,
onTriggerClick: this.onTriggerClear(this),
minLength: this.minChars
});
this.field.on('render', function() {
this.field.el.on('keyup', this.onKeyUp, this);
}, this, {single:true});

this.tb.add(this.field);
},

onKeyUp:function(e, t, o) {
if(!this.field.isValid()) {
return;
}

var val = this.field.getValue();
var store = this.grid.store;
if('local' === this.mode) {
store.clearFilter();
if(val) {
store.filterBy(function(r) {
var retval = false;
this.menu.items.each(function(item) {
if(!item.checked || retval) {
return;
}
var rv = r.get(item.dataIndex);
rv = rv instanceof Date ? rv.format(this.dateFormat || r.fields.get(item.dataIndex).dateFormat) : rv;
var re = new RegExp(Ext.util.Format.escapeRegex(val), 'gi');
retval = re.test(rv);
}, this);
if(retval) {
return true;
}
return retval;
}, this);
}
} else {
var fields = [];
this.menu.items.each(function(item) {
if(item.checked) {
if(item.dataIndex)
fields.push(item.dataIndex);
}
});
store.load({
params: {
fields : Ext.encode(fields),
search : val
}
});
}
},

onTriggerClear: function(el) {
return function() {
if(el.field.getValue()) {
el.field.setValue('');
el.field.focus();
el.onKeyUp();
}
}
},

reconfigure: function(grid) {

this.menu.add(new Ext.menu.CheckItem({
text: this.selectAllText,
checked: !(this.checkIndexes instanceof Array),
hideOnClick: false,
handler: function(item) {
var checked =! item.checked;
item.parentMenu.items.each(function(i) {
if(item !== i && i.setChecked && !i.disabled) {
i.setChecked(!checked);
}
});
}
}),'-');

var cm = this.grid.columns;

Ext.each(cm, function(config) {
text = config.header || config.text;
searchable = config.searchable == undefined || config.searchable ? true : false;
if(text && config.dataIndex && searchable) {
this.menu.add(new Ext.menu.CheckItem({
text: text,
hideOnClick: false,
dataIndex: config.dataIndex,
checked: true
}));
}
}, this)

}
});
CSS:

.x-form-clear-icon {
background-image:url(/images/desktop/clear.png) !important;
}
.x-form-colorfield-icon {
background-image:url(/images/desktop/color.png) !important;
}HOW TO:


Ext.create('Ext.grid.Panel', {
...
plugins: [new Ext.ux.GridSearch({
mode: 'local',
width: 150
...
})],
columns: [{
text: 'Name',
dataIndex: 'user_fname'
},{
text: 'Surname',
searchable: false,
dataIndex: 'user_sname'
}],
});
I don't know how can I search cells which have renderer function.


I am a beginner so I am waiting for your suggestions... Feel free to modify ;)

salvocanna
29 Jul 2011, 8:19 AM
Thanks... I would need it, but... It's not possible search in cells which have renderer function?!

I'm a beginner too... It's possible to solve the problem? :)

darkhorni
4 Aug 2011, 7:12 AM
Is it for ExtJs4? Because it didn't worked at a grouped grid.

djdiez
27 Sep 2011, 12:12 AM
Nice code! Works really good (and extremely good sakalos base too)
Thank you very much both of you!

A little improvement. Replacing


store.load({
params: {
fields : Ext.encode(fields),
search : val
}
});
with


store.proxy.extraParams = {
fields : Ext.encode(fields),
search : val
};
store.load();

will make the extra params to be in the proxy and this way allow pagination to remote query using the gridsearch fields and data. :)

djdiez
28 Sep 2011, 1:26 AM
Another little improvement for remote queries.


this.field.on('render', function() {
this.field.el.on('keyup', this.onKeyUp, this);
}, this, {single:true});
by


this.field.on('render', function() {
this.field.el.on({scope:this, buffer:700, keyup:this.onKeyUp});
}, this, {single:true});

Allows us to avoid some DB queries, waiting for the user to finish typing and then do the request.
We can replace the 700 by the number of milliseconds to wait before asking for the remote data.

Jan (HL)
5 Dec 2011, 6:30 AM
Based on the last comments the updated version:

* Changes: Alias prefix is now plugin!
* Changes: Buffered user input (buffered textfield events)
* Changes: Persistent the params.
* Changes: Change the param key "search" back to "query" being compatible with the old "Ext.ux.grid.Search" (and actually, that is the correct query parameter name technically)
* Changes: Replaces date.format(...) with Ext.Date.format(date, ...)

I'd would suggest following changes
* configurable param name fields and query
* configurable position (top, bottom)



Ext.define('Ext.ux.GridSearch', {


extend : 'Ext.util.Observable',
alias : 'plugin.gridsearch',
requires : [ 'Ext.form.field.VTypes' ],


searchText : 'Search',
selectAllText : 'Select all',
clearIconCls : 'x-form-clear-icon',
iconCls : 'icon-search',
width : 100,
minChars : 2,
mode : 'local',


init : function(grid) {
this.grid = grid;
grid.on('render', this.onRender, this, {
single : true
});
grid.on('render', this.reconfigure, this, {
single : true
});
},


onRender : function(grid) {
var ptb = Ext.ComponentQuery.query('pagingtoolbar', grid)[0];
var tb = Ext.ComponentQuery.query('toolbar', grid)[0];


if (ptb) {
this.tb = ptb;
} else if (tb) {
this.tb = tb;
} else {
grid.addDocked({
xtype : 'toolbar',
dock : 'bottom'
});
this.tb = Ext.ComponentQuery.query('toolbar', grid)[0];
}


if (0 < this.tb.items.getCount()) {
this.tb.add('-');
}


// menu
this.menu = new Ext.menu.Menu();
this.tb.add({
text : this.searchText,
menu : this.menu,
iconCls : this.iconCls
});


// field
this.field = new Ext.form.TriggerField({
width : this.width,
selectOnFocus : true,
triggerCls : this.clearIconCls,
onTriggerClick : this.onTriggerClear(this),
minLength : this.minChars
});
this.field.on('render', function() {
this.field.el.on({
scope : this,
buffer : 700,
keyup : this.onKeyUp
});
}, this, {
single : true
});


this.tb.add(this.field);
},


onKeyUp : function(e, t, o) {
if (!this.field.isValid()) {
return;
}


var val = this.field.getValue();
var store = this.grid.store;
if ('local' === this.mode) {
store.clearFilter();
if (val) {
store.filterBy(function(r) {
var retval = false;
this.menu.items.each(function(item) {
if (!item.checked || retval) {
return;
}
var rv = r.get(item.dataIndex);
rv = rv instanceof Date ? Ext.Date.format(rv, this.dateFormat || r.fields.get(item.dataIndex).dateFormat) : rv;
var re = new RegExp(Ext.util.Format.escapeRegex(val), 'gi');
retval = re.test(rv);
}, this);
if (retval) {
return true;
}
return retval;
}, this);
}
} else {
var fields = [];
this.menu.items.each(function(item) {
if (item.checked) {
if (item.dataIndex)
fields.push(item.dataIndex);
}
});
store.proxy.extraParams = Ext.applyIf({
fields : Ext.encode(fields),
query : val
}, store.proxy.extraParams);
store.load();
}
},


onTriggerClear : function(el) {
return function() {
if (el.field.getValue()) {
el.field.setValue('');
el.field.focus();
el.onKeyUp();
}
};
},


reconfigure : function(grid) {


this.menu.add(new Ext.menu.CheckItem({
text : this.selectAllText,
checked : !(this.checkIndexes instanceof Array),
hideOnClick : false,
handler : function(item) {
var checked = !item.checked;
item.parentMenu.items.each(function(i) {
if (item !== i && i.setChecked && !i.disabled) {
i.setChecked(!checked);
}
});
}
}), '-');


var cm = this.grid.columns;


Ext.each(cm, function(config) {
text = config.header || config.text;
searchable = config.searchable == undefined || config.searchable ? true : false;
if (text && config.dataIndex && searchable) {
this.menu.add(new Ext.menu.CheckItem({
text : text,
hideOnClick : false,
dataIndex : config.dataIndex,
checked : true
}));
}
}, this);


}
});