The combobox in modern fires the "select" event every time the input changes. This is very different from classic. With it doing this there is no way to differentiate between a user making a selection and pragmatically setting the value of the field.
This was reported as a bug in the Sencha forums:
https://www.sencha.com/forum/showthread.php?468730-Modern-6-5-2-ComboBox-fires-select-event-on-every-value-change
The link above also contains a fiddler to demonstrate the issue.
Has anyone run into this as an issue, and how did you overcome it?
forceSelection: true will help to solve this problem but will not cancel the bug in cases when forced selection is not needed
Edit:
This behavior is due to method syncValue (search in this source - method is private and hasn't documentation)
I don’t understand why the component developer chose to create a record even if it isn’t exist.
Comment from source file:
Either user has typed something (isInput), or we've had a setValue to a value which has no match in the store, and we are not forceSelection: true. We create a new record.
I propose to fix this behavior using the following override:
fiddle
Ext.define('Ext.field.SelectOverride', {
override: 'Ext.field.Select',
autoCreateRecord: false,
syncValue: function() {
var me = this,
store = me.getStore(),
forceSelection = me.getForceSelection(),
valueNotFoundText = me.getValueNotFoundText(),
is, isCleared, isInput, value, matchedRecord;
if (me.reconcilingValue || !store || !store.isLoaded() || store.hasPendingLoad()) {
return;
}
me.reconcilingValue = true;
me.getSelection(); // make sure selection config is flushed
is = {};
is[me.syncMode] = true;
value = ((isInput = is.input || is.filter)) ? me.getInputValue() : me.getValue();
isCleared = value == null || value === '';
if (!isCleared) {
if (me.getMultiSelect()) {
return me.syncMultiValues(Ext.Array.from(value));
}
matchedRecord = (isInput ? store.byText : store.byValue).get(value);
if (matchedRecord) {
if (!matchedRecord.isEntity) {
matchedRecord = matchedRecord[0];
}
}
else if (!forceSelection) {
matchedRecord = me.findRecordByValue(value);
}
}
// Either user has typed something (isInput), or we've had a setValue
// to a value which has no match in the store, and we are not forceSelection: true.
// We create a new record.
if (!isCleared && !matchedRecord && !forceSelection && me.autoCreateRecord) {
matchedRecord = me.createEnteredRecord(value);
}
else {
if (isInput || is.store) {
if (!matchedRecord && forceSelection) {
me.setValue(null);
me.setSelection(null);
if (!is.filter) {
me.setFieldDisplay();
}
}
} else {
if (isCleared) {
if (me.mustAutoSelect()) {
matchedRecord = store.first();
if (me.getAutoSelect() === 'initial') {
me.setAutoSelect(false);
}
}
else {
me.setSelection(null);
}
}
else if (!matchedRecord && valueNotFoundText) {
me.setError(valueNotFoundText);
}
}
}
if (matchedRecord) {
me.setSelection(matchedRecord);
}
me.reconcilingValue = false;
}
});
Related
I'm having trouble updating this code from angularjs ad angular 2, thank you for any help
if (settings != null && settings.checkSubscriptionForVip === true) {
return this.user.hasVipAccess().then(function(hasVipAccess) {
hasVipAccess ? deferred.resolve() : deferred.reject("NO_VIP");
return;
});
} else {
deferred.resolve();
return;
}
You neeed to have a boolean variable defined in your component and assign the result in to that,
hasVipAccess : boolean = false;
if (settings != null && settings.checkSubscriptionForVip === true) {
this.user.hasVipAccess().then(function(access) {
this.hasVipAccess = access;
});
} else {
this.hasVipAccess = access;
}
However if you do not need to set boolean variable, just return the result
I was asked to change some code using lodash's _.every:
//for every item in collection, check if "someProp" is true,
//but only if "someProp2" isn't "-1". If "someProp" is true for
//every item in collection, return true.
$scope.areAllTrue = function() {
for(var i=0; i<$scope.collection.length; i++){
if($scope.collection[i].someProp2 === -1) {
continue;
}
if(!$scope.collection[i].someProp) {
return false;
}
}
return true;
};
So following the lodash example of:
_.every(users, 'active', false);
We get:
$scope.areAllTrue = function() {
return _.every($scope.collection, 'someProp', true)
};
This handles the "For every item in the collection, check if someProp is true, if all are true, return true." But can I do the "continue" check here somehow?
Edit: Can I use two predicates with "_.every" somehow? Like if someProp1 === true || someProp2 === -1 ?
_.every() can use a predicate function:
_.every(users, function(user) {
return user.someProp2 === -1 || user.someProp;
});
You can also skip lodash, and use Array.prototype.every:
users.every(function(user) {
return user.someProp2 === -1 || user.someProp;
});
If i do:
scope.$watch('obj', function(newObj, oldObj) {
//...
}, true);
How do I find the key-value pair in the object that changed?
.
Only to understand what I try to do:
I have an object of the form:
scope.actions = {
action1: false,
action2: false
}
When the boolean changes, I want to assign function calls to it. Something like, DO-action - UNDO-action.
So I watch it the following way:
scope.$watch('actions', function(newObj, oldObj) {
/*PSEUDO CODE START*/
IF (action1 changed && action1 true) {
do-func1();
}
IF (action1 changed && action1 false) {
undo-func1();
}
...
/*PSEUDO CODE END*/
}, true);
My problem here is, that if I check the values for their boolean, all the functions get called. So the point here is, how do I find the changed key-value pair in the object?
scope.$watch('actions', function(newActions, oldActions) {
for(var i in newActions) {
if(newActions.hasOwnProperty(i)) {
var newAction = newActions[i];
var oldAction = oldActions[i];
if(newAction !== oldAction) {
if(newAction === true) {
doActions[i](); // do-func-i();
} else if (newAction === false) {
undoActions[i](); // undo-func-i();
}
}
}
}
}, true);
doActions here is a conventional map of actions
doActions = {
action1 : function() {
console.log('action1');
},
action2 : function() {
console.log('action2');
}
}
doActions['action1'] will reference first function
You may have an array as well, but then you'll need to introduce an index to fetch proper function doActions[0]
I open page properties and fill some fields
After I pressed cancel button, and reopened properties dialog, all field cleared, but datetime fields didn't.
What is the rigth way to clear datetime fields?
I was debuggin and find out strange behavior of isApplyDefault method in \ibs\cq\ui\widgets\source\ext\override\widgets\form\Field.js. It is compare created and modefied date, if they equals returns true, otherwise false.
I just ovveride method processRecord in DateTime.js to remove calling isApplyDefault:
processRecord: function(record, path) {
if (this.fireEvent('beforeloadcontent', this, record, path) !== false) {
var v = record.get(this.getName());
if (v == undefined && this.defaultValue != null) {
this.setValue(this.defaultValue);
}
else {
this.setValue(v);
}
this.fireEvent('loadcontent', this, record, path);
}
}
in Field.js it is:
processRecord: function(record, path) {
if (this.fireEvent('beforeloadcontent', this, record, path) !== false) {
var v = record.get(this.getName());
if (v == undefined && this.defaultValue != null) {
if (this.isApplyDefault(record, path)) {
this.setValue(this.defaultValue);
}
}
else {
this.setValue(v);
}
this.fireEvent('loadcontent', this, record, path);
}
}
See also in adobe forum
I have a checkbox on my form panel,
And I'm on the process where I need to edit a data based on id in MySQL database where there is a option for checkbox 1=checked 0=not checked,
how do I get the value of, for example, the field of checkbox and put it on a conditional clause and set the value checked to checkbox if it is 1 and not checked if it returns 0?...
Need to set to the checkbox config
inputValue: '1',
uncheckedValue: '0'
You can check the documentation at http://docs.sencha.com/extjs/4.2.2/#!/api/Ext.form.field.Checkbox-cfg-uncheckedValue
All checks do not consider the event check if the value is a string. I created a fix. Add before Ext.onReady
Ext.override
(
Ext.form.Checkbox,
{
setValue:function(v){
var checked = this.checked, inputVal = this.inputValue;
if(v === false)
{
this.checked = false;
}
else
{
this.checked = (v === true || v === 'true' || v == '1' || (v instanceof String) || (inputVal ? v == inputVal : String(v).toLowerCase() == 'on'));
}
if(this.rendered)
{
this.el.dom.checked = this.checked;
this.el.dom.defaultChecked = this.checked;
}
if(checked != this.checked)
{
this.fireEvent('check', this, this.checked);
if(this.handler)
{
this.handler.call(this.scope || this, this, this.checked);
}
}
return this;
}
}
);
{
xtype:'checkbox',
fieldLabel:'Caption',
labelSeparator:':',
boxLabel:'LabelText',
name:'status',
inputValue:'0'
}
inputValue must be a String '0'.
this issue has been resolved,
by using 1 checkbox per field, there is no problem at all!....
the checkbox will get checked when the fieldname assigned to it returns a value of 1,
that's it!,
....