Отрисовка предлагаемых значений из расширенного поля со списком в элемент DOM.
-
09-06-2019 - |
Вопрос
У меня есть расширенный список, который использует хранилище, чтобы предлагать значения пользователю по мере его ввода.
Пример которого можно найти здесь: пример выпадающего списка
Есть ли способ сделать так, чтобы предлагаемый список текстов отображается в элементе в DOM.Обратите внимание, что я не имею в виду параметр конфигурации «applyTo», поскольку при этом весь элемент управления, включая текстовое поле, будет отображаться в элементе DOM.
Решение
Для этого вы можете использовать плагин, поскольку вы можете вызывать или даже переопределять частные методы изнутри плагина:
var suggested_text_plugin = {
init: function(o) {
o.onTypeAhead = function() {
// Original code from the sources goes here:
if(this.store.getCount() > 0){
var r = this.store.getAt(0);
var newValue = r.data[this.displayField];
var len = newValue.length;
var selStart = this.getRawValue().length;
if(selStart != len){
this.setRawValue(newValue);
this.selectText(selStart, newValue.length);
}
}
// Your code to display newValue in DOM
......myDom.getEl().update(newValue);
};
}
};
// in combobox code:
var cb = new Ext.form.ComboBox({
....
plugins: suggested_text_plugin,
....
});
Я думаю, что можно даже создать целую цепочку методов, вызывая исходный метод до или после вашего, но я этого еще не пробовал.
Также, пожалуйста, не давите на меня за использование нестандартных определений плагинов и методов их вызова (недокументированных).Это просто мой взгляд на вещи.
РЕДАКТИРОВАТЬ:
Я думаю, что цепочку методов можно реализовать примерно так (непроверено):
....
o.origTypeAhead = new Function(this.onTypeAhead.toSource());
// or just
o.origTypeAhead = this.onTypeAhead;
....
o.onTypeAhead = function() {
// Call original
this.origTypeAhead();
// Display value into your DOM element
...myDom....
};
Другие советы
@qui
Еще следует учитывать, что initList не является частью API.Этот метод может исчезнуть или его поведение может существенно измениться в будущих выпусках Ext.Если вы никогда не планируете обновляться, вам не о чем беспокоиться.
Итак, уточните: вы хотите, чтобы выделенный текст отображался где-то помимо непосредственно под текстовым вводом.Правильный?
ComboBox — это просто комбинация Экст.DataView, текстовый ввод и дополнительную кнопку-триггер.Не существует официального варианта того, что вы хотите, и взломать его, чтобы заставить его делать то, что вы хотите, было бы очень болезненно.Итак, самый простой способ действий (кроме поиска и использования какой-либо другой библиотеки с компонентом, который делает именно то, что вы хотите) — создать свою собственную с помощью компонентов, указанных выше:
- Создайте текстовое поле.Вы можете использовать Экст.форма.TextField если хотите, и наблюдайте за событием keyup.
- Создайте DataView, привязанный к вашему магазину, который будет отображать любой элемент DOM, который вы хотите.В зависимости от того, что вы хотите, прослушайте событие «selectionchange» и выполните любое необходимое действие в ответ на выбор.например, setValue для элемента Ext.form.Hidden (или простого HTML-элемента input type="hidden").
- В прослушивателе событий keyup вызовите метод фильтра хранилища (см. док), передавая имя поля и значение из текстового поля.например, store.filter('name',new RegEx(value+'.*'))
Это немного больше работы, но это намного короче, чем написание собственного компонента с нуля или взлом ComboBox, чтобы он вел себя так, как вы хотите.
@Тевс
Я думаю, что вы были на правильном пути.
Я переопределил метод initList Combobox.
Ext.override(Ext.form.ComboBox, {
initList : function(){
Если вы посмотрите на код, вы увидите фрагмент, в котором он отображает список предложений в представлении данных.Поэтому просто установите Apply для нужного элемента dom:
this.view = new Ext.DataView({
//applyTo: this.innerList,
applyTo: "contentbox",
@qui
Хорошо.Я думал, вам нужно дополнительное поле DOM (в дополнение к существующему комбинированному полю).
Но ваше решение переопределит метод в классе ComboBox, не так ли?Это приведет к тому, что все ваши поля со списком будут отображаться в одном и том же DOM.Использование плагина приведет к переопределению только одного конкретного экземпляра.