I'm not sure what's wrong with my code. However after I type 4 characters on combobox, all of value will be displayed, not filtered based on characters that I have typed. Because of that my live search is broken. Please see attached image for better illustration.
I'm creating combobox inside panel as one of item
{
xtype: 'combobox',
fieldLabel: 'Guest Name',
padding: '10px 10px 20px 10px',
allowBlank: false,
id: 'guest_id_payment',
name: 'guest_id',
// Template for the dropdown menu.
// Note the use of "x-boundlist-item" class,
// this is required to make the items selectable.
tpl: Ext.create('Ext.XTemplate',
'<tpl for=".">',
'<div class="x-boundlist-item">{identity_number} - {name}</div>',
'</tpl>'
),
// template for the content inside text field
displayTpl: Ext.create('Ext.XTemplate',
'<tpl for=".">',
'{identity_number} - {name}',
'</tpl>'
),
valueField: 'identity_number',
store: 'SGuest',
height: 20,
queryMode: 'remote'
}
This is the store:
Ext.define('ghb.store.SGuest', {
extend: 'Ext.data.Store',
model: 'ghb.model.MGuest',
autoLoad: true,
autoSync: true,
proxy: {
pageParam: false,
startParam: false,
limitParam: false,
type: 'ajax',
api: {
create: '/ghb_manager/add_guest',
read: '/ghb_manager/data_guest',
update: '/ghb_manager/edit_guest',
destroy: '/ghb_manager/delete_guest'
},
reader: {
type: 'json',
root: 'data'
},
writer: {
type: 'json',
encode: true,
writeAllFields: true,
root: 'data'
},
root: 'data'
}
});
I'm also add change event listener
'#guest_id_payment':{
change: this.changeGuestCombo
},
This is the function of change event listener, loading another store (not the store of ComboBox)
changeGuestCombo: function(self, newValue, oldValue, eOpts){
var store = Ext.getStore('SReservation');
store.load({
params: {
data: self.getValue(),
}
});
},
N.B. I'm using 4.2.1
The way you currently have it setup the filtering should be handled server side. If you change queryMode: 'remote' to queryMode: 'local' then the filter should work the way you want.
queryMode: 'remote' tells the combo box to call the proxy with the value you typed and the server would have to return only matching values. This is helpful if you have a huge dataset to search
I found the problem. When we use tpl & displayTpl on Combobox, the livesearch feature won't work
When you are using custom tpl and displayTpl in your Combobox, you can define a custom Filter function, for example on key up:
// Clear the filter collection without updating the UI
store.clearFilter(true);
store.filter([
{filterFn: function(item) { return item.get("identity_number") == "[....]" }}
]);
For more information check the ExtJS documentation.
Related
I have the below extjs combobox created for user to change an item through an API call. I have a specific tpl to display the values in a format which works fine when the select list gets populated. I have displayField showing when user selects an item from the list, which is great too. The problem is, when user selects and item and submits, I need to pull 2 values off of that selection. One value is gmiExchangeCode and the other value is gmiFuturesCode. I need to be able to get both of these values when user submits. The code below only sends the gmiDescription
}, {
xtype: 'combo',
autoLoad: true,
hideTrigger: true,
fieldLabel: 'Product',
displayField: 'gmiDescription',
hiddenName: 'gmiExchangeCode',
valuefield: 'gmiExchangeCode',
forceSelection: true,
submitValue: true,
name: 'exchange',
queryMode: 'remote',
queryParam: 'entry',
typeAhead: true,
minChar: 2,
tpl: new Ext.XTemplate('*****'),
store: {
fields: ['text', 'value'],
proxy: {
type: 'ajax',
url: '*****',
reader: {
type: 'json'
}
},
sorters: [{
property: 'exchange',
direction: 'ASC'
}]
},
listeners: {
select: function (combo, record, index) {
exchangeCode.setValue(record.get('exchangeCode'));
}
}
}, {
By default, form submission sends all form elements values only (no extra field).
In order to send the second value you could create a hidden form field and set it ( see Sencha ExtJS Submit two values), and that way this hidden field would also be submitted
Another way around it is to pass some extra params to the submit action (if it is triggered manually), from https://docs.sencha.com/extjs/6.5.1/classic/Ext.form.action.Submit.html#cfg-params
Extra parameter values to pass. These are added to the Form's
Ext.form.Basic#baseParams and passed to the specified URL along with
the Form's input fields.
form.getForm().submit({
url: 'panel.php',
params: {
data: Ext.encode(json)
},
})
I'm having trouble in filtering the comboxbox on typeahead, when I type the required value which I want, the combo highlights the value correctly but it does not filters the store. The store reloads to the original data even after typing some text in the combobox.
Here is my code for store.
Ext.define('Dashboard.store.Rule', {
extend: 'Ext.data.Store',
model: 'Dashboard.model.Rule',
storeId : 'Rule',
pageSize: 35,
autoSync : false,
autoLoad: true,
remoteFilter: true,
sorters : ['ruleName'],
proxy: {
type: 'ajax',
api: {
read : 'rule/view.action',
create : 'rule/create.action',
update: 'rule/update.action',
destroy: ''
},
reader: { //reads the data in the JSON Format
type: 'json',
root: 'data',
successProperty: 'success'
},
writer: {
type: 'json', //writes the data in the JSON Format
writeAllFields: true,
encode: true,
root: 'data'
},
listeners: { //Exception Handler for the Ajax Request
exception: function(proxy, response, operation){
var error = Ext.decode(response.responseText);
Ext.MessageBox.show({
title: 'REMOTE EXCEPTION',
msg: error.message,
icon: Ext.MessageBox.ERROR,
buttons: Ext.Msg.OK
});
}
}
}
});
And below is my code for combobox in view
xtype: 'combobox',
id : 'ruleName',
padding : '10 30 10 20',
fieldLabel: '<html><font color = "red">*</font></html>Rule Name',
store: 'Rule',
width: screen.width*0.22,
emptyText: 'Select Rule',
typeAhead : true,
allowBlank: false,
queryMode: 'remote',
lastQuery:'',
displayField: 'ruleName',
disabled : true,
maxLength: 100,
maxLengthText: 'Maximum text size allowed 100',
listeners : {
'change' : function(){
//TODO
},
'blur' : function(){
//TODO
}
}
I also tried putting triggerAction : 'all' but still nothing works.
Please help on this issue
Many Thanks
Your store is configured with
remoteFilter: true,
which tells the store to reload whenever the filter is changed, sending the filter configuration to the server, so a server-side filter can be applied.
The records that are sent back by the server are not filtered by the client, since the server should have done that.
Did you implement a filter server-side? If so, what's your filter code there?
If you didn't mean to filter server-side, set remoteFilter to false.
I have a comboBox in which items are coming from database and a have applied filter option using that comboBox...Combo works good at first time ,but the problem is when i want to select items from the comboBox at second time i don't find items in my combo(only the previous selected item)..
this.control({
'combobox[itemId=YourCombo]':
{
select: this.combogridfilter
}
});
combogridfilter: function(newValue){
var value1= Ext.getCmp('myCombo').getValue();
var grid=Ext.getCmp('afteraddingtemplate');
grid.store.load().filter([
{id:'item_code', property:"item_code", value: value1, anyMatch: false}
]);
},
here is the combo configuration
xtype:'combo',
id:'myCombo',
itemId:'YourCombo',
action:'change',
fieldLabel:'Select a template',
queryMode:'local',
store:this.store,
name:'item_code',
displayField:'item_code',
valueField:'item_code',
enableKeyEvents: true,
typeAhead: true,
mode: 'local',
forceSelection: true,
triggerAction: 'all',
emptyText: 'Select a Template',
selectOnFocus: true
You should clear filter before applicate a new one:
combogridfilter: function(newValue){
var value1= Ext.getCmp('myCombo').getValue();
var grid=Ext.getCmp('afteraddingtemplate');
grid.store.clearFilter(true);
grid.store.filter('item_code', value1);
},
You should not share the store between the grid and the combo. Sharing stores between components is asking for trouble. What is happening, is that when you filter the grid, you filter the combo too. Given it's the same store...
What you can do is use a simple memory store for your combo, that you populate when the grid store is loaded.
For example, configure your combo this way:
{
renderTo: Ext.getBody(),
xtype:'combo',
id:'myCombo',
itemId:'YourCombo',
action:'change',
fieldLabel:'Select a template',
queryMode:'local',
store: {
fields: ['item_code']
,proxy: {type: 'memory', reader: 'array'}
},
name:'item_code',
displayField:'item_code',
valueField:'item_code',
enableKeyEvents: true,
typeAhead: true,
mode: 'local',
forceSelection: true,
triggerAction: 'all',
emptyText: 'Select a Template',
selectOnFocus: true
}
And populate it on the load event of the grid store:
grid.getStore().on('load', function(store) {
Ext.getCmp('myCombo').getStore().loadData(store.getRange());
});
Hello i'm trying to do search in combobox.It's working but search only in current page i'm using pagination with search too i need to search in all pages not current page only
Any suggestion
{
xtype: 'combo',
fieldLabel: 'Organization Id',
name: 'company_id',
displayField:'name_en',
valueField:'id',
store: Ext.create('UserApp.store.PicklistList', {
autoLoad: true,
fields: ['id', 'name_en', 'name_se'],
proxy:{
type:'ajax',
api: {
read:'picklist/listitems'
},
reader: {
type: 'json',
root: 'root',
successProperty: 'success'
},
extraParams:{
table :'table_name'
}
}
}),
editable: true,
autoSelect: false,
selectOnFocus:true,
typeAhead:true,
minChars:2,
queryMode: 'local',
mode: 'local',
pageSize: 25,
width:370,
allowOnlyWhitespace: false,
regex: /[a-zA-Z0-9]+/, // avoid to empty data only
})
I'm using combobox with queryMode : 'remote' and doing a search withing combobox for matches. I'm doing a 'contains' search - meaning it looks for matches anywhere in the result string not just beginning and also it searches for values not only in current page but in the entire resultset. I'm using extjs 4.0.7 and i achived it by overriding doQuery method.
`doQuery: function(queryString, forceAll) {
this.expand();
this.store.clearFilter(!forceAll);
if(this.queryMode == 'remote') {
this.store.load({
params: this.getParams(queryString)
});
}
if (!forceAll) {
this.store.filter(this.displayField, new RegExp(Ext.String.escapeRegex(queryString), 'i'));
}
}`
your store needs to be setup for pagination
your server needs to handle pagination correctly based on the parameters received from the store's proxy. The proxy will send up querystring parameters like ?page=1&start=0&limit=25, and your server needs to return only 25 (for example) records and a total parameter.
{"total":101,"data":[{model data}, {model data}, ...]}
despite the documentation, the pageSize property in combobox is actually a boolean, turning pagination on if 1 or greater.
I implemented as said at How to add an empty item to ExtJS combobox? I can see a blank row/item as desired but I am unable to select any of the item from combobox !
Any guess ?
My code is as follow
var rModel = Ext.regModel('State', {
fields: [
{type: 'string', name: 'fips_state_code'},
{type: 'string', name: 'state_name'}
]
});
// The data store holding the states
var store = Ext.create('Ext.data.Store', {
model: 'State',
data: [{fips_state_code: '0', state_name: ' '}]
});
store.add(obj.results);
{
xtype:'combo',
id:'filterstate',
width: 250,
fieldLabel: 'Filter By State',
store: store,
queryMode: 'local',
displayField: 'state_name',
valueField: 'fips_state_code',
editable: false,
forceSelection : true,
triggerAction : 'all',
typeAhead: true,
selectOnFocus:true,
allowBlank:true,
tpl : '<tpl for=\".\"><div class=\"x-combo-list-item\">{state_name} <\/div><\/tpl>'
}
The problem is the tpl attribute, in order to select an attribute you need to add the x-boundlist-item class to your tpl. Just like this
tpl : '<tpl for=".">'+
'<div class="x-boundlist-item">'+
'<div class="list-item">{state_name} </div>'+
'</div>'+
'</tpl>'
http://jsfiddle.net/alexrom7/CnwpD/
But if you only want to apply a custom css class to every item in the combobox list. I would recommend you to do it this way
listConfig: {
// Custom rendering template for each item
getInnerTpl: function() {
return '<div class="list-item">{state_name} <\/div>';
}
}
http://jsfiddle.net/alexrom7/6Jt5T/
Working directly with the tpl could give you some trouble.