I have a combobox in ExtJS4 with this initial config
xtype: 'combobox',
name: 'myCombo',
store: 'MyStore',
editable: false,
displayField: 'name',
valueField: 'id',
emptyText: 'Select an Option'
I don't know if there is an easy way to tell the combo to add an option so the user can deselect the combo (first he select an option and then he want to not select anything... so he wants to return to "Select an Option")
I solved this before by adding an extra option to the fetched data so I can simulate to have the "Select an Option" as a valid option in the combo but I think there should be a better way.
You do not need any new design or graphics or any complex extensions. ExtJS has is all out of the box.
You should be able to use this:
Ext.define('Ext.ux.form.field.ClearCombo', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.clearcombo',
trigger2Cls: 'x-form-clear-trigger',
initComponent: function () {
var me = this;
me.addEvents(
/**
* #event beforeclear
*
* #param {FilterCombo} FilterCombo The filtercombo that triggered the event
*/
'beforeclear',
/**
* #event beforeclear
*
* #param {FilterCombo} FilterCombo The filtercombo that triggered the event
*/
'clear'
);
me.callParent(arguments);
me.on('specialkey', this.onSpecialKeyDown, me);
me.on('select', function (me, rec) {
me.onShowClearTrigger(true);
}, me);
me.on('afterrender', function () { me.onShowClearTrigger(false); }, me);
},
/**
* #private onSpecialKeyDown
* eventhandler for special keys
*/
onSpecialKeyDown: function (obj, e, opt) {
if ( e.getKey() == e.ESC )
{
this.clear();
}
},
onShowClearTrigger: function (show) {
var me = this;
if (show) {
me.triggerEl.each(function (el, c, i) {
if (i === 1) {
el.setWidth(el.originWidth, false);
el.setVisible(true);
me.active = true;
}
});
} else {
me.triggerEl.each(function (el, c, i) {
if (i === 1) {
el.originWidth = el.getWidth();
el.setWidth(0, false);
el.setVisible(false);
me.active = false;
}
});
}
// ToDo -> Version specific methods
if (Ext.lastRegisteredVersion.shortVersion > 407) {
me.updateLayout();
} else {
me.updateEditState();
}
},
/**
* #override onTrigger2Click
* eventhandler
*/
onTrigger2Click: function (args) {
this.clear();
},
/**
* #private clear
* clears the current search
*/
clear: function () {
var me = this;
me.fireEvent('beforeclear', me);
me.clearValue();
me.onShowClearTrigger(false);
me.fireEvent('clear', me);
}
});
Here's a JSFiddle
And a JSFiddle without a default combo.
Note that both examples don't require any new graphic or style
To the best of my knowledge there is no better way of doing this. Although others may have a hack to do what you do by means of a plugin.
If I'm perfectly honest, no selection option in comboboxes is somewhat of a user interface paradox - users are required to select 'no selection'. A blank option is not very clear - looks a bit like a bug.
From a user interface perspective I think the preferred solution to this scenario is to have a button next to the combobox saying 'clear selection' (or just one with an X icon). Once you manage to put a button there, you can just call clearValue().
Related
http://2gears.com/2011/05/combobox-editor-remote-and-renderer-for-extjs-editorgridpanel/comment-page-2/#comment-11050?
Please see the function.
I am not using the 'combocolumn' completely. However i have used the major components. Please advise if there is a possibility it should work. As of now the grid refuses to render the column itself and I am unable to pinpoint what the bug is as the code is simply the same?
I did this not to act smart :) - but to simplify and run it on 1 column before standardizing the component common to the project.
The COMBO RENDERING fn()
<code>
function ComboBoxRenderer(combo, gridId) {
var getValue = function (value) {
var idx = combo.store.find(combo.valueField, value);
var rec = combo.store.getAt(idx);
if (rec) {
return rec.get(combo.displayField);
}
return value;
};
return function (value) {
if (combo.store.getCount() === 0 && gridId) {
console.log(combo.store.getCount()+gridId);
combo.store.on(
'load',
function () {
var grid = Ext.getCmp(gridId);
if (grid) {
grid.getView().refresh();
}
},
{
single: true
}
);
return value;
}
return getValue(value);
};
// Ext.getCmp(gridId).getView().refresh();
}
</code>
Editor - in Grid Column Model
{
header: 'Plan Type',
dataIndex: 'plan_id',
editor: {
// allowBlank: 'false',
xtype: 'combobox',
queryMode: 'local',
store: planTypeStore,
displayField: 'plan_name',
valueField: 'plan_id'
}
,renderer: ComboBoxRenderer(this.editor, 'gridPanelId')
/*this is the docs based renderrer - which wont work */
//, renderer: function (val) {
// var rec = planTypeStore.findRecord('plan_id', val);
// return (rec !== null ? rec.get("plan_name") : '');
// }
Please find the fiddles for PLUpload against Extjs 4 and 5
Fiddle with Extjs 4 [WORKING]
http://jsfiddle.net/jaspreets/dvsbsgse/
Fiddle with Extjs 5 [NOT WORKING]
http://jsfiddle.net/jaspreets/797sLzsn/
Please tell me why it is not working with ExtJs - 5 .
What can be the possible solution for this ?
Thanks in advance.
You need to migrate PLUpload plugin. For that you need to have several changes in the plugin.
Button.js:
/**
* #class Ext.ux.upload.Button
* #extends Ext.button.Button
*
* #author Harald Hanek (c) 2011-2012
* #license http://harrydeluxe.mit-license.org
*/
Ext.define('Ext.util.multiupload.Button', {
extend: 'Ext.button.Button',
alias: 'widget.uploadbutton',
requires: ['Ext.util.multiupload.Basic'],
disabled: true,
listeners: {
boxready: function() {
var me = this;
Ext.applyIf(me.config.uploader, {
browse_button: me.config.id || me.getId()
});
me.uploader = me.createUploader();
me.uploader.initialize();
me.plugins[0].initializeComponent(me);
me.relayEvents(me.uploader, ['beforestart',
'uploadready',
'uploadstarted',
'uploadcomplete',
'uploaderror',
'filesadded',
'beforeupload',
'fileuploaded',
'updateprogress',
'uploadprogress',
'storeempty'
]);
}
},
/**
* #private
*/
createUploader: function() {
return Ext.create('Ext.util.multiupload.Basic', this, Ext.applyIf({
listeners: {}
}, this.initialConfig));
}
});
Basic.js:
Remove AddEvents. Change Store to this.
me.store = Ext.create('Ext.data.JsonStore', {
fields: ['id', 'loaded', 'name', 'size', 'percent', 'status', 'msg'],
listeners: {
load: me.onStoreLoad,
remove: me.onStoreRemove,
update: me.onStoreUpdate,
scope: me
}
});
Second argument of onStoreRemove method is an array. So take first element.
Window.js:
Remove Id "form-statusbar". Rename init function to initializeComponent.
It should be working now.
I'm using selection Xtype and checkbox type property (CQ.form.Selection) to create a checkbox group in CQ5 (API docs at http://docs.adobe.com/docs/en/cq/5-6/widgets-api/index.html?class=CQ.form.Selection).
But I want to override setValue, getValue and validate functions of it in order to meet my requirement. How can I do that via JCR node declaration ?
many thanks and appreciate.
Not sure what you mean by "do that via JCR node declaration". But if you need to make a few additional steps with standard xtype you just need to create a custom xtype, which wraps the standard one, and use it.
Here is an example of JS-code that creates and registers new xtype (combines values of 2 different fields into a single value).
Ejst.CustomWidget = CQ.Ext.extend(CQ.form.CompositeField, {
/**
* #private
* #type CQ.Ext.form.TextField
*/
hiddenField: null,
/**
* #private
* #type CQ.Ext.form.ComboBox
*/
allowField: null,
/**
* #private
* #type CQ.Ext.form.TextField
*/
otherField: null,
constructor: function(config) {
config = config || { };
var defaults = {
"border": false,
"layout": "table",
"columns":2
};
config = CQ.Util.applyDefaults(config, defaults);
Ejst.CustomWidget.superclass.constructor.call(this, config);
},
// overriding CQ.Ext.Component#initComponent
initComponent: function() {
Ejst.CustomWidget.superclass.initComponent.call(this);
this.hiddenField = new CQ.Ext.form.Hidden({
name: this.name
});
this.add(this.hiddenField);
this.allowField = new CQ.form.Selection({
type:"select",
cls:"ejst-customwidget-1",
listeners: {
selectionchanged: {
scope:this,
fn: this.updateHidden
}
},
optionsProvider: this.optionsProvider
});
this.add(this.allowField);
this.otherField = new CQ.Ext.form.TextField({
cls:"ejst-customwidget-2",
listeners: {
change: {
scope:this,
fn:this.updateHidden
}
}
});
this.add(this.otherField);
},
// overriding CQ.form.CompositeField#processPath
processPath: function(path) {
console.log("CustomWidget#processPath", path);
this.allowField.processPath(path);
},
// overriding CQ.form.CompositeField#processRecord
processRecord: function(record, path) {
console.log("CustomWidget#processRecord", path, record);
this.allowField.processRecord(record, path);
},
// overriding CQ.form.CompositeField#setValue
setValue: function(value) {
var parts = value.split("/");
this.allowField.setValue(parts[0]);
this.otherField.setValue(parts[1]);
this.hiddenField.setValue(value);
},
// overriding CQ.form.CompositeField#getValue
getValue: function() {
return this.getRawValue();
},
// overriding CQ.form.CompositeField#getRawValue
getRawValue: function() {
if (!this.allowField) {
return null;
}
return this.allowField.getValue() + "/" +
this.otherField.getValue();
},
// private
updateHidden: function() {
this.hiddenField.setValue(this.getValue());
}
});
// register xtype
CQ.Ext.reg('ejstcustom', Ejst.CustomWidget);
Creating custom xtype in AEM6's touch UI
I am using extjs 4.0 and having a combobox with queryMode 'remote'. I fill it with data from server. The problem is that the number of records from server is too large, so I thought it would be better to load them by parts. I know there is a standart paginator tool for combobox, but it is not convinient because needs total number of records.
Is there any way to add dynamic scrolling for combobox? When scrolling to the bottom of the list I want to send request for the next part of records and add them to the list. I can not find appropriate listener to do this.
The following is my solution for infinite scrolling for combobox, Extjs 4.0
Ext.define('TestProject.testselect', {
extend:'Ext.form.field.ComboBox',
alias: ['widget.testselect'],
requires: ['Ext.selection.Model', 'Ext.data.Store'],
/**
* This will contain scroll position when user reaches the bottom of the list
* and the store begins to upload data
*/
beforeRefreshScrollTop: 0,
/**
* This will be changed to true, when there will be no more records to upload
* to combobox
*/
isStoreEndReached : false,
/**
* The main thing. When creating picker, we add scroll listener on list dom element.
* Also add listener on load mask - after load mask is hidden we set scroll into position
* that it was before new items were loaded to list. This prevents 'jumping' of the scroll.
*/
createPicker: function() {
var me = this,
picker = me.callParent(arguments);
me.mon(picker, {
'render' : function() {
Ext.get(picker.getTargetEl().id).on('scroll', me.onScroll, me);
me.mon(picker.loadMask, {
'hide' : function() {
Ext.get(picker.id + '-listEl').scroll("down", me.beforeRefreshScrollTop, false);
},
scope: me
});
},
scope: me
});
return picker;
},
/**
* Method which is called when user scrolls the list. Checks if the bottom of the
* list is reached. If so - sends 'nextPage' request to store and checks if
* any records were received. If not - then there is no more records to load, and
* from now on if user will reach the bottom of the list, no request will be sent.
*/
onScroll: function(){
var me = this,
parentElement = Ext.get(me.picker.getTargetEl().id),
parentElementTop = parentElement.getScroll().top,
scrollingList = Ext.get(me.picker.id+'-items');
if(scrollingList != undefined) {
if(!me.isStoreEndReached && parentElementTop >= scrollingList.getHeight() - parentElement.getHeight()) {
var multiselectStore = me.getStore(),
beforeRequestCount = multiselectStore.getCount();
me.beforeRefreshScrollTop = parentElementTop;
multiselectStore.nextPage({
params: this.getParams(this.lastQuery),
callback: function() {
me.isStoreEndReached = !(multiselectStore.getCount() - beforeRequestCount > 0);
}
});
}
}
},
/**
* Took this method from Ext.form.field.Picker to collapse only if
* loading finished. This solve problem when user scrolls while large data is loading.
* Whithout this the list will close before finishing update.
*/
collapse: function() {
var me = this;
if(!me.getStore().loading) {
me.callParent(arguments);
}
},
/**
* Reset scroll and current page of the store when loading all profiles again (clicking on trigger)
*/
doRawQuery: function() {
var me = this;
me.beforeRefreshScrollTop = 0;
me.getStore().currentPage = 0;
me.isStoreEndReached = false;
me.callParent(arguments);
}
});
When creating element, should be passed id to the listConfig, also I pass template for list, because I need it to be with id. I didn't find out more elegant way to do this. I appreciate any advice.
{
id: 'testcombo-multiselect',
xtype: 'testselect',
store: Ext.create('TestProject.testStore'),
queryMode: 'remote',
queryParam: 'keyword',
valueField: 'profileToken',
displayField: 'profileToken',
tpl: Ext.create('Ext.XTemplate',
'<ul id="ds-profiles-boundlist-items"><tpl for=".">',
'<li role="option" class="' + Ext.baseCSSPrefix + 'boundlist-item' + '">',
'{profileToken}',
'</li>',
'</tpl></ul>'
),
listConfig: {
id: 'testcombo-boundlist'
}
},
And the store:
Ext.define('TestProject.testStore',{
extend: 'Ext.data.Store',
storeId: 'teststore',
model: 'TestProject.testModel',
pageSize: 13, //the bulk of records to receive after each upload
currentPage: 0, //server side works with page numeration starting with zero
proxy: {
type: 'rest',
url: serverurl,
reader: 'json'
},
clearOnPageLoad: false //to prevent replacing list items with new uploaded items
});
Credit to me1111 for showing the way.
Ext.define('utils.fields.BoundList', {
override:'Ext.view.BoundList',
///#function utils.fields.BoundList.loadNextPageOnScroll
///Add scroll listener to load next page if true.
///#since 1.0
loadNextPageOnScroll:true,
///#function utils.fields.BoundList.afterRender
///Add scroll listener to load next page if required.
///#since 1.0
afterRender:function(){
this.callParent(arguments);
//add listener
this.loadNextPageOnScroll
&&this.getTargetEl().on('scroll', function(e, el){
var store=this.getStore();
var top=el.scrollTop;
var count=store.getCount()
if(top>=el.scrollHeight-el.clientHeight//scroll end
&&count<store.getTotalCount()//more data
){
//track state
var page=store.currentPage;
var clearOnPageLoad=store.clearOnPageLoad;
store.clearOnPageLoad=false;
//load next page
store.loadPage(count/store.pageSize+1, {
callback:function(){//restore state
store.currentPage=page;
store.clearOnPageLoad=clearOnPageLoad;
el.scrollTop=top;
}
});
}
}, this);
},
});
You can implement the infinite grid as list of the combobox.
Look at this example to implement another picker:
http://www.sencha.com/forum/showthread.php?132328-CLOSED-ComboBox-using-Grid-instead-of-BoundList
If anyone needs this in ExtJS version 6, here is the code:
Ext.define('Test.InfiniteCombo', {
extend: 'Ext.form.field.ComboBox',
alias: ['widget.infinitecombo'],
/**
* This will contain scroll position when user reaches the bottom of the list
* and the store begins to upload data
*/
beforeRefreshScrollTop: 0,
/**
* This will be changed to true, when there will be no more records to upload
* to combobox
*/
isStoreEndReached: false,
/**
* The main thing. When creating picker, we add scroll listener on list dom element.
* Also add listener on load mask - after load mask is hidden we set scroll into position
* that it was before new items were loaded to list. This prevents 'jumping' of the scroll.
*/
createPicker: function () {
var me = this,
picker = me.callParent(arguments);
me.mon(picker, {
'afterrender': function () {
picker.on('scroll', me.onScroll, me);
me.mon(picker.loadMask, {
'hide': function () {
picker.scrollTo(0, me.beforeRefreshScrollTop,false);
},
scope: me
});
},
scope: me
});
return picker;
},
/**
* Method which is called when user scrolls the list. Checks if the bottom of the
* list is reached. If so - sends 'nextPage' request to store and checks if
* any records were received. If not - then there is no more records to load, and
* from now on if user will reach the bottom of the list, no request will be sent.
*/
onScroll: function () {
var me = this,
parentElement = me.picker.getTargetEl(),
scrollingList = Ext.get(me.picker.id + '-listEl');
if (scrollingList != undefined) {
if (!me.isStoreEndReached && me.picker.getScrollY() + me.picker.getHeight() > parentElement.getHeight()) {
var store = me.getStore(),
beforeRequestCount = store.getCount();
me.beforeRefreshScrollTop = me.picker.getScrollY();
store.nextPage({
params: this.getParams(this.lastQuery),
callback: function () {
me.isStoreEndReached = !(store.getCount() - beforeRequestCount > 0);
}
});
}
}
},
/**
* Took this method from Ext.form.field.Picker to collapse only if
* loading finished. This solve problem when user scrolls while large data is loading.
* Whithout this the list will close before finishing update.
*/
collapse: function () {
var me = this;
if (!me.getStore().loading) {
me.callParent(arguments);
}
},
/**
* Reset scroll and current page of the store when loading all profiles again (clicking on trigger)
*/
doRawQuery: function () {
var me = this;
me.beforeRefreshScrollTop = 0;
me.getStore().currentPage = 1;
me.isStoreEndReached = false;
me.callParent(arguments);
}
});
First of all thanks to #me1111 for posting the code for dynamic rendering on scroll. That code is working for me after doing a small change.
tpl: Ext.create('Ext.XTemplate',
'<ul id="testcombo-boundlist-items"><tpl for=".">',
'<li role="option" class="' + Ext.baseCSSPrefix + 'boundlist-item' + '">',
'{profileToken}',
'</li>',
'</tpl></ul>'
),
listConfig: {
id: 'testcombo-boundlist'
}
in code from <ul id="ds-profiles-boundlist-items"><tpl for="."> i have changed id to "testcombo-boundlist-items". as we defined id as 'testcombo-boundlist' in listConfig.
Before modification, in onScroll method scrollingList = Ext.get(me.picker.id + '-items'); i am getting scrollList as a null. because me.picker.id will return 'testcombo-boundlist' on this we are appending '-items' so it became 'testcombo-boundlist-items' but this id does not exists. so iam getting null.
After modification of id in <ul id="testcombo-boundlist-items"> we have a list object on "testcombo-boundlist-items". so i got a object.
Hope this small change will help.
I have tried this different ways, but still can't get the filter to work. My ext app lets user to choose a single state from a combobox, and the grid below displays more data on that selected "value"=state.. On select, the combobox fires a function that filters the store of the grid and updates the store...
this is my store for the grid...
var store = Ext.create('Ext.data.Store', {
autoLoad: true,
id: 'OurData',
pageSize: 20,
pageNumber: 1,
remoteSort: true,
fields: [
{ name: 'States' },
{ name: 'FullName' },
{ name: 'Capital' },
{ name: 'Population' }
],
proxy: {
type: 'ajax',
url: 'GetState/getS',
reader: {
type: 'json',
root: 'myTable',
idProperty: 'States',
totalProperty: '#count'
}
}
});
store.loadPage(1);
this is my combobox
xtype: 'combo',
id: 'iccombo',
scope: this,
store: this.Combostore,
fieldLabel: 'Short State',
displayField: 'States',
valueField: 'States',
typeAhead: true,
triggerAction: 'all',
queryMode: 'remote',
name: 'State',
labelWidth: 125,
anchor: '95%',
listeners: {
scope: this,
select: this.fireFilter
}
and this is where the filter should take place...
fireFilter: function (value) {
// Get passed value
this.selectedC = value.getValue();
console.log('selectedValue: ' + this.selectedC);
// Clear existing filters
this.store.clearFilter(false);
// Build filter
var myfilter = Ext.create('Ext.util.Filter', {
scope: this,
filterFn: function (item) {
var fieldNames = item.fields.keys;
for (var j = 0; j < fieldNames.length; j++) {
var fieldName = fieldNames[j];
if (item.data[fieldName] != null) {
var stringVal = item.data[fieldName].toString();
if (stringVal != null && stringVal.toLowerCase().indexOf(value.toLowerCase()) != -1) {
return true;
}
}
}
return false;
}
});
// Apply filter to store
this.store.filter(myfilter);
}
when I run the code, it display all data in the grid, and on selection of combobox, it still shows the same data..
For some reason, the code never runs through the filterFn... because my console.log doesn't show up
this is what I got in firebug's response
_dc 1352902173425
filter [{"property":null,"value":null}]
limit 20
page 1
start 0
as you can clearly see, the selected 'value' is null, but my 'console.log' prints the value selected... I think the way I am getting the passed value and applying the filter is incorrect... can someone please take a look... thanks
UPDATE... I am able to get inside the function and my console.log shows all the fields... but once I get to the last if statement... I get this error
TypeError: value.toLowerCase is not a function
What am I doing wrong here? Thanks
In addition to dbrin's anwser I also can't understand why you are using remoteSort but not remoteFilter? You may also have a scope issue by using this.
Anyway I would recommend you to extend a new combo type so that you are also be able to clear your filter if you have the need to. Here is an extension I have written for my own use. Note that the filtering itself needs to be implemented in the onSearch method, which can be either a remote or a local sort.
Ext.define('Ext.ux.form.field.FilterCombo', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.filtercombo',
/**
* #cfg {string} recordField
* #required
* The fieldname of the record that contains the filtervalue
*/
/**
* #cfg {string} searchField
* #required
* The fieldname on which the filter should be applied
*/
/**
* #cfg {boolean} clearable
* Indicates if the clear trigger should be hidden. Defaults to <tt>true</tt>.
*/
clearable: true,
initComponent: function () {
var me = this;
if (me.clearable)
me.trigger2Cls = 'x-form-clear-trigger';
else
delete me.onTrigger2Click;
me.addEvents(
/**
* #event clear
*
* #param {Ext.ux.form.field.FilterCombo} FilterCombo The filtercombo that triggered the event
*/
'clear',
/**
* #event beforefilter
*
* #param {Ext.ux.form.field.FilterCombo} FilterCombo The filtercombo that triggered the event
* #param {String/Number/Boolean/Float/Date} value The value to filter by
* #param {string} field The field to filter on
*/
'beforefilter'
);
me.callParent(arguments);
// fetch the id the save way
var ident = me.getId();
me.on('select', function (me, rec) {
var value = rec[0].data[me.recordField],
field = me.searchField;
me.fireEvent('beforefilter', me, value, field)
me.onShowClearTrigger(true);
me.onSearch(value, field);
}, me);
me.on('afterrender', function () { me.onShowClearTrigger(); }, me);
},
/**
* #abstract onSearch
* running a search on the store that may be removed separately
* #param {String/Number/Boolean/Float/Date} val The value to search for
* #param {String} field The name of the Field to search on
*/
onSearch: Ext.emptyFn,
/**
* #abstract onFilterRemove
* removing filters from the the
* #param {Boolean} silent Identifies if the filter should be removed without reloading the store
*/
onClear: Ext.emptyFn,
onShowClearTrigger: function (show) {
var me = this;
if (!me.clearable)
return;
show = (Ext.isBoolean(show)) ? show : false;
if (show) {
me.triggerEl.each(function (el, c, i) {
if (i === 1) {
el.setWidth(el.originWidth, false);
el.setVisible(true);
me.active = true;
}
});
} else {
me.triggerEl.each(function (el, c, i) {
if (i === 1) {
el.originWidth = el.getWidth();
el.setWidth(0, false);
el.setVisible(false);
me.active = false;
}
});
}
// Version specific methods
if (Ext.lastRegisteredVersion.shortVersion > 407) {
me.updateLayout();
} else {
me.updateEditState();
}
},
/**
* #override onTrigger2Click
* eventhandler
*/
onTrigger2Click: function (args) {
this.clear();
},
/**
* #private clear
* clears the current search
*/
clear: function () {
var me = this;
if (!me.clearable)
return;
me.onClear(false);
me.clearValue();
me.onShowClearTrigger(false);
me.fireEvent('clear', me);
}
});
Here is an untested implementation of your combo. Please note that I cleaned up your filterFn but I didn't make any further check.
{
xtype: 'filtercombo',
id: 'iccombo',
scope: this,
store: this.Combostore,
fieldLabel: 'Short State',
displayField: 'States',
valueField: 'States',
typeAhead: true,
triggerAction: 'all',
queryMode: 'remote',
name: 'State',
labelWidth: 125,
anchor: '95%',
// begin new parts
recordField: 'States',
searchField: '',
clearable: false,
onSearch: function (me, value, field) {
// New part!
var store = Ext.StoreMgr.lookup('YourStoreIdName');
// Clear existing filters
store.clearFilter(false);
// Build filter
var myfilter = Ext.create('Ext.util.Filter', {
scope: this,
filterFn: function (item) {
var fieldNames = item.fields.keys,
fieldName, stringVal,
len = fieldNames.length,
j = 0;
for (; j < len; j++) {
fieldName = fieldNames[j];
if (item.data[fieldName] != null) {
stringVal = item.data[fieldName].toString();
if (stringVal != null && stringVal.toLowerCase().indexOf(value.toLowerCase()) != -1) {
return true;
}
}
}
return false;
}
});
// Apply filter to store
store.filter(myfilter);
}
}
I guess this should work too
var myfilter = Ext.create('Ext.util.Filter', {
scope: this,
filterFn: function (rec) {
var fieldValue = rec[this.fieldName];
if (fieldValue && fieldValue === this.value)
return true;
return false;
}
});
I set this before two vars to mark them as from a external scope.
i see 2 issues
store should have remoteFilter: true set
in JavaScript all variables declarations are picked out and hoisted to the beginning of the function. so any variables declared inside a loop should be taken out and declared at the top of the function. JS has no block scope (like Java).