[ExtJs] Связанные комбобоксы
        Возникла задача сделать так, чтобы при выборе группы студентов в одном комбобоксе, в другом комбобоксе процессор getlist возвращал записи относящиеся только к выбранной группе. Делюсь как решил эту задачу я, надеюсь кому нибудь пригодится =)
 
Вот так выглядит вызов xtype, где мы выбираем группу студентов. Вся соль в параметре listeners.
Функция которая заменяет дни недели на записи из лексиконов:
При выборе даты получаю записи только за конкретный день недели, дальше идет фильтрация по группе студентов. В итоге я получаю список пар для конкретной группы и в конкретный день недели, в зависимости от выбранной даты.
Спасибо @Павел Гвоздь за помощь в этом вопросе и его modExtraLayout
    
    
                                                        Решение
Вот так выглядит вызов xtype, где мы выбираем группу студентов. Вся соль в параметре listeners.
{
    xtype: 'portal-combo-group',
    id: config.id + '-group_id',
    name: 'group_id',
    anchor: '100%',
    hiddenName: 'group_id',
    fieldLabel: 'Группа',
    listeners: {
        select: {
            fn: function (combo, a, b) {
                var cmp = Ext.getCmp(config['id'] + '-schedule_id');
                if (!!cmp) {
                    cmp.getStore().baseParams['group_id'] = combo.getValue();
                    cmp.store.removeAll();
                    cmp.store.load();
                    cmp.reset();
                    cmp.setValue('');
                }
            },
            scope: this,
        }
    },
}xtype поля даты:{
    xtype: 'datefield',
    id: config.id + '-date',
    name: 'date',
    fieldLabel: 'Дата',
    anchor: '100%',
    format: 'd-m-Y',
    startDay: 1,
    listeners: {
        select: {
            fn: function (a,b) {
                var cmp = Ext.getCmp(config['id'] + '-schedule_id');
                if (!!cmp) {
                    cmp.getStore().baseParams['day'] = a.getValue().getDay();
                    cmp.store.removeAll();
                    cmp.store.load();
                    cmp.reset();
                    cmp.setValue('');
                }
            },
            scope: this,
        }
    }
}Сам код комбы в которую подставлется значение вполне стандартный: portal.combo.Schedule = function (config) {
    config = config || {};
    Ext.applyIf(config, {
        name: 'schedule_id',
        fieldLabel: config['name'] || 'schedule_id',
        hiddenName: config['name'] || 'schedule_id',
        displayField: 'day_time',
        emptyText: 'Выберите пару в расписании',
        valueField: 'id',
        fields: ['id', 'group_name','day','time_start','time_end','day_time'],
        url: portal.config['connector_url'],
        baseParams: {
            action: 'mgr/combo/getschedule',
            group_id: 0,
        },
        pageSize: 20,
        typeAhead: false,
        editable: true,
        minChars: 1,
        anchor: '100%',
        listEmptyText: '<div style="padding: 7px;">' + _('portal_combo_list_empty') + '</div>',
        tpl: new Ext.XTemplate('\
            <tpl for=".">\
                <div class="x-combo-list-item">\
                    <span>\
                        <small>({id})</small>\
                        <tpl if="group_name"> - {group_name}</tpl>\
                        <tpl if="day"> | {day}</tpl>\
                        <tpl if="time_start"> | {time_start}</tpl>\
                        <tpl if="time_end"> - {time_end}</tpl>\
                    </span>\
                </div>\
            </tpl>',
            {compiled: true}
        ),
    });
    portal.combo.Schedule.superclass.constructor.call(this, config);
};
Ext.extend(portal.combo.Schedule, MODx.combo.ComboBox);
Ext.reg('portal-combo-schedule', portal.combo.Schedule);Фильтрация в процессоре: public function prepareQueryBeforeCount(xPDOQuery $c)
    {
        $c->select('id,group_name,day,time_start,time_end');
        if ($query = trim($this->getProperty('query'))) {
            $c->where(array(
                'id:LIKE' => "{$query}%",
                'OR:group_name:LIKE' => "%{$query}%",
            ));
        }
        if ($group_id = (int)$this->getProperty('group_id')) {
            $c->where(array(
                'group_id' => "{$group_id}%",
            ));
        } else {
            $c->where(array(
                'id' => 0,
            ));
        }
        return $c;
    }Функция которая заменяет дни недели на записи из лексиконов:
public function afterIteration(array $list)
    {
        foreach ($list as &$v) {
            $v['day_raw'] = $v['day'];
            $v['day'] = $this->modx->lexicon('week_day_' . $v['day']);
            $v['day_time'] = $v['day'] . ' / ' . $v['time_start'] . '-' . $v['time_end'];
        }
        return $list;
    }Я использую эту штуку для выбора пары в расписании: При выборе даты получаю записи только за конкретный день недели, дальше идет фильтрация по группе студентов. В итоге я получаю список пар для конкретной группы и в конкретный день недели, в зависимости от выбранной даты.
Спасибо @Павел Гвоздь за помощь в этом вопросе и его modExtraLayout
            
                Поблагодарить автора            
            
                 Отправить деньги            
        
        
            Комментарии: 7
                Спасибо. Обязательно где-нибудь пригодится.            
                    id: config.id + '-group_id',желательно вообще не задавать, иначе будут проблемы при одновременном открытии нескольких окон, панелей и тд когда id дублируются.
var cmp = Ext.getCmp(config['id'] + '-schedule_id');так тоже не есть хорошо, но когда нет других вариантов конечно можно)
можно сделать так
listeners: {
    select: {
        fn: function (r) {
            this._handleChange();
        },
        scope: this
    }
}
//...
_handleChange: function () {
    var f = this.fp.getForm();
// получаем поля по имени
    var _field1 = f.findField('name_field1');
    var _field2 = f.findField('name_field1');
    _field2.baseParams['name_field1'] = _field1.getValue();
    // показываем пагинацию если нужно на комбике
    if (!!_field2.pageTb) {
        _field2.pageTb.show();
    }
    _field2.store.load();
}            
                Интересно! Попробую!) Спасибо!            
                    
                Новое — это хорошо забытое старое.
П.С. Маленький совет. Лучше обозвать топик «Связанные комбобоксы в ExtJs» или «Связанные списки в ExtJs». Так ближе к смыслу и легче будет потом найти пользователям.
                    П.С. Маленький совет. Лучше обозвать топик «Связанные комбобоксы в ExtJs» или «Связанные списки в ExtJs». Так ближе к смыслу и легче будет потом найти пользователям.
                Переименовал)            
                    
                Кстати а чем modExtraLayout отличается от modExtra?            
                    
                Многие штуки которые я часто использую там есть из коробки. 
Системные методы вынесены в отдельный класс tools.
Окна create и update в админке сделаны так, что они в коде extjs все поля прописываются один раз, а не 2.
… много всяких мелочей, все и не упомнишь =)
                    Системные методы вынесены в отдельный класс tools.
Окна create и update в админке сделаны так, что они в коде extjs все поля прописываются один раз, а не 2.
… много всяких мелочей, все и не упомнишь =)
                            Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.