Set default value to a checkbox in EXT JS (Sencha) - extjs

I have a checkbox whose value is bound to a field from database. I want to set a default value 'true'/'checked' if the database contains null value.
The checkbox is :
xtype: 'checkbox',
bind: { value: '{database_variable_name}'},
fieldLabel: 'label_name'
I have tried this formula with no effect (checkbox remains unchecked):
bind: { value: '{checkboxFormula}'}
and
checkboxFormula: {
get: function (get) {
var value = get('database_variable_name');
return (value == null) ? true : value;
},
set: function (value) {
this.set('database_variable_name', value);
}
}
The whole function works correctly if database does not return null, the checkbox is checked/unchecked accordingly. Any pointers to where I might be going wrong would be highly appreciated!
PS : Binding database variables is already in working condition.

Related

How to disable the widget in a widgetcolumn of a grid based on the attribute of a record in Sencha ExtJS v6?

More or less the configuration looks like this:
{
xtype: 'widgetcolumn',
//text: "", //localize
dataIndex: "carStatusButton",
//disable action for the column
sortable: false,
filter: false,
menuDisabled: true,
widget: {
xtype: 'changeavailbutton',
//reference: "gridCarStatusButton", we cannot use reference because we get a duplicate reference warning
//text is being automatically generated from dataIndex of widgetcolumn
/*
//didn't work!
defaultBindProperty: "curCarStatus", //default is text
curCarStatus: "aaaaaaaa",
setCurCarStatus: function (value) {
this.curCarStatus = value;
},*/
/*
getCurCarStatus: function () {
return "aaaaaa"
},
setCurCarStatus: function (value) {
},*/
/*text: (function() {
return this.enableToggle;
})(),
bind: {
},*/
},
}
We have considered using the updater(cell, value, record, view) but it does not get called initially
We have considered using the renderer(value, metadata, record) but we can only affect the value, it does not give us any help with the widget
We considered to use a custom defaultBindProperty in the widget like this:
defaultBindProperty: "curCarStatus", //default is text
curCarStatus: "",
setCurCarStatus: function (value) {
this.curCarStatus = value;
}
The above helped to avoid creating an extra field in the model that would be necessary. In other words initially we had a field in the model, as a transient field to get the calculated value inside the dataIndex of the widgetcolumn but didn't bring any help on what we were trying to achieve.
The fact is that (from documentation) widgetcolumn binds the dataIndex to the defaultBindProperty of the widget. One problem is that there is a bind that happens in the background that we are not aware of its key value. It would look like that if it was a configuration:
bind: {
text: "{unknownProperty}"
}
If we knew how the property was called it could be helpful to use it in various properties because in our situation we need to bind more than one properties to the widget.
We are actually looking similar functionality provided by isDisabled provides to an ActionColumn to have it in a WidgetColumn.
In the widgetcolumn itself:
onWidgetAttach: function (column, widget) {
if (widget.getWidgetRecord().get('property')) {
widget.setDisabled(false)
} else {
widget.setDisabled(true)
}
}
And the grid can be updated with grid.getView().refresh() to reflect any changes

Sencha Touch 2.3: Remove validations from hidden form fields

I am doing form validations in Sencha Touch 2.3. My model looks like following.
Ext.define('net.omobio.dialog.dialogcc.model.StockTransferDetails', {
extend: 'Ext.data.Model',
config: {
fields: ['to_msisdn','to_profile_id','transfer_lob','transfer_item_status','transfer_product','transfer_qty','transfer_req_type','transfer_item_type','transfer_pack_type'],
validations: [
{ type: 'presence', field: 'to_msisdn' },
{ type: 'presence', field: 'to_profile_id' },
{ type: 'exclusion', field: 'transfer_lob', list: ['null'] },
{ type: 'exclusion', field: 'transfer_req_type', list: ['null'] },
{ type: 'exclusion', field: 'transfer_item_type', list: ['null'] },
{ type: 'exclusion', field: 'transfer_pack_type', list: ['null'] }
]
}
});
Following is a code segment that I use in my controller to remove validations from hidden form fields but no luck.
var form1 = me.getStockTransferRequestPage();
var model = Ext.create("net.omobio.dialog.dialogcc.model.StockTransferDetails", form1.getValues());
// validate form fields
var errors = model.validate();
if (!errors.isValid()) {
// loop through validation errors and generate a message to the user
errors.each(function (errorObj){
//errorString += errorObj.getField() + " " + errorObj.getMessage();
console.log('7777777777777777777 '+errorObj.getField());
if (!Ext.getCmp(errorObj.getField().toString()).isHidden()) {
var s = Ext.String.format('field[name={0}]',errorObj.getField());
form1.down(s).addCls('invalidField');
}
});
Ext.Msg.alert('','stock_transfer.errors.required_fields_empty');
}
I would be much appreciated if anyone could help me to solve this.
Thank you
so there are multiple ways to achieve this, my preference even though some folks won't like it, but it will always work.
I did the following override to solve this problem, tried my best not to affect the normal flow of validation.the first two overrides have to be added somewhere to your overrides folder, you only have to add them once for the whole app.
Ext.Define('Ext.form.field.BaseOverride', {
override: 'Ext.form.field,Base',
/* traverse up and look for a hidden Parent/Ancestor */
isParentHidden: function () {
return this.up('[hidden=true]');
}
/* override isValid basic method to consider skipValidateWhenHidden property, when skipValidateWhenHidden is set to true code should check if the elementor it's Parent/Ancestors is hidden */
isValid: function () {
var me = this,
disabled = me.disabled,
isHidden = me.isHidden(),
skipValidateWhenHidden = !!me.skipValidateWhenHidden,
validate = me.forceValidation || !disabled,
isValid = validate ? me.validateValue(me.processRawValue(me.getRawValue())) : disabled;
if (isValid || !skipValidateWhenHidden) {
return isValid;
}
if (skipValidateWhenHidden) {
isHidden = isHidden ? true : me.isParentHidden();
if (isHidden) {
return skipValidateWhenHidden;
}
}
return isValid;
}
});
and eventually you'll be able to do the following, which is set the property to true on any field so if its not visible for the user, it will survive validation
{
itemId: 'City',
cls: 'AddressCity',
xtype: 'textfield',
emptyText: emptyCityText,
skipValidateWhenHidden: true,
},
another approach is to add a show()/Hide() listener on the fields container to enable/disable the children, disabling the fields would make them skip validation, but i'm not a big fan of managing button states and wiring listeners.
Note
Ext.getCmp() takes component id
errorObj.getField().toString() returns model field name, It won't
return id of the component (hidden) field.
So if model field name matches with hidden field id, It will work. Otherwise it won't work.

Values not being added to combobox dynamically

I have a combobox whose values I need to populate via the json formatted string I am retrieving via AJAX call.
Here's the string which I have retrieved (stored in data)
{
"a2m":
[
"a2mMeeting",
"sugar"
]
}
The combobox must contain a2m (this is the only name in the string as of now)
Here's what I have been trying:
Approach 1:
this.initAjaxCall = Ext.Ajax.request({
url : 'indigo/restproxy/get/v1/applications/list',
method:'GET',
scope : this,
success : function(result, request) {
var data = Ext.decode(result.responseText);
Object.keys(data).forEach(function(key) {
console.log(key);
Ext.getCmp('appCombo').getStore().add({appName : key});
})
}
});
this.appcombo = Ext.create('Ext.form.field.ComboBox', {
id : 'appCombo',
store: this.appStore
});
this.appStore = Ext.create('Ext.data.Store', {
fields : [
{
name : 'appName',
type : 'string'
}
]
});
Approach 2:
this.appStore = Ext.create('Ext.data.Store', {
fields: ['appName'],
proxy: {
type: 'ajax',
url: 'indigo/restproxy/get/v1/applications/list',
method : 'GET'
},
listeners: {
load: function(store, records, successful, eOpts ) {
store.insert(0, {
'appName' : 'yellow' //Trying to populate randomly using this method.
})
}
}
})
this.appcombo = Ext.create('Ext.form.field.ComboBox', {
id : 'appCombo',
store: this.appStore
});
In both the cases the combobox doesn't load any value and I am unable to see any value in the dropdown menu.
EDIT 1: When I printed the store.getCount() in the console after adding one element, the value is shown as 1 (checked by adding two elements and it does show 2). This implies the values are being added to the store but not being shown in the combobox dropdown menu. Kindly suggest how to resolve this.
SOLUTION:
The solution as it turns out was by adding a statement queryMode : 'local'. I don't understand why this was creating an issue. Anyone willing to shed light on this is welcome to do so.
As you have proven the store is being populated. However you haven't set a display field on the combo box.
this.appcombo = Ext.create('Ext.form.field.ComboBox', {
id : 'appCombo',
store: this.appStore,
displayField: 'appName'
});
displayField: The underlying data field name to bind to this ComboBox. Defaults to: 'text'
valueField: The underlying data value name to bind to this ComboBox. Defaults to match the value of the displayField config.

ExtJs combo loses selected value on store page load

I have an ExtJS 4.1 combo box with a JsonStore and queryMode: 'remote', with paging and filtering, as such:
...
queryMode: 'remote',
allowBlank: true,
forceSelection: true,
autoSelect: false,
pageSize: 25,
typeAhead: true,
minChars: 2,
...
When I load my form with a saved value in this combo box, I load the store passing the saved value as a query (filtering) parameter, to make sure that the selected value is definitely within the returned records, and then I set that value as the combo selected value as such:
mycombo.getStore().load({
params: {
query: displayField
},
scope: {
field: combo,
valueField: valueField,
displayField: displayField
},
callback: function(records, operation, success) {
this.field.setValue(this.valueField);
}
});
So far, so good, the above works fine. The problem is, that if the user then clicks on the dropdown arrow to select another value for the combo, the 1st page of the store is loaded, erasing all previously selected values, and even if nothing is selected, the previously selected value is lost.
This problem is generic, and is quite similar to this question:
ExtJS paged combo with remote JSON store. Display selected value with paging
and can be summarized as such:
In an ExtJS combo box with a remote store and paging, selected values are lost when the loaded page changes.
I tried setting clearOnPageLoad: false for the store, but then each time a new page is loaded, the records are appended to the end of the list. I would have expected this parameter to cache the loaded pages and still show me the correct page while moving back and forth.
So, any ideas on how to keep the selected value while moving between pages? I suppose I could create a record with the selected value manually and append it to the store on each page load until a new value is selected, but this sounds like too much effort for something so basic.
We ended up contacting Sencha support since we have a paid license. This is the answer we got back:
Ext.override(Ext.form.field.ComboBox, {
onLoad: function() {
var me = this,
value = me.value;
if (me.ignoreSelection > 0) {
--me.ignoreSelection;
}
if (me.rawQuery) {
me.rawQuery = false;
me.syncSelection();
if (me.picker && !me.picker.getSelectionModel().hasSelection()) {
me.doAutoSelect();
}
}
else {
if (me.value || me.value === 0) {
if (me.pageSize === 0) { // added for paging; do not execute on page change
me.setValue(me.value);
}
} else {
if (me.store.getCount()) {
me.doAutoSelect();
} else {
me.setValue(me.value);
}
}
}
}
});
Had the same problem, and 'pruneRemoved: false' didn't work (it seems to be used only in grids). This is the solution:
Ext.override(Ext.form.field.ComboBox,{
// lastSelection is searched for records
// (together with store's records which are searched in the parent call)
findRecord: function(field, value) {
var foundRec = null;
Ext.each(this.lastSelection, function(rec) {
if (rec.get(field) === value) {
foundRec = rec;
return false; // stop 'each' loop
}
});
if (foundRec) {
return foundRec;
} else {
return this.callParent(arguments);
}
}
});
Hope it doesn't have negative side effects. I've tested it a bit and it seems OK.
I am experiencing this issue in extjs 6.0.1.
I discovered a work around that might be helpful for others.
I used override for onLoad to add the selected record from the combo to the store prior to calling the base onLoad.
This works because if the selected record is in the page being viewed, the combo is smart enough to not clear the selection. In other words, the reason the selection is being cleared as you page is because the selected record is not in the page you are viewing.
onLoad: function (store, records, success)
{
var selection = this.getSelection();
if (selection)
{
records.unshift(selection);
store.insert(0, records);
}
this.callParent(arguments);
}

How do I set a Ext Grid Filter Default?

I have a working sort-able grid using the ext 3.4 grid filter plugin. I would like to default the active column to filter true values. User who needs the inactive records could remove the filter. How do I specify a default filter column and value?
Thanks in advance!
colModel: new Ext.grid.ColumnModel({
defaults: {
sortable: true
// How do I specify a default filter value
//
// Only show active records unless the user changes the filter...
},
columns: [{
dataIndex:'f_uid',
id:'f_uid',
header:'ID',
hidden:true
}, {
dataIndex:'f_name',
id:'f_name',
header:'Name',
}, {
xtype:'booleancolumn',
dataIndex:'f_active',
id:'f_active',
header:'Active',
filterable:true,
trueText:'Active',
falseText:'Inactive'
}]
I realise this is an old question but it took me a while to find a solution, therefore I thought I would share.
1) The filter can be set using the value property in the filter.
filter: {
type: 'LIST',
value: ['VALUE TO FILTER']
}
2) In order to initially filter the data use the filterBy() method in the store. This could be defined in the onRender event handler.
this.getStore().load({
scope:this,
callback: function() {
// filter the store
this.getStore().filterBy(function(record, id) {
// true will display the record, false will not
return record.data.DATA_TO_FILTER == 'VALUE TO FILTER ';
});
}
});
The answer was in the Filter.js source code. The filter object within the column definition can be used to configure the default behavior.
}, {
xtype:'booleancolumn',
dataIndex:'f_active',
id:'f_active',
header:'Active',
trueText:'Active',
falseText:'Inactive',
filterable:true,
filter: {
value:1, // 0 is false, 1 is true
active:true // turn on the filter
}
}
I have encountered the same problem and I found that #John's answer is right, I can make it work with the sample http://dev.sencha.com/deploy/ext-4.0.0/examples/grid-filtering/grid-filter-local.html, for the grid-filter-local.js, just add the code like:
grid.getStore().load({
scope:this,
callback: function() {
// filter the store
grid.getStore().filterBy(function(record, id) {
// true will display the record, false will not
return record.data.size === 'small';
});
}
});
before the original code store.load(), and wipe off the store.load().
Then it will only show the record with size equals 'small' at the first load of the web page. Cheers!
I've made a universal helper class that allows you to set any default values in column definition.
https://gist.github.com/Eccenux/ea7332159d5c54823ad7
This should work with both remote and static stores. Note that this also works with filterbar plugin.
So your column item is something like:
{
header: 'Filename',
dataIndex: 'fileName',
filter: {
type: 'string',
// filename that starts with current year
value: Ext.Date.format(new Date(), 'Y'),
active:true
}
},
And then in your window component you just add something like:
initComponent: function() {
this.callParent();
// apply default filters from grid to store
var grid = this.down('grid');
var defaultFilters = Ext.create('Ext.ux.grid.DefaultFilters');
defaultFilters.apply(grid);
},

Resources