В некоторых случаях пользователям приходится вставлять специальные символы, например, знаки перегласовки немецкого алфавита или символы, такие как знак «°C». Для этого я создал плагин. Он вставляет триггер в поле, которое создает окно с выбором специальных символав. Реализация состоит из двух файлов, самого плагина и всплывающего окна.
Ext.define('app.ux.form.field.VirtualKeyboard', {
extend: 'Ext.plugin.Abstract',
alias: 'plugin.virtualkeyboard',
requires: [
'app.ux.form.field.VirtualKeyboardPanel'
],
triggerTooltip: "Additional Symbols",
triggerGlyph: 'xf1ab@FontAwesome',
pickerTitle: "Symbols",
pickerHeight: 200,
numberOfColumns: 5,
symbols: [],
init: function (field) {
this.field = field;
var triggers = field.getTriggers();
triggers.virtualKeyboard = {
glyph: this.triggerGlyph,
tooltip: this.triggerTooltip,
handler: this.openPicker,
scope: this
};
field.setTriggers(triggers);
},
openPicker: function () {
this.getPicker().show();
},
getPicker: function () {
if (!this.picker) {
this.picker = this.createPicker();
}
return this.picker;
},
createPicker: function () {
var picker,
pickerCfg;
pickerCfg = Ext.apply({
xtype: 'window',
id: this.field.id + '-symbolContainer',
title: this.pickerTitle,
pickerField: this,
height: this.pickerHeight,
layout: 'fit',
closeAction: 'hide',
items: [{
xtype: 'app_ux_form_field_VirtualKeyboardPanel',
numberOfColumns: this.numberOfColumns,
symbols: this.symbols,
listeners: {
'SymbolClick': {
fn: this.onSymbolClick,
scope: this
}
}
}]
});
picker = Ext.widget(pickerCfg);
return picker;
},
onSymbolClick: function (symbol) {
var fieldValue = this.field.getValue();
fieldValue += symbol;
this.field.setValue(fieldValue);
this.getPicker().hide();
},
onEsc: function () {
this.getPicker().hide();
}
});
Ext.define('app.ux.form.field.VirtualKeyboardPanel', {
extend: 'Ext.view.View',
alias: 'widget.app_ux_form_field_VirtualKeyboardPanel',
scrollable: true,
border: false,
symbols: [],
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.onSymbolClick, this);
this.on('blur', this.onBlur, this);
},
onSymbolClick: function(dataView, record, item, index, e, eOpt) {
this.fireEvent('SymbolClick', record.get('symbol'));
e.stopEvent();
},
onBlur: function(cmp, e, eOpt) {
this.hide();
},
getSymbols: function() {
var symbols = [];
if(Ext.isArray(this.symbols)) {
symbols = this.symbols;
} else if(Ext.isFunction(this.symbols)) {
symbols = this.symbols()
}
return symbols;
},
createXTempalte: function() {
var me = this;
var xTemplate = new Ext.XTemplate(
'<table>',
'<tpl for=".">',
'<tpl if="this.showOpenTr(xindex)">',
'<tr>',
'</tpl>',
'<td style="background-color: #cccccc; text-align: center;" >',
'<div style="cursor: pointer;" class="thumb-wrap">',
'<span style="font-size: 40px;">{symbol}</span>',
'</div>',
'</td>',
'<tpl if="this.showCloseTr(xindex, xcount)">',
'</tr>',
'</tpl>',
'</tpl>',
'</table>',
{
showOpenTr: function(xIndex) {
return xIndex === 0 && xIndex % me.numberOfColumns === 0;
},
showCloseTr: function(xIndex, xCount) {
return xIndex === xCount || xIndex % me.numberOfColumns === 0;
}
}
);
return xTemplate;
},
createStore: function () {
var store = Ext.create('Ext.data.Store', {
fields: [
'symbol'
]
});
Ext.Array.each(this.getSymbols(), function(symbol) {
store.add({
'symbol': symbol
})
}, this);
return store;
}
});
Специальные символы могут быть заданы с помощью массива или функции.
plugins: {
virtualkeyboard: {
pickerTitle: "Polish chars",
symbols: ['Ą', 'Ć', 'Ę', 'Ł', 'Ń', 'Ó', 'Ś', 'Ź', 'Ż'],
numberOfColumns: 3
}
}
plugins: {
virtualkeyboard: {
pickerTitle: "Chinese Сharacters",
symbols: function() {
var cJKUnifiedIdeographs = [];
for(var i=19968; i<20000; i++) {
cJKUnifiedIdeographs.push(String.fromCharCode(i));
}
return cJKUnifiedIdeographs;
}
}
}
Fiddle: