Can anyone help me to do a Grouping Combo?
I'm trying but I'm finding many errors.
Thanks!
Printable View
Can anyone help me to do a Grouping Combo?
I'm trying but I'm finding many errors.
Thanks!
u can try to change combo's picker to a grouping grid.
this may be help:
http://www.sencha.com/forum/showthre...d-of-BoundList
@atian25
Thanks for idea, below my solution:
GroupingList
GroupingComboBoxCode:Ext.define('Ext.ux.view.GroupingList', {
extend: 'Ext.view.View',
alias: 'widget.groupinlist',
requires: ['Ext.layout.component.BoundList', 'Ext.toolbar.Paging'],
pageSize: 0,
autoScroll: true,
baseCls: Ext.baseCSSPrefix + 'boundlist',
listItemCls: '',
shadow: false,
trackOver: true,
refreshed: 0,
ariaRole: 'listbox',
componentLayout: 'boundlist',
renderTpl: ['<div class="list-ct"></div>'],
initComponent: function() {
var me = this,
baseCls = me.baseCls,
itemCls = baseCls + '-item';
me.itemCls = itemCls;
me.selectedItemCls = baseCls + '-selected';
me.overItemCls = baseCls + '-item-over';
me.itemSelector = "." + itemCls;
if (me.floating) {
me.addCls(baseCls + '-floating');
}
var tpl = [
'<ul>',
'<tpl for=".">'
];
var padding = 1;
if (Ext.isArray(me.groupField)) {
padding = me.groupField.length;
for (var i = 0; i < me.groupField.length; i++) {
tpl.push(
'<tpl if="xindex == 1 || parent[xindex - 2][\'' + me.groupField[i] + '\'] != values[\'' + me.groupField[i] + '\']">',
'<li class="x-combo-list-group" style="padding-left:' + (i * 16) + 'px;">{[values["' + me.groupField[i] + '"]]}</li>',
'</tpl>'
);
}
}
else {
tpl.push(
'<tpl if="xindex == 1 || parent[xindex - 2][\'' + me.groupField + '\'] != values[\'' + me.groupField + '\']">',
'<li class="x-combo-list-group">{[values["' + me.groupField + '"]]}</li>',
'</tpl>'
);
}
tpl.push(
'<li role="option" class="' + itemCls + '" style="padding-left:' + (padding * 16) + 'px;">{[values["' + me.displayField + '"]]}</li>',
'</tpl>',
'</ul>'
);
me.tpl = Ext.create('Ext.XTemplate', tpl);
if (me.pageSize) {
me.pagingToolbar = me.createPagingToolbar();
}
me.callParent();
Ext.applyIf(me.renderSelectors, {
listEl: '.list-ct'
});
},
createPagingToolbar: function() {
return Ext.widget('pagingtoolbar', {
pageSize: this.pageSize,
store: this.store,
border: false
});
},
onRender: function() {
var me = this,
toolbar = me.pagingToolbar;
me.callParent(arguments);
if (toolbar) {
toolbar.render(me.el);
}
},
bindStore : function(store, initial) {
var me = this,
toolbar = me.pagingToolbar;
me.callParent(arguments);
if (toolbar) {
toolbar.bindStore(store, initial);
}
},
getTargetEl: function() {
return this.listEl || this.el;
},
getInnerTpl: function(displayField) {
return '{' + displayField + '}';
},
refresh: function() {
var me = this;
me.callParent();
if (me.isVisible()) {
me.refreshed++;
me.doComponentLayout();
me.refreshed--;
}
},
initAria: function() {
this.callParent();
var selModel = this.getSelectionModel(),
mode = selModel.getSelectionMode(),
actionEl = this.getActionEl();
if (mode !== 'SINGLE') {
actionEl.dom.setAttribute('aria-multiselectable', true);
}
},
onDestroy: function() {
Ext.destroyMembers(this, 'pagingToolbar', 'listEl');
this.callParent();
}
});
CSSCode:Ext.define('Ext.ux.form.GroupingComboBox', {
extend: 'Ext.form.field.ComboBox',
requires: ['Ext.ux.view.GroupingList'],
alias: ['widget.groupingcombobox', 'widget.groupingcombo'],
initComponent: function() {
var me = this;
if (!me.displayTpl) {
var display = [],
tpl = '<tpl for=".">{0}</tpl>';
if (Ext.isArray(me.groupField)) {
for (var i = 0; i < me.groupField.length; i++) {
display.push('{[values["' + me.groupField[i] + '"]]}');
}
}
else {
display.push('{[values["' + me.groupField + '"]]}');
}
display.push('{[values["' + me.displayField + '"]]}');
me.displayTpl = Ext.String.format(tpl, display.join(this.displaySeparator || ' '));
}
me.callParent();
},
createPicker: function() {
var me = this,
picker,
menuCls = Ext.baseCSSPrefix + 'menu',
opts = Ext.apply({
selModel: {
mode: me.multiSelect ? 'SIMPLE' : 'SINGLE'
},
floating: true,
hidden: true,
ownerCt: me.ownerCt,
cls: me.el.up('.' + menuCls) ? menuCls : '',
store: me.store,
groupField: me.groupField,
displayField: me.displayField,
focusOnToFront: false,
pageSize: me.pageSize
}, me.listConfig, me.defaultListConfig);
//picker = me.picker = Ext.create('Ext.view.BoundList', opts);
picker = me.picker = Ext.create('Ext.ux.view.GroupingList', opts);
me.mon(picker, {
itemclick: me.onItemClick,
refresh: me.onListRefresh,
scope: me
});
me.mon(picker.getSelectionModel(), 'selectionchange', me.onListSelectionChange, me);
return picker;
}
});
ExampleCode:.x-combo-list-group {
font : bold 12px tahoma,arial,helvetica,sans-serif;
padding : 2px;
border : 1px solid #fff;
white-space : nowrap;
overflow : hidden;
text-overflow : ellipsis;
}
Code:{
anchor: '100%',
fieldLabel: 'My Grouping ComboBox',
xtype: 'groupingcombobox',
name: 'name',
allowBlank: false,
groupField: ['nivel1', 'nivel2'],// string or array
valueField: 'value',
displayField: 'display',
queryMode: 'local',
typeAhead: true,
store: {
fields: [
{ name: 'value', type: 'int' },
{ name: 'nivel1', type: 'string' },
{ name: 'nivel2', type: 'string' },
{ name: 'display', type: 'string' }
],
sorters: [
{ property: 'nivel1', direction: 'ASC' },
{ property: 'nivel2', direction: 'ASC' },
{ property: 'display', direction: 'ASC' }
],
data: [
{ value: 1, nivel1: 'nivel 1', nivel2: 'nivel 1.1', display: 'display 1' },
{ value: 2, nivel1: 'nivel 1', nivel2: 'nivel 1.1', display: 'display 2' },
{ value: 3, nivel1: 'nivel 1', nivel2: 'nivel 1.1', display: 'display 3' },
{ value: 4, nivel1: 'nivel 2', nivel2: 'nivel 2.1', display: 'display 4' },
{ value: 5, nivel1: 'nivel 2', nivel2: 'nivel 2.1', display: 'display 5' },
{ value: 6, nivel1: 'nivel 2', nivel2: 'nivel 2.1', display: 'display 6' },
{ value: 7, nivel1: 'nivel 3', nivel2: 'nivel 3.1', display: 'display 7' },
{ value: 8, nivel1: 'nivel 3', nivel2: 'nivel 3.1', display: 'display 8' },
{ value: 9, nivel1: 'nivel 3', nivel2: 'nivel 3.1', display: 'display 9' }
]
}
}
Thanks for sharing your extension, i needed a combobox with an 'optgroup' like implementation.
However I found a (minor) bug in the code.
Attachment 28210
related code (GroupingList):
As you can see, if the second (or third etc) level group is the same as in the previous item it won't be displayed, however if the parent group is different, it should be.Code:for (var i = 0; i < me.groupField.length; i++) {
tpl.push(
'<tpl if="xindex == 1 || parent[xindex - 2][\'' + me.groupField[i] + '\'] != values[\'' + me.groupField[i] + '\']">',
'<li class="x-combo-list-group" style="padding-left:' + (i * 16) + 'px;">{[values["' + me.groupField[i] + '"]]}</li>',
'</tpl>'
);
}
Here is my solution:
Code:for (var i = 0; i < me.groupField.length; i++) {
var checking = '';
for(var j=i-1;j>=0;j--) {
checking += ' || parent[xindex - 2][\'' + me.groupField[j] + '\'] != values[\'' + me.groupField[j] + '\']';
}
tpl.push(
'<tpl if="xindex == 1 || parent[xindex - 2][\'' + me.groupField[i] + '\'] != values[\'' + me.groupField[i] + '\']'+checking+'">',
'<li class="x-combo-list-group" style="padding-left:' + (i * 16) + 'px;">{[values["' + me.groupField[i] + '"]]}</li>',
'</tpl>'
);
}
Hello,
first i want to say thanks for sharing your extension. Very cool feature.
Unfortunately under 4.1.0 Beta 3 this extension is broken.
I show 2 pictures - the first one is with 4.0.7 and the second one with 4.1.0 Beta 3! This is the only difference.
Attachment 32197Attachment 32198
I have tried to figure the problem out.
Thanks!
Michi
Hello,
has anyone an idea how to solve this?
Any help is useful!
Thanks in advance!
Michi
You can use listConfig.tpl or tpl for simple grouping:
Code:Ext.onReady(function () {
Ext.create('Ext.form.ComboBox', {
fieldLabel: 'Choose City',
store: Ext.create('Ext.data.Store', {
fields: ['country', 'city'],
data: [
{"country": "France", "city": "Paris"},
{"country": "France", "city": "Lion"},
{"country": "France", "city": "Marcel"},
{"country": "Germany", "city": "Berlin"},
{"country": "Germany", "city": "Bonn"},
{"country": "Germany", "city": "Heidelberg"},
{"country": "Russia", "city": "St.Petersburg"},
{"country": "Russia", "city": "Moscow"},
{"country": "Russia", "city": "Novgorod"}
]
}),
queryMode: 'local',
displayField: 'city',
valueField: 'city',
renderTo: Ext.getBody(),
listConfig: {
tpl: Ext.create('Ext.XTemplate',
'<ul><tpl for=".">',
'<tpl if="xindex == 1 || this.getGroupStr(parent[xindex - 2]) != this.getGroupStr(values)">',
'<li class="x-combo-list-group"><b>{[this.getGroupStr(values)]}</b></li>',
'</tpl>',
'<li role="option" class="x-boundlist-item" style="padding-left: 12px">{city}</li>',
'</tpl>' +
'</ul>',
{
getGroupStr: function (values) {
return values.country
}
}
)
}
});
});
Based on this StackOverflow answer, I crufted up the following, which seems to work:
Attachment 42409
Then you can use it with a grouping store and you get something like the screenshot.Code:Ext.define('common.field.GroupingComboBox', {
extend: 'Ext.form.field.ComboBox',
alias: 'widget.common.field.GroupingComboBox',
constructor: function (args) {
var me = this,
groupField = args.groupField || "group",
groupDisplayField = args.groupDisplayField || groupField,
displayField = args.displayField || "name";
args.tpl = new Ext.XTemplate(
'<tpl for=".">',
'<tpl if="this.' + groupField + ' != values.' + groupField + '">',
'<tpl exec="this.' + groupField + ' = values.' + groupField + '"></tpl>',
'<div class="x-panel-header-default x-panel-header-text-container x-panel-header-text x-panel-header-text-default" title="{' + groupDisplayField + '}">{' + groupDisplayField + '}</div>',
'</tpl>',
'<div class="x-boundlist-item">{' + displayField + '}</div>',
'</tpl>'
);
me.callParent(arguments);
}
});