ExtJS :Pass groupname in grouped combobox tpl dynamically - extjs

I am working on a group combobox where I need to pass group-name dynamically(from its config).
var data = [{
group: 'Fubar',
key: '1',
name: '2015 Product Development'
}, {
group: 'Fubar',
key: '2',
name: 'Message Filter'
}, {
group: 'Fubar',
key: '3',
name: '2014 Product Development (Little)'
}, {
group: 'Other',
key: '4',
name: 'Global Structure'
}, {
group: 'Other',
key: '5',
name: 'My SW'
}];
Ext.apply(combo, {
listConfig: {
tpl = new Ext.create('Ext.XTemplate',
'<tpl for=".">',
'<tpl for="group" if="this.shouldShowHeader(group)"><div class="group-header">{[this.showHeader(values.group)]}</div></tpl>',
'<div class="x-boundlist-item"><input type="checkbox" />{name}</div>',
'</tpl>', {
shouldShowHeader: function(group) {
return this.currentGroup !== group;
},
showHeader: function(group) {
this.currentGroup = group;
return group;
}
});
}
});
var combo = Ext.create('Ext.data.Store', {
fields: ['group', 'key', 'name'],
data: data
});
items: [{
xtype: 'combobox',
id: 'searchInput',
store: combo,
multiSelect: true,
labelWidth: 50,
queryMode: 'local',
displayField: 'name',
fieldLabel: 'Choose',
listConfig: {
cls: 'grouped-list'
},
tpl: tpl,
groupName: 'group'
}]
I have tried with code but not working. It giving group, property itself instead of its value.
<tpl for="combo.groupName" if="this.shouldShowHeader(combo.groupName)">
Here combo is combobox instance being used.

Tpl should be used in this way to get desired output.
'<tpl for=".">',
'<tpl for="' + combo.groupName + '" if="this.shouldShowHeader(' + combo.groupName + ')"><div class="group-header">{[this.showHeader(values.' + combo.groupName + ')]}</div></tpl>',
'<div class="x-boundlist-item"><input type="checkbox" />{name}</div>',
'</tpl>'

Related

Ext Js Combobox displayTpl is shown twice

I'm trien to populate a ExtJS 7.3.1 combobox with key/value from an array.
Then I need to display both (Key and Value) on the combobox and the dropdown like this:
var test_store = new Ext.data.SimpleStore({fields : ['value','text'],data : []});
var testArr = [
['test 1', '1'],
['test 2', '2'],
['test 3', '3'],
['test 4', '4'],
]
var combo = Ext.getCmp('test');
test_store = new Ext.data.SimpleStore({
fields: ['value', 'text'],
data: testArr,
});
Ext.create({
xtype: 'formpanel',
renderTo: document.body,
items: [{
xtype: 'combobox',
id: 'test',
name: 'test',
label: 'test',
store: test_store,
displayField: 'text',
valueField: 'value',
queryMode: 'local',
editable: false,
displayTpl: '{value} - {text}',
itemTpl: '<div data-qalign="b-t" data-qanchor="true" data-qtip="{text}">{value} - {text} </div>',
autocomplete: false,
}]
});
But when I unfocus the combobox after I have selected a new value, it will show the displayTpl twice, am I doing something wrong or do I need to report a bug?
fiddle:
https://fiddle.sencha.com/#view/editor&fiddle/3c6i
I really would only override displayTpl or itemTpl if you know what you're doing. In the case of this, I'd say create a separate field and do the conversion there. Like this
var test_store = new Ext.data.SimpleStore({fields : ['value','text'],data : []});
var testArr = [
['test 1', '1'],
['test 2', '2'],
['test 3', '3'],
['test 4', '4'],
]
var combo = Ext.getCmp('test');
test_store = new Ext.data.SimpleStore({
fields: ['value', 'text', {
name: 'display',
type: 'string',
depends: ['value', 'text'],
convert: function(value, record) {
return `${record.get('value')} - ${record.get('text')}`
}
}],
data: testArr,
});
Ext.create({
xtype: 'formpanel',
renderTo: document.body,
items: [{
xtype: 'combobox',
id: 'test',
name: 'test',
label: 'test',
store: test_store,
displayField: 'display',
valueField: 'value',
queryMode: 'local',
autocomplete: false,
anyMatch: true,
forceSelection: true
}]
});

ExtJS Assigning value to the hidden field

I have the below combobox set to put some records through API call and then display on the page. I need to submit 2 values when user clicks submit, 1) gmiExchangeCode and 2) gmiFuturesCode. The first value works through this form's field, the gmiFuturesCode doesn't work on updating the hidden form field.
}, {
xtype: 'combo',
autoLoad: true,
hideTrigger: true,
fieldLabel: 'Product',
displayField: 'gmiDescription',
valueField: 'gmiExchangeCode',
submitValue: true,
name: 'exchange',
queryMode: 'remote',
queryParam: 'entry',
typeAhead: true,
minChar: 2,
tpl: new Ext.XTemplate('<tpl for="."><div class="x-boundlist-item" style="border-bottom:1px solid #757575;">{gmiExchangeCode} - {lisaMarket} - {gmiFuturesCode} - {gmiDescription}</div></tpl>'),
store: {
fields: ['text', 'value'],
proxy: {
type: 'ajax',
url: 'API',
reader: {
type: 'json'
}
}
},
listeners: {
select: function (combo, record, index) {
hidden.setValue(record.get('gmiFuturesCode'));
}
}
}, {
xtype: 'hidden',
id: 'futures',
name: 'futures'
}, {
There is nothing called "hidden.setValue()" you have to get the object using the query selector or Ext.getCmp('ObjectID')
Here is a working Example Fiddle
Ext.create('Ext.form.Panel', {
title: 'test',
width: 400,
height: 300,
renderTo: Ext.getBody(),
items: [{
xtype: 'combobox',
reference: 'states',
publishes: 'value',
fieldLabel: 'Select State',
displayField: 'displayField',
anchor: '-15',
store: {
fields: ['valueField', 'displayField'],
data: [
['1', 'MyDisplayValueFor1'],
['2', 'MyDisplayValueFor2'],
['3', 'MyDisplayValueFor3']
]
},
minChars: 0,
queryMode: 'local',
typeAhead: true,
listeners: {
select: function (combo, record, index) {
console.log(record.get('displayField'));
Ext.getCmp('futures').setValue(record.get('displayField'));
Ext.Msg.alert('Alert', 'The hidden Field value from the getter is : ' + Ext.getCmp('futures').getValue());
}
}
}, {
xtype: 'hidden',
id: 'futures',
name: 'futures'
}]
})
Try this
Ext.getCmp('futures').setValue(record.get('gmiFuturesCode'));

ExtJS 4: Dynamic store filtering

I have a filter specified in filters config of the store:
Ext.define('Record', {
extend: 'Ext.data.Model',
fields: [{
name: 'value',
type: 'number'
}]
});
Ext.create('Ext.data.Store', {
id: 'store',
model: 'Record',
filters: [
function(item) {
return item.get('value') > 2;
}
],
sorters: [{
property: 'value',
direction: 'DESC'
}],
data: [{
value: 2,
}, {
value: 1
}, {
value: 3
}]
});
Ext.create('Ext.view.View', {
store: Ext.data.StoreManager.lookup('store'),
tpl: new Ext.XTemplate(
'<tpl foreach=".">',
'<div class="record">{value}</div>',
'</tpl>'
),
itemSelector: '.record',
emptyText: 'No records',
renderTo: Ext.getBody()
});
It is only applied if I explicitly call filter() on the store. The filterOnLoad is not set and defaults to true, so the store must be filtered. How can I keep the store always filtered (whenever any CRU action is performed and after load)?
To accomplish this it's needed to add listeners to the store on adding and updating events:
listeners: {
add: function(store) {
store.filter();
},
update: function(store) {
store.filter();
}
},

Date formatting in Store

How to format store data, In my case it is returning date and I am binding it to Comobox
var comboDate = new Ext.form.ComboBox({
displayField: 'date',
valueField: 'date',
store: {
type: 'webapi',
autoLoad: true,
api: {
read: 'api/Report/GetDate'
}
}
});
It is binding it as "Mon May 9 00:00:00 EDT 2016"
I tried few things to resolve it -
dateFormat: 'c'
and
renderer: Utility.Formatting.ShortDateTime
Please suggest me how can we apply Date formatting in Store
UPDATING
Here i am adding the complete code - I am trying to bind date to a combobox in a grid.
header: 'From Date', dataIndex: 'date', editor: comboDate, renderer: comboBoxDateRenderer(comboDate)
var comboBoxDateRenderer = function (comboDate) {
return function (value) {
var idx = comboDate.store.find(comboDate.valueField, value);//Ext.util.Format.date(value, "Y-m-d")
var rec = comboDate.store.getAt(idx);
return (rec === null ? '' : rec.get(comboDate.displayField));
};
}
var comboDate = new Ext.form.ComboBox({
displayField: 'date',
valueField: 'date',
//dateFormat: 'c',
store: {
type: 'webapi',
autoLoad: true,
fields: [
{ name: 'date', type: 'date', dateFormat: 'c' }
],
api: {
read: 'api/Report/GetDate'
}
}
});
The value is a standard date object. You can use XTemplates to format the displayfield: https://fiddle.sencha.com/#fiddle/1a37
List Template:
tpl: Ext.XTemplate(
'<tpl for=".">'+
'<div class="x-boundlist-item">' +
'{[Ext.util.Format.date(values.date, "d/m/y")]}' +
'</div>'+
'</tpl>'
),
Displayfield Template:
displayTpl: Ext.XTemplate(
'<tpl for=".">'+
'{[Ext.util.Format.date(values.date, "d/m/y")]}'+
'</tpl>'
),
Keep in mind that this is only pure formatting the display output.

How to access the view from within dataview's tpl in ExtJS6?

I am trying to test against a combobox value from inside dataview's tpl:
Ext.define('MyForm', {
extend: 'Ext.form.Panel',
items: [
{
xtype: 'combo',
name: 'my_combo',
},
{
xtype: 'dataview',
tpl: new Ext.XTemplate(
'<tpl for=".">',
'<tpl if="this.test()">pass</tpl>',
'</tpl>'
,
{
test: function(){
//doesn't work
return this.getView().down('[name=my_combo]').getValue() == 'ok';
}
}),
}
]
});
This doesn't work because this is referencing to the template itself and I can't figure out how to access the view from the inside.
It is not possible to access a view in XTemplate. To achieve this you can use ViewModel, here is the code for it.
And working sencha fiddle https://fiddle.sencha.com/#fiddle/175s
Update: I updated the code to use the DataView, DataView is little tricky, i overwritten the prepareData method to pass in extra information to the template and also updating the DataView whenever the combo value is changed. Here is the fiddle with updated changes https://fiddle.sencha.com/#fiddle/175s
Ext.define('MyApp.MyPanel', {
extend: 'Ext.Panel',
xtype: 'myForm',
defaults: {
padding: 10
},
viewModel: {
stores: {
employeeStore: {
fields: ['name'],
data: [{
name: 'John'
}, {
name: 'Tempel'
}, {
name: 'George'
}, {
name: 'Milinda'
}]
},
}
},
items: [
{
xtype: 'combobox',
fieldLabel: 'Name',
name: 'nameField',
queryMode: 'local',
displayField: 'name',
valueField: 'name',
reference: 'emp',
bind: {
store: '{employeeStore}',
value: '{name}'
}
},{
xtype: 'dataview',
itemId: 'empList',
tpl: new Ext.XTemplate(
'<tpl for=".">',
'<div class="dataview-multisort-item">',
'<h3>{name}</h3>',
'<tpl if="passed">Selected</tpl>',
'</div>',
'</tpl>'
),
itemSelector: 'div.dataview-multisort-item',
bind: {
store: '{employeeStore}'
},
prepareData: function(data, index, record) {
var name = this.up().getViewModel().get('name');
var passed = record.get('name') == name;
return Ext.apply({passed: passed}, data);
}
}
],
initComponent: function() {
this.callParent(arguments);
var me = this;
// refresh the dataview when name is changed.
this.getViewModel().bind('{name}', function() {
var dataview = me.down('#empList');
dataview.refresh();
});
}
});

Resources