[英]EXT 4.2 ComboBox grouping of results with XTemplate
我試圖將我從商店獲得的結果分組,以便在ComboBox中顯示。 我有一個看起來像這樣的組合框:
我需要它看起來像這樣:
這意味着按類別(訂單/發票)分組。
我的組合框定義如下:
Ext.define('NG.view.searchcombo.Combo', {
requires: ['Ext.form.field.ComboBox'],
extend: 'Ext.form.ComboBox',
alias: 'widget.searchcombo',
minChars:3,
fieldLabel: 'Choose Search',
store: 'Search',
displayField: 'name',
valueField: 'id',
typeAhead: false,
hideLabel: true,
hideTrigger:false,
anchor: '100%',
listConfig: {
loadingText: 'Searching...',
emptyText: 'No matching posts found.',
// Custom rendering template for each item
getInnerTpl: function() {
return '<h3>{name} / {category}</h3>' +'{excerpt}' ;
}
},
pageSize: 10,
initComponent: function () {
this.callParent(arguments);
}
});
我的數據是這樣的:
[{
"id": 1,
"name": "one",
"category": "invoice"
}, {
"id": 2,
"name": "two",
"category": "invoice"
}, {
"id": 3,
"name": "one",
"category": "order"
}, {
"id": 4,
"name": "two",
"category": "order"
}, {
"id": 5,
"name": "three",
"category": "invoice"
}, {
"id": 6,
"name": "four",
"category": "invoice"
}, {
"id": 7,
"name": "three",
"category": "order"
}, {
"id": 8,
"name": "four",
"category": "order"
}, {
"id": 9,
"name": "five",
"category": "invoice"
}, {
"id": 10,
"name": "six",
"category": "invoice"
}, {
"id": 11,
"name": "five",
"category": "order"
}, {
"id": 12,
"name": "six",
"category": "order"
}, {
"id": 13,
"name": "seven",
"category": "invoice"
}, {
"id": 14,
"name": "eight",
"category": "invoice"
}, {
"id": 15,
"name": "seven",
"category": "order"
}, {
"id": 16,
"name": "eight",
"category": "order"
}]
我認為可以通過使用Ext.XTemplate
來完成,但我不熟悉Ext.XTemplate
。
我想要一個更簡單的解決方案,所以我將分享我的想法。
為了我的目的,我有一個我想要分組的key
,這是一個單個字符。 我知道我想要為每個鍵顯示的標題,所以我預先對列表進行排序以確保類型組合在一起,然后我只是在每次看到新鍵時呈現組標題。
myStore.sort('key', 'DESC');
Ext.create('Ext.form.field.ComboBox', {
store: myStore,
queryMode: 'local',
displayField: 'name',
valueField: 'id',
listConfig: {
cls: 'grouped-list'
},
tpl: Ext.create('Ext.XTemplate',
'{[this.currentKey = null]}' +
'<tpl for=".">',
'<tpl if="this.shouldShowHeader(key)">' +
'<div class="group-header">{[this.showHeader(values.key)]}</div>' +
'</tpl>' +
'<div class="x-boundlist-item">{name}</div>',
'</tpl>',
{
shouldShowHeader: function(key){
return this.currentKey != key;
},
showHeader: function(key){
this.currentKey = key;
switch (key) {
case 's': return 'Structures';
case 'f': return 'Filters';
...
}
return 'Other';
}
}
)
});
使用以下CSS:
.grouped-list .x-boundlist-item {
padding: 1px 3px 0 10px
}
.grouped-list .group-header {
padding: 4px;
font-weight: bold;
border-bottom: 1px solid #ddd;
}
這個數據:
[
{ key: 's', name: '2014 Product Development' },
{ key: 'f', name: 'Message Filter' },
{ key: 's', name: '2014 Product Development (Little)' },
{ key: 's', name: 'Global Structure' },
{ key: 'f', name: 'My SW' }
]
我得到一個漂亮的分組列表,如下所示:
這是一個擴展,通過從他的代碼中創建一個可重用的組件來改進Sean Adkinson的回答。
我有一個混合的結果,用一個帶有Ext 5.0.1的GridPanel替換BoundList,這就是我使用的。
有一點需要注意,它不支持折疊群體,但它對我來說很有用。
在Extjs 4.2.3和5.0.1中測試過。
你可以在Sencha 小提琴中看到它
希望它可以幫助那里的人。
Ext.define('Ext.ux.GroupComboBox', { extend: 'Ext.form.field.ComboBox', alias: 'widget.groupcombobox', /* * @cfg groupField String value of field to groupBy, set this to any field in your model */ groupField: 'group', listConfig: { cls: 'grouped-list' }, initComponent: function() { var me = this; me.tpl = new Ext.XTemplate([ '{%this.currentGroup = null%}', '<tpl for=".">', ' <tpl if="this.shouldShowHeader(' + me.groupField + ')">', ' <div class="group-header">{[this.showHeader(values.' + me.groupField + ')]}</div>', ' </tpl>', ' <div class="x-boundlist-item">{' + me.displayField + '}</div>', '</tpl>', { shouldShowHeader: function(group) { return this.currentGroup != group; }, showHeader: function(group) { this.currentGroup = group; return group; } } ]); me.callParent(arguments); } }); //Example usage var Restaurants = Ext.create('Ext.data.Store', { storeId: 'restaraunts', fields: ['name', 'cuisine'], sorters: ['cuisine', 'name'], groupField: 'cuisine', data: [{ name: 'Cheesecake Factory', cuisine: 'American' }, { name: 'University Cafe', cuisine: 'American' }, { name: 'Creamery', cuisine: 'American' }, { name: 'Old Pro', cuisine: 'American' }, { name: 'Nola\\'s', cuisine: 'Cajun' }, { name: 'House of Bagels', cuisine: 'Bagels' }, { name: 'The Prolific Oven', cuisine: 'Sandwiches' }, { name: 'La Strada', cuisine: 'Italian' }, { name: 'Buca di Beppo', cuisine: 'Italian' }, { name: 'Pasta?', cuisine: 'Italian' }, { name: 'Madame Tam', cuisine: 'Asian' }, { name: 'Sprout Cafe', cuisine: 'Salad' }, { name: 'Pluto\\'s', cuisine: 'Salad' }, { name: 'Junoon', cuisine: 'Indian' }, { name: 'Bistro Maxine', cuisine: 'French' }, { name: 'Three Seasons', cuisine: 'Vietnamese' }, { name: 'Sancho\\'s Taquira', cuisine: 'Mexican' }, { name: 'Reposado', cuisine: 'Mexican' }, { name: 'Siam Royal', cuisine: 'Thai' }, { name: 'Krung Siam', cuisine: 'Thai' }, { name: 'Thaiphoon', cuisine: 'Thai' }, { name: 'Tamarine', cuisine: 'Vietnamese' }, { name: 'Joya', cuisine: 'Tapas' }, { name: 'Jing Jing', cuisine: 'Chinese' }, { name: 'Patxi\\'s Pizza', cuisine: 'Pizza' }, { name: 'Evvia Estiatorio', cuisine: 'Mediterranean' }, { name: 'Gyros-Gyros', cuisine: 'Mediterranean' }, { name: 'Mango Caribbean Cafe', cuisine: 'Caribbean' }, { name: 'Coconuts Caribbean Restaurant & Bar', cuisine: 'Caribbean' }, { name: 'Rose & Crown', cuisine: 'English' }, { name: 'Baklava', cuisine: 'Mediterranean' }, { name: 'Mandarin Gourmet', cuisine: 'Chinese' }, { name: 'Bangkok Cuisine', cuisine: 'Thai' }, { name: 'Darbar Indian Cuisine', cuisine: 'Indian' }, { name: 'Mantra', cuisine: 'Indian' }, { name: 'Janta', cuisine: 'Indian' }, { name: 'Starbucks', cuisine: 'Coffee' }, { name: 'Peet\\'s Coffee', cuisine: 'Coffee' }, { name: 'Coupa Cafe', cuisine: 'Coffee' }, { name: 'Lytton Coffee Company', cuisine: 'Coffee' }, { name: 'Il Fornaio', cuisine: 'Italian' }, { name: 'Lavanda', cuisine: 'Mediterranean' }, { name: 'MacArthur Park', cuisine: 'American' }, { name: 'St Michael\\'s Alley', cuisine: 'Californian' }, { name: 'Cafe Renzo', cuisine: 'Italian' }, { name: 'Miyake', cuisine: 'Sushi' }, { name: 'Sushi Tomo', cuisine: 'Sushi' }, { name: 'Kanpai', cuisine: 'Sushi' }, { name: 'Pizza My Heart', cuisine: 'Pizza' }, { name: 'New York Pizza', cuisine: 'Pizza' }, { name: 'Loving Hut', cuisine: 'Vegan' }, { name: 'Garden Fresh', cuisine: 'Vegan' }, { name: 'Cafe Epi', cuisine: 'French' }, { name: 'Tai Pan', cuisine: 'Chinese' }] }); Ext.create('Ext.container.Viewport', { items: Ext.create('Ext.ux.GroupComboBox', { fieldLabel: 'Restaurants', name: 'txtRestaurant', forceSelection: true, editable: false, queryMode: 'local', triggerAction: 'all', multiSelect: true, groupField: 'cuisine', displayField: 'name', valueField: 'name', store: Restaurants, width: 400 }) }).show();
.grouped-list .x-boundlist-item { padding: 1px 3px 0 10px; } .grouped-list .group-header { padding: 4px; font-weight: bold; border-bottom: 1px solid #ddd; }
請使用網格來渲染你的組合框內容。 請參閱這篇文章: http : //www.sencha.com/forum/showthread.php? 132328-CLOSED-ComboBox-using-Grid-instead-of- BoundList
在文章之后,我能夠創建:
這是為我工作的代碼:
如果您使用的是Sencha Architect,請在Override中添加createPicker,並手動將listConfig創建為Object。
{
xtype: 'combobox',
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,
displayField: me.displayField,
focusOnToFront: false,
pageSize: me.pageSize
}, me.listConfig, me.defaultListConfig);
// NOTE: we simply use a grid panel
//picker = me.picker = Ext.create('Ext.view.BoundList', opts);
picker = me.picker = Ext.create('Ext.grid.Panel', opts);
// hack: pass getNode() to the view
picker.getNode = function() {
picker.getView().getNode(arguments);
};
me.mon(picker.getView(), {
refresh: me.onListRefresh,
scope: me
});
me.mon(picker, {
itemclick: me.onItemClick,
// refresh: me.onListRefresh,
scope: me
});
me.mon(picker.getSelectionModel(), {
selectionChange: me.onListSelectionChange,
scope: me
});
return picker;
},
listConfig: {
columns: [{
xtype: "gridcolumn",
dataIndex: "id",
text: "Id"
}, {
xtype: "gridcolumn",
dataIndex: "name",
text: "Name"
}],
features: [{
ftype: "grouping"
}]
},
fieldLabel: 'Label',
queryMode: 'local',
store: 'myTestStore'
}
我已經使用網格作為列表組件實現了我自己的組合版本。 你可以在GitHub上得到它,我在網上做了一些例子 。
第三個例子與你想要達到的目標非常匹配。
這是一個更緊密匹配的例子。 你只能留下造型:
Ext.widget('gridpicker', {
queryMode: 'local'
,displayField: 'name'
,store: {
fields: ['name', 'group']
,proxy: {type: 'memory', reader: 'array'}
,data: ...
,groupField: 'group'
,sorters: {property: 'name', order: 'ASC'}
}
,gridConfig: {
features: [{
ftype:'grouping'
,groupHeaderTpl: '{name}'
,collapsible: false
}]
,columns: [{
width: 30
,renderer: function(value, md, record, rowIndex) {
return '<img src="..." />';
}
},{
dataIndex: 'name'
,flex: 1
}]
}
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.