ExtJs Checkbox Bind Issue - extjs

A checkbox in ExtJs Form Panel is not binding properly , i.e when the value is changed from checked(value is 1) to unchecked (value is 0) the value in model for the respective field is still checked(1). This issue occurs in version 6.2.0.981, but the issue is not reproducible in latest version 6.2.1.167. Here is the fiddle for the same, toggle between the versions and check the issue. please let us know if there are any workaround for this issue in 6.2.0.981 version. Also in release notes of 6.2.1.167 its told that "EXTJS-21886 - Checkboxes don't return the correct value" is fixed, but how to have this fix in previous versions?
CheckBox Bind issue Fiddle

You can fix this by adding
uncheckedValue: 0
to your checkbox config. Excerpt from the docs:
By default this is undefined, which results in nothing being submitted for the checkbox field when the form is submitted
The bug was that nothing was submitted during model update as well, and since nothing was provided, the value of the model was not updated.

In ExtJS 6.6 I was still trying to figure this out and it wasn't as straight forward as I'd hoped (Having the checkbox bind to the model and pass 1 for true and 0 for false to the binding). I wanted to avoid having a formula with a middle man binding in the model because I'd have to have a formula for every checkbox and that seemed silly.. Extending the combo box class and overriding getValue method like below. The accepted answer worked ok for unchecked but I was still getting true on checked.
Ext.define('Components.BinaryCheckBox', {
extend: 'Ext.form.field.Checkbox',
xtype: 'binary-checkbox',
getValue: function () {
if (this.value) {
return 1;
} else {
return 0;
}
},
});

Related

ExtJS -- tag field ignoring forceSelection flag on enter/blur

I'm using the Ext.form.field.Tag component. I have configured
createNewOnEnter:true,
createNewOnBlur:true,
forceSelection:true
but if I type in a value that's not the in the dropdown list/store records and tab-out or click enter the value gets selected. I want the value to be selected on enter/blur ONLY if it exists in the dropdown. But when createNewOnEnter and createNewOnBlur are set to true, forceSelection becomes false. I verified this by setting a debugger in the "change" event handler.
I dont have a fiddle but you can copy paste the above config into the live editor in the API Docs here
thanks
There are some configurations that are incompatible with each other, and ExtJS does not provide for all thinkable configurations of components (although they try, but then, Tagfield is quite new). This is the relevant part of the form/field/Tag.js file that explains your experience:
if (me.createNewOnEnter || me.createNewOnBlur) {
me.forceSelection = false;
}
To get what you want, you would have to override some parts of the tag field definition to suit your needs. You should look into overriding the assertValue and the onKeyUp functions.

Angular indeterminate checkbox directive ng-change issue

I am trying to implement the angular data-indeterminate-checkbox directive in my application from the link below.
Example Fiddle
I have added ng-change to both the parent and the children checkboxes (same event) which updates the columns in a table below. The problem is when I check/uncheck the child checkboxes, the columns appear and dissapear fine and it works ok, but when I click the select all checkbox, the action is inverted. That is, when select all is checked, all columns hidden and when unchecked, all columns are visible.
In the snippet for the directive from the fiddle link mentioned above, in the else part, if I change the modelCtrl.$setViewValue(hasChecked); to modelCtrl.$setViewValue(true);, as shown in code below, the uncheck part works, i.e when I uncheck 'Select All', all columns are hidden but when I check it, nothing happens and it does not go to the ng-change event. Any help is much appreciated.
Thanks in advance and Happy New Year 2016!!
// Determine which state to put the checkbox in
if (hasChecked && hasUnchecked) {
element.prop('checked', false);
element.prop('indeterminate', true);
if (modelCtrl) {
modelCtrl.$setViewValue(false);
}
} else {
element.prop('checked', hasChecked);
element.prop('indeterminate', false);
if (modelCtrl) {
modelCtrl.$setViewValue(true);
}
}
Solved it by putting a condition on the ng-change event of the checkboxes. Here is the snippet - (as per the example fiddle):
if(!$scope.model.people[0].allEaten){
$timeout(function(){
updateModel();
refreshColumns();
},2000);
} else {
$timeout(function(){
refreshColumns();
},2000);
}
But please feel free to comment if there is a better answer to this.
Thank you!

AngularJS inconsistent databinding

I'm learning AngularJS and I have a question regarding the databinding for select elements. The databinding for textboxes works without any kind of event handling code. Once the ng-model attribute is set textbox updates when the model property changes and vice versa. There is no need for ng-change attribute.
However, for select elements we need to write functions that will be called via ng-change atribute.
Why does angularjs handle databinding without an ng-change attribute for textboxes but requires functions that will be called via ng-change attribute for select elements?
UPDATE:
Added the fiddle in the comments section. The example is from AngularJS in Action book. Click on one of the stories, change the textbox value and the model is updated. Change the selection in dropdown model is not updated.
UPDATE:
Added a new fiddle in the comments.
Thanks.
I've created a fiddle that works here - The issue is really just the dummy data here. In the original fiddle, the object created in the statuses array for {name:'Back Log'} and {name:'To Do'} are not the same (not ===) as the {name:'Back Log'} and {name:'To Do'} objects created in the dummy story objects.
To make the example work, I pass the indexed statuses into the getStories function. However I think this is really just a case of demo-induced confusion. (I've been looking at the MEAP for Angular in Action as well, and I think it could be simplified a bit like this one, that uses simple string statuses that will pass the === test
var getStories = function(statusesIndex) {
var tempArray = [
{title:'Story 00',
description:'Description pending.',
status: statusesIndex['To Do']
},
{title:'Story 01',
description:'Description pending.',
status: statusesIndex['Back Log']
}
];
return tempArray;
}
I think your confusion might be a result of the select documentation still being incorrect. (See my Disqus comment.) ng-model can and should be used with select. ng-change is optional and it just gives you a hook should you want to do something each time the selected option changes.
Normally you should use ng-options with select.
If i understood your question correctly then I think your guessing is wrong because for select boxes, you do not have to invoke ng-change event in order to fetch the selected option.
<select ng-model='select'>
<option>....</option>
<option value='one'>One</option>
<option value='Two'>Two</option>
</select>
// Your selected option will print below... without invoking ng-change
<div>You selected: {{select}}</div>
Demo: http://jsfiddle.net/jenxu/1/

ExtJS 4 ComboBox AutoComplete

I have an extjs combobox used for auto-complete having following configuration:
xtype:'combo',
displayField: 'name',
valueField:'id',
store: storeVar,
queryMode: 'remote',
minChars:2,
hideTrigger:true,
forceSelection:true,
typeAhead:true
There are two issues being faced by me:
a. If a user chooses a value from the list returned from server, but later wants to remove that value and keep combo-box empty, then also the old values re-appears on blur, not allowing combo-box to remain empty. How can I allow empty value in this combo-box in such a case? I understand it could be due to forceSelection:true, but then I need to keep it true as otherwise user can type any random value.
b. When the server returns an empty list, I want to display a message - No Values Found. I tried doing this, by putting this value in the displayField entity, i.e., {id:'', name:'No Value Found'}. But then in this case, the user is able to choose this value and send it to server which is not what is expected. Thus, how can I display the message for empty list?
Could someone please throw light on this?
For the issue related to forceSelection in the question above, following is the hack created which can serve the expected purpose:
Ext.override(Ext.form.field.ComboBox,{
assertValue: function() {
var me = this,
value = me.getRawValue(),
rec;
if (me.multiSelect) {
// For multiselect, check that the current displayed value matches the current
// selection, if it does not then revert to the most recent selection.
if (value !== me.getDisplayValue()) {
me.setValue(me.lastSelection);
}
} else {
// For single-select, match the displayed value to a record and select it,
// if it does not match a record then revert to the most recent selection.
rec = me.findRecordByDisplay(value);
if (rec) {
me.select(rec);
} else {
if(!value){
me.setValue('');
}else{
me.setValue(me.lastSelection);
}
}
}
me.collapse();
}
});
This needs to be included after library files of extjs have been included.
For the other issue of message to be shown at No Values Found - emptyText - works fine as suggested by Varun.
Hope this helps somone looking for something similar.
I've done this for Ext JS 3.3.1. I don't know if they apply to Ext JS 4, though I guess they should.
For the first problem, set autoSelect : false. autoSelect is by default set to true. This will work only if allowBlank : true is set. From the docs
true to select the first result gathered by the data store (defaults
to true). A false value would require a manual selection from the
dropdown list to set the components value unless the value of
(typeAheadDelay) were true.
For the second problem, use listEmptyText. From the docs
The empty text to display in the data view if no items are found.
(defaults to '')
Cheers.

How to hide rows in ExtJS GridPanel?

Suppose I know which row index to target (with this.rowToBeDeleted having a value of 2, say), how can I hide this row only from the grid but not the store (I have a flag in the store, which signifies what rows should be deleted from the db later in my PHP webservice code).
You can either use one of the store.filter() methods or you can hide the row element.
grid.getView().getRow(rowIndex).style.display = 'none';
I think it's much better though to just remove the record from the store and let the store update the view since you are deleting the record and not just hiding it. With the store in batch mode (the default: batch: true, restful: false), it will remember which rows you've removed and won't fire a request to the server until you call store.save().
I suggest using store.FilterBy() and pass a function to test the value of the value in rowToBedeleted:
store.filterBy(function(record) {
return record.get("rowToBeDeleted") != 2;
});
I wrote a basic blogpost about gridfiltering a while ago, you can read it here: http://aboutfrontend.com/extjs/extjs-grid-filter/
In ExtJS 4.1, there is no view.getRow(..). Instead you can use:
this.view.addRowCls(index, 'hidden');
to hide the row at the specified index, and
this.view.removeRowCls(index, 'hidden');
to show it (where 'this' is the grid).
CSS class hidden is defined as
.hidden,
{
display: none;
}
This is useful for peculiar scenarious where store.filterBy() is not appropriate.
In the grid js file write following code to apply a CSS to those rows which you want to hide.
<pre><code>
Ext.define('MyGrid',{
extend : 'Ext.grid.Panel',
xtype : ''mygrid',
viewConfig : {
getRowClass : function(record,id){
if(record.get('rowToBeDeleted') == 2){
return 'hide-row';
}
}
},
.................
.................
});
</code></pre>
Now define a custom CSS in custom.css file:
.hide-row{display:none}
This will hide rows in grid without removing or filtering from store.
You can use the store.filter() or store.filterBy() methods for that.
Set a "hidden" property on your records and the filter all records that have hidden set to true for example. This way they'll still be present in the store but not visible in the grid.

Resources