У меня довольно простая проблема, решение которой оказывается не таким простым.
Я хочу добавить изображения перед каждой опцией selectfield
. Чтобы быть более точным, я хочу добавить изображения в триггеры picker
, а также текущее значение selectfield.
Для простоты я создам небольшой пример:
Скажем, вы хотите, чтобы пользователь выбирал один из четырех игровых карточек: Diamonds, Hearts, Spades и Clubs. Чтобы поддерживать визуальное распознавание, вы хотите добавить соответствующий символ к каждому имени костюма, чтобы он выглядел примерно так:
Мой первый выбор сенсорного компонента sencha, который позволяет выбирать из заданного набора параметров, естественно, был selectfield
. К сожалению, он, по-видимому, способен отображать чистый текст, и не более того. Покопавшись в источниках сенча, я, наконец, придумал половину решения. В основном, я передаю selectfield
пользовательский defaultPhonePickerConfig
, в котором соответствующему picker
(который используется selectfield
для отображения параметров) присваивается пользовательский itemTpl
. itemTpl
делает все остальное, а именно добавление некоторого html для отображения изображения:
defaultPhonePickerConfig: {
listeners: {
initialize: function() {
var slots = this.query('pickerslot');
Ext.each(slots, function(slot) {
slot.setItemTpl('<img src="someImage.jpg"> {text}');
});
},
change: function() {
// reconstruct the selectfield change handler,
// since it gets overwritten
var iconSelect = Ext.Viewport.query('#IconSelect')[0];
iconSelect.onPickerChange.apply(iconSelect, arguments);
}
}
}
Для этого решения можно найти скрипт здесь.
Мое решение не так уж плохо, но есть небольшая косметическая проблема, которая мне не подходит: значки отображаются только в picker
(нижняя часть скриншота выше), но не selectfield
(верхняя, серая часть), когда была выбрана опция. И, похоже, нет хорошего способа добавить значок к текущему значению selectfield.
И что главная проблема моего вопроса: какой хороший способ добавить значок в как параметры выбора, так и значение текущего значения selecfield? Может быть, мне просто нужно добавить относительно небольшой код в мое существующее решение или я должен использовать целый подход? Каждый вклад приветствуется. Спасибо!
Update:
После некоторого взлома я нашел способ (уродливый), чтобы добавить значок к самому selectfield
. В основном это основано на жестоких манипуляциях HTML DOM: теперь я также определяю обработчики событий для самого selectfield
(change
и painted
). При инициализации и при каждом изменении значения мои обработчики ищут сгенерированную DOM для лежащего в основе <input>
и обходятся с ней. (Этот плохой мальчик, вероятно, является причиной того, что мы не можем назначить HTML в первую очередь, так как каркас меняет свой атрибут value
. И value
, с другой стороны, может содержать только обычный текст.)
Вот как я определяю selectfield
listeners
:
listeners: {
change: function () {
var pickerDOM = document.querySelector('#' + this.getId() + ' input[name="picker"]');
PickerIcons.app.prependIconToSelectfield(arguments[1], pickerDOM);
},
painted: function () {
// Initialize an icon on creation
var pickerDOM = document.querySelector('#' + this.getId() + ' input[name="picker"]');
PickerIcons.app.prependIconToSelectfield(this.getValue(), pickerDOM);
}
}
Соответствующая функция prependIconToSelectfield()
просто определяет некоторый CSS:
prependIconToSelectfield: function (optValue, domElement) {
var iconUrl = this.getIconUrl(optValue);
domElement.style.backgroundImage = 'url(' + iconUrl + ')';
domElement.style.backgroundSize = '20px 20px';
domElement.style.backgroundRepeat = 'no-repeat';
domElement.style.backgroundPosition = 'left center';
domElement.style.paddingLeft = '30px';
}
Просмотрите эту скрипту для рабочего примера.
Это по-прежнему не очень хорошее решение для меня, так как выполнение такого рода хакерских манипуляций с DOM слишком изгоев для моего вкуса. Я не знаю, какие побочные эффекты активного вовлечения в DOM могут быть в больших проектах и не хотят изучать его с трудом. Итак, я все еще ищу более чистое решение.