Каскадные комбинированные списки в ExtJS EditorGridPanel - PullRequest
4 голосов
/ 20 октября 2010

У меня есть рабочая панель EditorGrid, в которой два столбца имеют редакторы ComboBox.Оба ComboBox загружаются удаленно из базы данных (countryStore и cityStore).

Я хотел бы ограничить cityComboBox, чтобы показывать только города в выбранной стране.Мне нужно перезагрузить cityStore с фильтром из базы данных (слишком много городов для локальной фильтрации).Значением фильтра является значение countryComboBox.

В countryComboBox всегда есть значение, потому что я добавляю значение по умолчанию = 1 при создании новой записи, поэтому это не проблема.

Я не знаю, какой слушатель будет уместен здесь.Мне нужно уловить момент, когда я дважды щелкну по ячейке страны, до того, как появится countryComboBox, и отфильтрую поле со списком, прежде чем оно отобразится (или отобразит сообщение ожидания при получении данных).невозможно, могу ли я открыть всплывающее окно, дважды щелкнув по ячейке, выбрать из списка со списком отфильтрованные города, «подтвердить» и ввести значение в ячейку?

Ответы [ 2 ]

5 голосов
/ 22 октября 2010

Я наконец заставил это работать.Я создал два решения - для локального и удаленного поиска в выпадающем списке в сетке.В конце концов я решил использовать локальный поиск (я могу добавить country_id к моему cities запросу и фильтру в ExtJS), но возможно сделать это для удаленного поиска - если кому-то это нужно, я могу подготовить этотоже решение.

LOCAL SOLUTION

Мне пришлось отфильтровать cityCombo, используя событие beforeQuery, используя идентификатор из countryCombo в той же строке.Вот код для cityCombo:

var cityCombo = new Ext.form.ComboBox({
    triggerAction: 'all',
    mode: 'local',
    lastQuery: '', // to make sure the filter in the store is not cleared the first time the ComboBox trigger is used
    store: cityDropdownStore,
    displayField: 'city',
    valueField: 'city_id',
    listeners: {
        beforeQuery: function(query) { 
            currentRowId = myGrid.getSelectionModel().getSelected().data.country_id;
            this.store.clearFilter();
            this.store.filter( { property: 'country_id', value: currentRowId, exactMatch: true } );
        }
    }
});

Как видите, когда дважды щелкается cityCombo внутри сетки, я получаю country_id в текущей строке и фильтрую cityStore, используя этозначение.Для этого необходимо, чтобы cityStore имел следующие поля: id, country_id, city

Остается одна проблема: когда пользователь меняет countryCombo, поле города должно изменить / предупредить пользователячто это не правильно для текущей страны.Решение для этого было сложным ... как вы, возможно, знаете, вы не можете получить ссылку на parentGrid comboBox (в противном случае вы можете просто вызвать countryCombo --> parentGrid --> currentRecord --> cityCombo --> change it).

Я попытался прослушать событие rowchange в сеткесамо по себе, но если пользователь щелкнул по другой строке сразу после изменения countryCombo, это изменило город неправильной строки.

Решение было несколько сложным: мне пришлось скопировать ссылки для текущей строки в cityCombo из предсредства сетки.событие.Вот слушатель сетки для этого:

listeners: {
    beforeedit: function(e) {
        // reference to the currently clicked cell
        var ed = e.grid.getColumnModel().getCellEditor(e.column, e.row);    
        if (ed && ed.field) {
            // copy these references to the current editor (countryCombo in our case)
            Ext.copyTo(ed.field, e, 'grid,record,field,row,column');
        }
    }
},

Теперь наш countryCombo имеет всю информацию, необходимую для сброса города, когда он меняется.Вот весь код countryCombo:

var countryCombo = new Ext.form.ComboBox({
    id: 'skupina_combo',
    typeAhead: true,
    triggerAction: 'all',
    lazyRender: true,
    mode: 'local',
    store: countryDropdownStore,
    displayField: 'country',
    valueField: 'country_id',
    listeners: {
        change: function(t, n, o) {    // t is the reference to the combo
            // I have t.record available only because I copied it in the beforeEdit event from grid
            t.record.set('city_id', '0');
        }

    }
});

У средств визуализации ячеек не было проблем с фильтрацией их хранилища, поэтому мне нужен был только один магазин как для рендеринга, так и для редактирования комбинированного списка (cityStore).

Для удаленного решения мне потребовалось создать два магазина для городов - cityRendererStore и cityDropdownStore, которые запрашивали базу данных каждый раз вместо использования фильтров.Такой подход необходим, если у вас слишком много городов для локальной фильтрации.Я должен отметить, что я на самом деле не использую города и страны в своем приложении, я просто создал этот пример для упрощения вещей.

Я действительно доволен конечным результатом - он дает все преимущества сетки вместес условными выпадающими списками, обычно доступными только в формах.

1 голос
/ 20 октября 2010

Я вижу несколько вариантов здесь.Вы можете перехватить событие магазина update (когда основная запись обновлена ​​или помечена как грязная) или перехватить событие select countryComboBox.Оба из них предоставят вам значение идентификатора выбранной страны, которое затем вы можете добавить в baseParams вашего cityComboBox для удаленной фильтрации.

...