[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.
… много всяких мелочей, все и не упомнишь =)
Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.