I have an editable combo like this:
xtype : 'combo',
value : '',
queryMode : 'local',
displayField : 'label',
valueField : 'value',
store : someStore,
allowBlank : false,
disabled : true,
typeAhead : true,
listeners : {
beforequery : function(record) {
record.query = new RegExp(record.query, 'i');
record.forceAll = true;
}
}
This combo is part of a form, and the strange behaviour is this:
If I type some text, the combo filters the results perfect, and I can select any result after type filtering. And when I press a button to submit the form, in some point in a controller I use combo.findRecord to get extra data of the selected item in the combo, process that extra data and submit the form with no problem.
Same case than first, I type some text, the combo filters and I select an option, but if I select a part/all text(click and move mouse/double click mouse on text) and press the key combination ctrl+c (copy), and press the submit button, the combo.findRecord returns false, and the only difference between case 1 and 2 is that I copied (not cut) some part of the text of the selected item.
Any idea why this happens? I have googled it but havenĀ“t find any clue about this.
You can try by adding forceSelection config to the combo and share your results.
Regards,
Sandeep R
The problem was with new RegExp(record.query, 'i'), because when you do ctrl+c on an editable combo, it goes through the listener before query, and sometimes, the value of the combo contains characters that are used in regular expressions configurations like (,) or ..
So the solution is to scape the string to do the search:
var string= record.query;
string = string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');//This line scapes all special characters
record.query = new RegExp(string,'gi')
record.forceAll = true;
Related
My combo uses remote query. When the user types something, the server returns matching results. However, when there are a lot of matching results, then the combo expands, loses focus and highlights the firts record returned by the server. The combo has these properties:
...
queryMode:'remote',
enableKeyEvents:true,
forceSelection:true,
...
The screen of what is going on is here:
So, as you can see, when the user typed the last character, the server returned records and for some (I think stupid) reason highlighted the first record. But what is more important there is no focus any longer and the user has to put cursor on the field again to continue typing. To solve this problem, I tried these events:
'blur':function(){
this.focus();
},
'keydown':function(){
this.focus();
},
'keypress':function(){
this.focus();
},
'keyup':function(){
this.focus();
},
But there is no effect. I also tried to use load event, but it also has no effect.
I had this issue too, for solve it use the afterQuery property in the combo.
Something like this:
afterQuery: function() {
combo.setRawValue(combo.lastQuery);
},
pd: I think this is a Bug, but i'm not sure about it...
I could solve the similar issue with focus be two actions:
Set "selectOnFocus: false"
Update doRawQuery.
doRawQuery: function() {
var me = this;
...
me.inputEl.focus();
}
If you have your overridden version (I believe you should to not change original plugin), you can do it this way to not duplicate the logic:
doRawQuery: function() {
var me = this;
me.callParent(arguments);
me.inputEl.focus();
}
xtype: 'combo',
...
listeners:{
// repair raw value after blur
blur:function() {
var val = this.getRawValue();
this.setRawValue.defer(1, this, [val]);
}
}
Look this example(thanks to Saki)
I am using Extjs 4.2, so i have a grid with rowediting plugin. All works fine, I want to know how I can update one field value, depending on another field. I mean for example if in my grid I have field1, and field2, I need to update field3 value with field1 + field2 values when one of those were changed. Normally using jquery we can code a change event for each of the fields, but how i can do this on rowediting event?
Is this possible?
You can use edit events of rowedit as follow:
Sencha Fiddle : Grid RowEditor - Change cell value based on condition
grid.on('edit', function(editor, e){
/**
* here I am checking the column name to complete process
* you change what you want
*/
if (e.field == "name") {
e.record.set('result', parseInt(e.record.get('dummy')) + parseInt(e.record.get('age')));
}
})
You have to add editors to the columns, the editor is like any component, has listeners, type etc. then add a change listener
Example:
...
{
header: 'HeaderName',
dataIndex: 'man_peso',
type: 'number',
width: 50,
editor: {
enableKeyEvents: true,
listeners: {
change: function(c, e, eOpts) {
//here you can modify others components
}
},
xtype: 'textfield',
maskRe: /[0-9\.]/,
maxLength: 16
},
...
When you use RowEditor, the e.field value entirely depends on the field that was clicked on to edit the row.
To illustrate the problem:
In the previous answer, open the fiddle link (https://fiddle.sencha.com/#fiddle/4pj).
Double click the email field and change the name.
The handler will not update the result field as e.field will now be 'email' and not 'name'.
That is, Row Editor considers the field on which you click as the edited field. This does not make sense as it is a 'row' editor and is most probably used to edit multiple fields in the row.
To get the list of only modified fields, use e.record.getChanges(). These will give you only the modified fields and their new values.
In my application a text field is there where only regex: /[A-Z0-9_]/ should be allowed.
its working fine when we enter values from key board with the code i pasted below.
Problem is when i paste some value other than regex is being accepted using ctrl+v and rightclick paste.
NoteI disabled right click and ctrl+v events on key down which is not good solution for my problem please help me in solving this..
please tell me how to validate the value of text field after pasting some text .
Mycode: {
xtype: 'textfield',
flex: 1,
allowBlank: false,
maskRe: /[A-Z0-9_]/,
maxLength: 50,
regex: /[A-Z0-9_]/,
ref: '../refField',
enableKeyEvents:true,
listeners: {
keydown: function(field, e){
if((e.getKey() ==86) && e.ctrlKey){
e.stopEvent();
}
}
}
}
Regards,
raj
You could try call validate method on the keyup event, as suggested here:
http://www.sencha.com/forum/showthread.php?27147-Trying-to-get-extjs-to-react-to-text-changing-on-a-text-field
But as they say, it wont guarantee that this will work in all browsers. In my view 100% solution is to call validate() on field in the blur event.
something like:
combo.on('blur', funciton(field){
!if(field.isValid()){
//do what you need, for example clean the value in the field
}
})
In ext js, when I have a combo, there is display value and value( which is sent to server). I do not need displayValue to send to server, but I need to capture it on the page and display an alert.
What is the eextjs method of doing this?
combo.getValue() will return the underlying value...and I do not see any combo.getDisplay()
EDIT: Just to clarify, I am looking to get the display value of the item that is selected by the user. I wish to show an alert on the onselect or on changeevent.
If you set the valueField property on the combo box to the value you wish to display in the alert that will work fine.
alert(combo.getValue());
If you want this value to be different from the value you submit to the server you will have to get the store from the combo box and find the corresponding record.
var store = combo.getStore();
var index = store.find('*YourFieldName*', combo.getValue());
if(index != -1)//the record has been found
{
var record = store.getAt(index);
//you can then do what you like with the record.
}
combo.getStore().getById(combo.getValue()).raw.displayAttribute //Ext 4.x,
//displayAttribute: displayField or displayed attrib in store data for the combo
We can retreive the underlying store, then use our value as a key to get the display value.
Something like this (I haven't tested it):
var displayValue = combo.getStore()[combo.getValue()]
We can get the combo box display value something like this...
getRawValue( ) : String
Returns the raw String value of the combo, without performing any normalization, conversion, or validation. Gets the current value of the input element if the field has been rendered, ignoring the value if it is the emptyText.
combo.getRawValue();
Let's assume that you have following in your combobox:
id: 'COMBOBOX_ID',
displayField: 'COMBOBOX_DIS_FIELD_NAME',
valueField: 'COMBOBOX_VAL_FIELD_NAME'
Then, you can do following:
var combo = Ext.getCmp('COMBOBOX_ID');
var comboStore = combo.getStore();
var index = comboStore.find('COMBOBOX_VAL_FIELD_NAME', combo.getValue());
if(index != -1)
{
var selectedItemDisplayValue = combo.getStore().getAt(index).get('COMBOBOX_DIS_FIELD_NAME');
}
I'm using the following combobox:
var cb = new Ext.form.ComboBox({
store: someDs,
fieldLabel: 'test',
valueField:'name',
displayField:'name_id',
typeAhead: true,
minChars: 3,
triggerAction: 'query'
});
So when the user typed in 3 chars, a query to the server is made showing the proper results.
Now I try to make the user input programmatically usint the doQuery() function of the combobox. After calling the doQuery() method, I want to seledct an Item via setValue().
cb.doQuery('myval');
cb.setValue('myval');
The problem is that setValue() can't select the propper value, because at the time it is called, the request started through doQuery() hasn't finished.
So I need something like a callback in which I could use setValue() - but doQuery() doesn't seem to have a callback function.
any ideas? thanks!
I'm answering myself bacause code formatting ist not avaiable in the comment.
Igor: it works but it feels like a ugly hack then a clean solution.
For a better understanding I explain the situation:
I have a GridPanel. When the user clicks on a row on this panel, I want to preselect the selected value in the combobox. Because there's a lot of data I want to lower it with using the doQuery-function of the combobox.
In the GridPanel's rowClick-event i have the following code:
var myrec = Ext.getCmp('mygrid').store.getAt(rowIndex);
mycombo.store.on('load', myfn1 = function() {
// When the store has finisihed loading, select item in the combobox
mycombo.setValue(myrec.data.customer_id);
// Remove the function assigend to the load event...
// ...(when user types directly to the combobox instead clicking on a row...)
mycombo.store.un('load', myfn1);
});
// setValue has to be called again, because the load-event doesn't fires
// when doQuery is called with same params
mycombo.setValue(myrec.data.customer_id);
// Call do query to fill the combo only with the relevant values
mycombo.doQuery(myrec.data.customer_id);
The ComboBox has a beforequery event that gives you the option to intercept the query, do your own store load instead and cancel the ComboBox query. Also, in your example you are saving the handler function to a variable and then calling un from within the handler. That's totally unnecessary, as you can pass the options {single: true} as the fourth parameter to on (third parameter is scope).
If I understand your question, you want to set the value of a combo to a certain value, say customer id 123. The problem is that the record for customer 123 is not loaded so you don't have any data in the store regarding that customer. Am I right?
What you would want to do then is (this is not necessarily correct for your situation, just a direction to get you started):
combo.on('beforequery', function(q) {
q.cancel = true;
var id = q.query;
combo.setDisabled(true);
combo.store.on('load', function() {
combo.setValue(id);
}, combo.store, {single: true});
combo.store.reload({
customer_id: id
});
return q;
});