Modern 7.0 ComboBox fires 'select' event on every value change - extjs

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

equivalent of following code in angular 2

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

Test multiple properties using _.every

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;
});

find updated field in object - scope.$watch - angularjs

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]

On/Off time(datetime field) doesn't cleared after cancel button is pressed

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

Extjs checkbox setValue based on 1 and 0

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!,
....

Resources