is there any way to re-render checkbox in ext js? - javascript

i have following code
extend: 'Ext.container.Viewport',
initComponent: function () {
var me = this;
me.items = [
{
xtype: 'checkbox',
fieldLabel: 'RPTest',
itemId:'chk1'
},
{
xtype: 'button',
text: 'test',
handler: function () {
me.chk1.setBoxLabel(me.chk1.fieldLabel);
me.chk1.boxLabelAlign = 'before';
me.chk1.setFieldLabel('');
}
}
];
me.callParent(arguments);
me.chk1 = me.down('#chk1');
}
})
i want to update boxLabelAlign property whenever user click button property values changes but DOM doesn't update i have tried updateLayout() of checkbox but it doesn't works. so is there any solution of these problem? or is there any way to update DOM??

You should use the setConfig() method to assign the new boxLabelAlign property instead of assigning the value directly. Here is how:
var checkbox = Ext.create({
xtype: 'checkbox',
boxLabelAlign: 'after',
boxLabel: 'ltest'
})
var button = Ext.create({
xtype: 'button',
text: 'CLICK ME',
handler: function () {
checkbox.setConfig({
boxLabelAlign: 'before'
})
}
})
Ext.create('Ext.panel.Panel', {
title: 'Setting label align',
items: [
checkbox,
button
],
renderTo: Ext.getBody()
});
You can change the initialConfigs of an Ext js element using the element.setConfig({...}) method

Related

How to read values from multiselector component

I am trying to use multiselector from EXTJS 6.5.2
This is the code that I am using to create multiselector with the values that I need
{
xtype: 'multiselector',
title: 'I caktohet:',
name: 'Caktohen[]',
bind: '{userfullname.value}',
fieldName: 'userfullname',
viewConfig: {
deferEmptyText: false,
emptyText: 'Askush i zgjedhur'
},
search: {
field: 'userfullname',
model: 'InTenders.model.UserModel',
store: {
type: 'users',
sorters: 'userfullname',
// proxy: {
// type: 'rest',
// limitParam: null,
// url: 'api/User'
// }
}
}
}
When I call form = win.down('form') records I can get all values except the multiselector values, they show like this on console.
Anyone can help me or guide me how to get the values?
Thank you.
//Code that I'm trying to get multiselector items and save them
saveTenderForm: function (button, e, eOpts) {
var userMultiSelector = Ext.getCmp('AssignedUsers'); //save assigned users
var selectedUsers = userMultiSelector.getStore().getData(); //get store and put them in array
var me = this,
win = button.up('window'),
form = win.down('form'),
// formApplyUpload = this.getFormApplyUpload(),
// var ko = win.items.items[0].items.items[0].value;
recordtenderUsers = Ext.create('InTenders.model.TenderSaveModel');
// recordtenderUsers = form.getRecord();
// record = form.getRecord(),
values = form.getValues();
// appFile = this.getApplicationFile(),
// callbacks;
recordtenderUsers.set(values);
recordtenderUsers.set('tenderUsers',selectedUsers.items);
// // me.showMask();
// if (form.isValid()) {
recordtenderUsers.save({
success: function (recordtenderUsers, operation) {
win.close();
me.hideMask();
},
failure: function (recordtenderUsers, operation) {
me.hideMask();
}
});
You can get value using multiselector.down('grid') this will return you the grid. And grid have method getSelection().
In this FIDDLE, I have created a demo. I hope this will help/guide you to achieve your requirement.
CODE SNIPPET
Ext.application({
name: 'Fiddle',
launch: function () {
Ext.create({
xtype: 'form',
renderTo: Ext.getBody(),
items: [{
xtype: 'multiselector',
title: 'Multi selector example',
fieldName: 'text',
viewConfig: {
deferEmptyText: false,
emptyText: 'No value selected'
},
search: {
field: 'text',
store: {
fields: [{
name: 'text',
type: 'string'
}],
data: [{
text: 'ABC'
}, {
text: 'ABC 1'
}, {
text: 'ABC 2 '
}, {
text: 'ABC 3'
}, {
text: 'ABC 4'
}]
}
}
}, {
xtype: 'button',
text: 'Get Value',
margin:15,
handler: function (btn) {
var multiselector = btn.up('form').down('multiselector');
if (multiselector.down('grid')) {
multiselector.down('grid').getSelection().forEach(rec => {
console.log(rec.get('text'));
});
}
}
}]
});
}
});

How to enable Extjs filters on page load

I want to filter my grid with different buttons that active certain filters. However they do not work on page load. Only when you select/deselect a filter option and then click the button, does the filter actually kick in.
When the page first loads and you click a button, you get the following error:
TypeError: filter is undefined
How do I enable these filter settings when the page first loads?
To recreate the error. Load the fiddle and try clicking the buttons and notice they don't work. Then activate one of the filters and try again. The buttons will work after a filter is activated.
Fiddle
Buttons
var openButton = Ext.create('Ext.Button', {
text: 'Open Topics',
handler: function () {
var filter = grid[uniqueId].filters.getFilter('TopicStateValue');
filter.setActive(true);
filter.setValue('Open/Current');
}
});
var holdButton = Ext.create('Ext.Button', {
text: 'On Hold Topics',
handler: function () {
var filter = grid[uniqueId].filters.getFilter('TopicStateValue');
filter.setActive(true);
filter.setValue('Hold');
}
});
var closedButton = Ext.create('Ext.Button', {
text: 'Closed Topics',
handler: function () {
var filter = grid[uniqueId].filters.getFilter('TopicStateValue');
filter.setActive(true);
filter.setValue('Archived/Closed');
}
});
Columns
columns: [{
text: 'Title',
width: 260,
dataIndex: 'Title',
filterable: true,
filter: {
type: 'string'
// specify disabled to disable the filter menu
//, disabled: true
}
}, {
text: 'Description',
flex: 1,
dataIndex: 'Description',
filter: {
type: 'string'
// specify disabled to disable the filter menu
//, disabled: true
}
}, {
text: 'Modified',
width: 90,
dataIndex: 'Modified',
xtype: 'datecolumn',
format: 'm/d/Y',
filter: true
}, {
text: 'Status',
width: 100,
dataIndex: 'TopicStateValue',
filter: {
active: true,
type: 'list',
value: 'Open/Current',
options: ['Open/Current', 'Archived/Closed', 'Hold']
}
}]
Just check if the filter exists before pass value to it, if not, add it like this:
var openButton = Ext.create('Ext.Button', {
text: 'Open Topics',
handler: function () {
var filter = grid[uniqueId].filters.getFilter('TopicStateValue');
if (!filter) {
filter = grid[uniqueId].filters
.addFilter({
type : 'string',
dataIndex : 'TopicStateValue'
});
}
filter.setActive(true);
filter.setValue('Open/Current');
}
});
var holdButton = Ext.create('Ext.Button', {
text: 'On Hold Topics',
handler: function () {
var filter = grid[uniqueId].filters.getFilter('TopicStateValue');
if (!filter) {
filter = grid[uniqueId].filters
.addFilter({
type : 'string',
dataIndex : 'TopicStateValue'
});
}
filter.setActive(true);
filter.setValue('Hold');
}
});
var closedButton = Ext.create('Ext.Button', {
text: 'Closed Topics',
handler: function () {
var filter = grid[uniqueId].filters.getFilter('TopicStateValue');
if (!filter) {
filter = grid[uniqueId].filters
.addFilter({
type : 'string',
dataIndex : 'TopicStateValue'
});
}
filter.setActive(true);
filter.setValue('Archived/Closed');
}
});
You need to initialize the filters manually before you use them.
Please add the below code to your grid panel.
listeners: {
beforeRender:function() {
this.filters.createFilters();
}
},
I tried that on your fiddle and it works.

Passing an argument to a declared function

I have the following function declaration
var exportStore = function (exportVar) {
// Process export .cfc
var params_JSON = {
<cfoutput>
l_companyid: '#url.companyid#',
l_start: '#l_start#',
l_end: '#l_end#'
</cfoutput>
};
if(exportVar == 'results') {
var exportQuery = Ext.getCmp('query');
var query = exportQuery.getValue();
params_JSON.query = query;
}
<cfoutput>var url = 'some url parameters' + Ext.JSON.encode(params_JSON)';</cfoutput>
//ajax call here returns link to export file
// display export link
var myForm = new Ext.form.Panel({
title: 'Export File',
width: 300,
height: 200,
floating: true,
closable : true,
layout: {
type: 'hbox',
pack: 'center'
},
items: [{
xtype: 'displayfield',
name: 'export_file',
value: 'Click here to download file'
}],
buttons: [{
margin: '0 10 10 0',
text: 'Close',
handler: function() {
this.up('form').destroy();
}
}]
});
I am attempting call this function from a button that has a drop down selection.
{
text: 'Export All',
handler: exportStore
},
{
text: 'Export Search Results',
handler: exportStore
}
My question is can you pass a parameter to a function declared as a variable? I know I can just give both buttons their own handler, but that handler is going to contain quite a bit of code and im attempting to simplify... just wanted to know if a paramerter can be passed to exportStore in some form for example.....
{
text: 'Export All',
handler: [
exportStore,
extraParams: { exportVar: 'all' }
]
}
You could use Ext.bind() to achieve this like below:
var exportStore = function (exportVar) {
// exportVar will have your 'all' or 'search' value as per the
// button clicked
...
}
// In definition
{
text: 'Export All',
handler: Ext.bind(exportStore, undefined, ['all'])
}, {
text: 'Export Search Results',
handler: Ext.bind(exportStore, undefined, ['search'])
}
You can refer this fiddle for the usage.

combobox should remember the last selection

Below is my code to display three comboboxes, which will be Filter by severity, start release and end release. When I refresh the page I want comboboxes to remember what was selected earlier. Now it shows the current release in both the comboboxes.
Any help on this
launch: function() {
var that = this;
this.down('#SevFilter').add({
xtype: 'rallyattributecombobox',
cls: 'filter',
itemId: 'severity',
model: 'Defect',
labelWidth: 117,
fieldLabel : 'Filter By Severity:',
field: 'Severity',
allEntryText: '-- ALL --',
allowNoEntry: true,
_insertNoEntry: function(){
var record;
var doesNotHaveAllEntry = this.store.count() < 1 || this.store.getAt(0).get(this.displayField) !== this.allEntrylText;
if (doesNotHaveAllEntry) {
record = Ext.create(this.store.model);
console.log("record value", record);
record.set(this.displayField, this.allEntryText);
record.set(this.valueField, "-1");
this.store.insert(0, record);
}
/*var doesNotHaveNoEntry = this.store.count() < 2 || this.store.getAt(1).get(this.displayField) !== this.noEntryText;
if (doesNotHaveNoEntry) {
record = Ext.create(this.store.model);
record.set(this.displayField, this.noEntryText);
record.set(this.valueField, null);
this.store.insert(1, record);
}*/
},
listeners: {
//ready: this._onSevComboBoxLoad,
select: this._onSevComboBoxSelect,
scope: this
}
});
var button = this.down('#goButton');
button.on('click', this.goClicked, this);
this.down('#SevFilter').add({
xtype: 'rallyreleasecombobox',
//multiSelect: true,
itemId: 'priorityComboBox',
fieldLabel: 'Release Start:',
model: 'release',
width: 400,
valueField: 'ReleaseStartDate',
displayField: 'Name',
// multiSelect: true,
//field: 'Name',
_removeFunction: function(){
console.log("this.store");
},
listeners: {
//select: this._onSelect,
select: this._onFirstReleaseSelect,
scope: this
}
});
this.down('#SevFilter').add({
xtype: 'rallyreleasecombobox',
itemId: 'priorityComboBox2',
fieldLabel: 'Release End:',
model: 'release',
//multiSelect: true,
stateId: 'rally.technicalservices.trend.defect.release',
stateful: true,
stateEvents: ['change'],
width: 400,
valueField: 'ReleaseDate',
displayField: 'Name',
listeners: {
change: function(box) {
var start_date = this.down('#priorityComboBox2').getDisplayField();
this.logger.log(start_date);
},
ready: this._removeFutureReleases,
select: this._onSecondReleaseSelect,
// ready: this._onLoad,
scope: this
},
});
},
In javascript you may use localstorage.
Here is an app example that retains State and Release selections in respective compboboxes when page is refreshed:
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
items: [
{html:'Select a Filter checkbox to filter the grid'},
{
xtype: 'container',
itemId: 'StateFilter'
},
{
xtype: 'container',
itemId: 'ReleaseFilter'
}
],
launch: function() {
document.body.style.cursor='default';
this._createFilterBox('State');
this._createFilterBox('Release');
},
_createFilterBox: function(property){
this.down('#'+property+'Filter').add({
xtype: 'checkbox',
cls: 'filter',
boxLabel: 'Filter table by '+property,
id: property+'Checkbox',
scope: this,
handler: this._setStorage
});
this.down('#'+property+'Filter').add({
xtype: 'rallyattributecombobox',
cls: 'filter',
id: property+'Combobox',
model: 'Defect',
field: property,
value: localStorage.getItem(property+'Filtervalue'), //setting default value
listeners: {
select: this._setStorage,
ready: this._setStorage,
scope: this
}
});
},
_setStorage: function() {
localStorage.setItem('StateFiltervalue',Ext.getCmp('StateCombobox').getValue());
localStorage.setItem('ReleaseFiltervalue',Ext.getCmp('ReleaseCombobox').getValue());
console.log('localStorage State: ', localStorage.StateFiltervalue,', localStorage Release:', localStorage.ReleaseFiltervalue);
this._getFilter();
},
_getFilter: function() {
var filter = Ext.create('Rally.data.wsapi.Filter',{property: 'Requirement', operator: '=', value: 'null'});
filter=this._checkFilterStatus('State',filter);
filter=this._checkFilterStatus('Release',filter);
if (this._myGrid === undefined) {
this._makeGrid(filter);
}
else{
this._myGrid.store.clearFilter(true);
this._myGrid.store.filter(filter);
}
},
_checkFilterStatus: function(property,filter){
if (Ext.getCmp(property+'Checkbox').getValue()) {
var filterString=Ext.getCmp(property+'Combobox').getValue()+'';
var filterArr=filterString.split(',');
var propertyFilter=Ext.create('Rally.data.wsapi.Filter',{property: property, operator: '=', value: filterArr[0]});
var i=1;
while (i < filterArr.length){
propertyFilter=propertyFilter.or({
property: property,
operator: '=',
value: filterArr[i]
});
i++;
}
filter=filter.and(propertyFilter);
}
return filter;
},
_makeGrid:function(filter){
this._myGrid = Ext.create('Rally.ui.grid.Grid', {
itemId:'defects-grid',
columnCfgs: [
'FormattedID',
'Name',
'State',
'Release'
],
context: this.getContext(),
storeConfig: {
model: 'defect',
context: this.context.getDataContext(),
filters: filter
}
});
this.add(this._myGrid);
}
});
The source is available here.
You could use Sencha localstorage proxy. This way you can keep consistency in your project and use a localstorage based store across all your code.
You can use stateful and stateId configurations to enable last selection. Here is an example of my code. Here what I am doing is to create a custom combobox that will show two options: Platform and program. Then for stateId, you can use any string that you want:
_createCategoryFilter: function()
{
// The data store containing the list of states
var platformTypeList = Ext.create('Ext.data.Store',
{
fields: ['abbr', 'name'],
data : [
{"abbr":"PLAN", "name":"Platform"},
{"abbr":"CURR", "name":"Program"},
//...
]
});
// Create the combo box, attached to the states data store
var platformTypeFilter = Ext.create('Ext.form.ComboBox',
{
fieldLabel: 'Select category',
store: platformTypeList,
queryMode: 'local',
displayField: 'name',
valueField: 'abbr',
stateful: true,
stateId: 'categoryFilter',
listeners:
{
afterrender: function(param)
{
console.log('afterrender - category param is', param.rawValue);
CategoryFilterValue = param.rawValue;
LoadInformation();
},
select: function(param)
{
console.log('select - category param is', param.rawValue);
CategoryFilterValue = param.rawValue;
},
scope: this,
}
});
this.add(platformTypeFilter);
},

ExtJS - using a custom TriggerField as a GridEditor

So I posted this last week to the ExtJS forums, but no one has responded and I'm going a bit crazy trying to figure it out:
I'm fairly new to ExtJS (just learned it last week for work), but I've been working with other JavaScript libraries for quite some time now. I'm making a custom control for editing a list of attributes (currently populated by a JSON request). I'm using PropertyGrid's with custom GridEditor's (created by extending various Ext.form fields). All of my custom fields work except one, which is a repeating value editor. Basically the field is going to be passed a simple 2d key/value pair array by the JSON request, which it displays in an EditorGridPanel (inside of a Ext.Window that I've created).
Here is the section of the JSON request that defines the repeating value editor:
{
key: 'Repeating',
type: 'repeating',
category: 'Category A',
options: {
dataArray: [
{key: 'key A', value: 'value A'},
{key: 'key B', value: 'value B'},
{key: 'key C', value: 'value C'}
]
}
}
The key is the name for the field (displayed on the left column of the PropertyGrid).
The type tells the function which creates all of the grid editors what type of custom editor to use.
The category is used to determine which PropertyGrid the GridEditor is added to (I have multiple PropertyGird's, all contained in a Panel with layout: 'acordion').
Anything in options is added to the extended Ext.form field when it is created.
So dataArray is attached to my repeating value editor for setting up the initial key/value pairs and to store the array passed back to the GridEditor by the Ext.Window used for editing it.
After some experimenting I decided to use a TriggerField as the GridEditor for my repeating value type. Here is the code for the definition of the repeating value field:
Ext.form.customFields = {
'repeating': Ext.extend(Ext.form.TriggerField, {
triggerClass: 'x-form-edit-trigger',
enableKeyEvents: true
})
};
And here is the code that sets it up:
Ext.form.customFields['repeating'] = Ext.extend(Ext.form.customFields['repeating'], {
onTriggerClick: function()
{
this.editorWindow.show();
},
listeners: {
'render': function(field)
{
field.editorWindow = new Ext.MultiSelectWindow({
data: field.dataArray,
parent: field
});
},
'keydown': function(field, event)
{
event.stopEvent();
},
'beforerender': function()
{
for (i in this.opt) {
if (i != 'store') {
this[i] = this.opt[i];
}
else {
this.store.loadData(this.opt.store);
}
}
if (this.regex != undefined) {
this.validator = function(value)
{
return this.regex.test(value);
};
}
}
}
});
And finally, here is the code for the custom editor window:
Ext.MultiSelectWindow = function(args)
{
var obj = this;
obj.args = args;
obj.KeyValue = new Ext.data.Record.create([{
name: 'key'
}, {
name: 'value'
}]);
obj.gridStore = new Ext.data.Store({
data: obj.args.data,
reader: new Ext.data.JsonReader({}, obj.KeyValue),
autoLoad: true
});
obj.cm = new Ext.grid.ColumnModel([{
id: 'key',
header: "Key",
dataIndex: 'key',
editor: new Ext.form.TextField({
allowBlank: false
}),
hideable: false,
sortable: false,
menuDisabled: true,
css: 'font-weight: bold;'
}, {
id: 'value',
header: "Value",
dataIndex: 'value',
editor: new Ext.form.TextField({}),
hideable: false,
sortable: false,
menuDisabled: true
}]);
obj.gridEditor = new Ext.grid.EditorGridPanel({
cm: obj.cm,
height: 280,
store: obj.gridStore,
autoExpandColumn: 'value',
listeners: {
'render': function()
{
// set up local aliases
obj.a = new Array();
obj.a.grid = obj.gridEditor;
obj.a.store = obj.a.grid.getStore();
obj.a.sel = obj.a.grid.getSelectionModel();
}
},
bbar: [{
text: 'Add',
cls: 'x-btn-text-icon',
icon: '/lib/images/add.png',
listeners: {
'click': function()
{
var kv = new obj.KeyValue({
key: '',
value: ''
});
var row = obj.a.store.data.items.length;
obj.a.grid.stopEditing();
obj.a.store.insert(row, kv);
obj.a.grid.startEditing(row, 0);
}
}
}, {
text: 'Delete',
cls: 'x-btn-text-icon',
icon: '/lib/images/delete.png',
listeners: {
'click': function()
{
if (obj.a.sel.selection)
obj.a.store.remove(obj.a.sel.selection.record);
}
}
}]
});
obj.panelAll = new Ext.Panel({
border: false,
layout: 'absolute',
items: [new Ext.Panel({
width: 250,
border: false,
x: 0,
y: 0,
items: obj.gridEditor
}), new Ext.Panel({
border: false,
x: 254,
y: 0,
items: [new Ext.Button({
cls: 'x-btn-icon-side',
icon: '/lib/images/arrow_up.png',
listeners: {
'click': function()
{
if (obj.a.sel.selection) {
var row = obj.a.sel.selection.cell[0];
var rec = obj.a.store.getAt(row);
if (row >= 1) {
obj.a.store.remove(rec);
obj.a.store.insert(row - 1, rec);
obj.a.grid.startEditing(row - 1, 0);
}
}
}
}
}), new Ext.Button({
cls: 'x-btn-icon-side',
icon: '/lib/images/arrow_down.png',
listeners: {
'click': function()
{
if (obj.a.sel.selection) {
var row = obj.a.sel.selection.cell[0];
var rec = obj.a.store.getAt(row);
var len = obj.a.store.data.items.length;
if (row < len - 1) {
obj.a.store.remove(rec);
obj.a.store.insert(row + 1, rec);
obj.a.grid.startEditing(row + 1, 0);
}
}
}
}
})]
})]
});
obj.win = new Ext.Window({
title: 'Repeating Value Editor',
layout: 'fit',
closeAction: 'hide',
border: false,
items: obj.panelAll,
width: 300,
height: 350,
resizable: false,
shadow: false,
buttonAlign: 'left',
buttons: [{
text: 'OK',
handler: function()
{
// reset the repeating field data array
obj.args.parent.dataArray = [];
for (r in obj.a.store.data.items)
obj.args.parent.dataArray[r] = obj.a.store.data.items[r].data;
obj.args.parent.setRawValue(attrValueToString(obj.args.parent.dataArray));
obj.win.hide();
}
}, {
text: 'Cancel',
handler: function()
{
obj.win.hide();
}
}]
});
obj.show = function()
{
obj.win.show();
obj.a.store.loadData(obj.args.parent.dataArray);
}
}
Now for my problem: all of this works fine, except for the 7th line of the window's 'OK' button handler ( obj.args.parent.setRawValue(attrValueToString(obj.args.parent.dataArray)); ).
obj is a self-alias.
obj.args.parent is an alias for the field that opened the repeating value editor window.
attrValueToString() is a function that takes in a 2d array and converts it to a string with special formatting so it can be displayed in a readable, meaningful manner in the TriggerField's textbox.
The data is loaded back into the field's dataArray variable and if you open the editor again, it will have the new data included in the view. I can't, however, manage to get any sort of value to be displayed in the TriggerField after it has been created. I have tried both obj.args.parent.setValue('abc') and obj.args.parent.setRawValue('abc') . No exception is thrown, yet the value displayed in the TriggerField does not change. I even tried creating a custom function for setting the value from within the TriggerField - something like this:
Ext.form.customFields['repeating'] = Ext.extend(Ext.form.customFields['repeating'], {
setFieldValue: function(value){
this.setValue(value);
}
});
This custom function works if called from within the TriggerField, but not when called from somewhere else (i.e. the editor window's 'OK' button handler). The function can be called successfuly from anywhere and does not produce any exceptions, however, it only sets the value correctly if called from within the TriggerField.
The custom field works perfectly when instantiated as a basic form field:
var sample = new Ext.form.customFields['repeating']({
renderTo: Ext.getBody(),
dataArray: [
{key: 'key A', value: 'value A'},
{key: 'key B', value: 'value B'},
{key: 'key C', value: 'value C'}
]
});
I have scoured the ExtJS API documentation and done every possible google search I can think of. I found a few forum posts that seem to be from people having a similar problem, but they never get a clear answer.
Any help with this matter would be most appreciated - thanks in advance!
I think you should use Ext.override for onTriggerClick handler function instead of redefining it in your superclass.
You also could set it right after triggerField creation (possibly in the 'render' event handler) by assigning it to a function name, i.e. trigger.onTriggerClick = somefunction.

Categories