В данном примере я покажу как создать DataView вместо стандартного Ext.menu.Menu на примере обычной кнопки. Это просто концепт, так что принимайте как есть 🙂
Ext.define('app.view.toolbar.cmp.application.Button', {
extend: 'Ext.button.Button',
requires: [
'app.view.toolbar.cmp.application.DataView'
],
initComponent: function () {
this.on('click', this.showDataView, this);
this.callParent();
},
showDataView: function (button, e, eOpt) {
var dataView = this.getApplicationDataView(),
isPointerEvent = !e || e.pointerType;
if (dataView && this.rendered) {
if (this.tooltip && Ext.quickTipsActive && this.getTipAttr() !== 'title') {
Ext.tip.QuickTipManager.getQuickTip().cancelShow(this.el);
}
if (dataView.isVisible()) {
if (isPointerEvent) {
dataView.hide();
} else {
dataView.focus();
}
} else if (!e || this.showEmptyMenu || dataView.getStore().getCount() > 0) {
dataView.autoFocus = !isPointerEvent;
dataView.showBy(this.el, this.menuAlign);
dataView.show();
}
}
return this;
},
getApplicationDataView: function () {
if (!this.applicationDataView) {
var dataViewConfig = Ext.apply({
items: this.items,
hidden: true,
listeners: {
'iconItemClick': {
fn: this.onIconItemClick,
scope: this
}
},
}, this.dataViewConfig);
this.applicationDataView = Ext.create('app.view.toolbar.cmp.application.DataView', dataViewConfig);
}
return this.applicationDataView;
},
onIconItemClick: function(record, item) {
this.fireEvent('iconitemclick', this, record, item);
},
handler: Ext.emptyFn
});
Ext.define('app.view.toolbar.cmp.application.DataView', {
extend: 'Ext.view.View',
floating: true,
numbderOfColumns: 3,
scrollable: true,
cls: Ext.baseCSSPrefix + 'panel-body-default',
itemSelector: 'div.thumb-wrap',
initComponent: function () {
this.tpl = this.createXTempalte();
this.store = this.createStore();
this.initEvents();
this.callParent();
},
initEvents: function() {
this.on('itemclick', this.onIconItemClick, this);
this.on('blur', this.onBlur, this);
},
onIconItemClick: function(dataView, record, item, index, e, eOpt) {
this.fireEvent('iconItemClick', record, item);
this.hide();
e.stopEvent();
},
onBlur: function(cmp, e, eOpt) {
this.hide();
},
createXTempalte: function() {
var me = this;
var xTemplate = new Ext.XTemplate(
'<table>',
'<tpl for=".">',
'<tpl if="this.showOpenTr(xindex)">',
'<tr>',
'</tpl>',
'<td style="padding: 10px; text-align: center;" >',
'<div style="cursor: pointer;" class="thumb-wrap">',
'<span style="font-family: {fontFamily}; font-size: {iconSize}; color: {iconColor}">&#{uniCode};</span>',
'<br/><span style="">{text}</span>',
'</div>',
'</td>',
'<tpl if="this.showCloseTr(xindex, xcount)">',
'</tr>',
'</tpl>',
'</tpl>',
'</table>',
{
showOpenTr: function(xIndex) {
return xIndex === 0 && xIndex % me.numbderOfColumns === 0;
},
showCloseTr: function(xIndex, xCount) {
return xIndex === xCount || xIndex % me.numbderOfColumns === 0;
}
}
);
return xTemplate;
},
createStore: function () {
var store = Ext.create('Ext.data.Store', {
fields: [
'text',
'uniCode',
'fontFamily',
'iconSize',
'iconColor'
]
}), items = [], unicode, fontFamily;
if(this.items && Ext.isObject(this.items) && Ext.isArray(this.items.items)) {
this.items.defaults = this.items.defaults || {};
Ext.Array.each(this.items.items, function(item, index) {
items.push(Ext.apply(item, this.items.defaults));
}, this);
} else {
items = this.items;
}
Ext.Array.each(items, function(item) {
[unicode, fontFamily] = item.glyph.split('@');
store.add({
text: item.text,
uniCode: unicode,
fontFamily: fontFamily,
iconSize: item.iconSize,
iconColor: item.iconColor,
glyph: item.glyph,
handler: item.handler || false,
scope: item.scope
});
});
return store;
},
setOwnerCmp: function (comp, instanced) {},
getCount() {
return this.getStore().getCount();
}
});
Fiddle: