В окне создания и редактирования записей у меня есть поле типа combobox
Ext.define('BookApp.view.Book', {
extend: 'Ext.window.Window',
alias: 'widget.bookwindow',
width : 450,
title: 'Book',
layout: 'fit',
autoShow: true,
modal : true,
initComponent: function() {
this.items = [{
xtype: 'form',
items: [
{
xtype: 'combobox',
fieldLabel: 'Status',
name: 'status',
store: Ext.data.StoreManager.lookup('Statuses'),
valueField: 'id',
displayField: 'name',
typeAhead: true,
queryMode: 'remote'
},
...............
Статусы магазина - это записи из таблицы с полями: id, name, order_install, где order_install - порядок статусов.
Статусы таблиц
имя id order_install
23 Новинка 1
24 в работе 2
29 Перенесено 3
34 Отправлено 4
31 In_transit 5
Как сделать так, чтобы выбор значения из списка статусов был ограничен только одним значением вверх или вниз в соответствии с полем order_install?
Например: если статус В работе, то для выбора были доступны только статусы Отложено и Новое.
Решение:
filterBy()
с настраиваемой функцией фильтрации.id
случайны, вам нужно получить внутреннюю позицию записи в магазине, чтобы найти предыдущую и следующую запись.В следующих примерах filterCombo()
- это функция, которая фильтрует магазин. Эта функция используется в событии выбора поля со списком. Вы можете использовать его где хотите. Между версиями ExtJS 4 и ExtJS 6 есть различия, поэтому есть два примера:
ExtJS 4:
Ext.onReady(function(){
Ext.QuickTips.init();
Ext.FocusManager.enable();
var store = Ext.create('Ext.data.Store', {
fields: ['order', 'id', 'name'],
data : [
{"id": 23, name: "New", order_install: 1},
{"id": 24, name: "In Work", order_install: 2},
{"id": 29, name: "Postponed", order_install: 3},
{"id": 34, name: "Shipped", order_install: 4},
{"id": 31, name: "In_transit", order_install: 5}
]
});
function filterCombo(combobox, index) {
store = combobox.getStore();
store.clearFilter();
store.filterBy(
function(record) {
if ((record.index == index - 1) || (record.index == index) || (record.index == index + 1)) {
return true;
} else {
return false;
}
}
);
};
Ext.create('Ext.form.ComboBox', {
fieldLabel: 'Choose items',
store: store,
queryMode: 'local',
displayField: 'name',
valueField: 'id',
multiSelect: false,
renderTo: Ext.getBody(),
value: 'In Work',
listeners: {
'select': function (combo, records) {
index = records[0].index;
filterCombo(combo, index);
},
'render': function (combo) {
index = combo.store.find('name', combo.getValue());
filterCombo(combo, index);
}
}
});
});
ExtJS 6:
Ext.application({
name : 'Fiddle',
launch : function() {
var store = Ext.create('Ext.data.Store', {
fields: ['order', 'id', 'name'],
data : [
{"id": 23, name: "New", order_install: 1},
{"id": 24, name: "In Work", order_install: 2},
{"id": 29, name: "Postponed", order_install: 3},
{"id": 34, name: "Shipped", order_install: 4},
{"id": 31, name: "In_transit", order_install: 5}
]
});
function filterCombo(combobox, index) {
store = combobox.getStore();
store.clearFilter();
store.filterBy(
function(record) {
if ((record.internalId == index - 1) || (record.internalId == index) || (record.internalId == index + 1)) {
return true;
} else {
return false;
}
}
);
};
Ext.create('Ext.form.field.ComboBox', {
fieldLabel: 'Choose items',
store: store,
queryMode: 'local',
displayField: 'name',
valueField: 'id',
value: '24', // Equals to "In Work"
multiSelect: false,
renderTo: Ext.getBody(),
listeners: {
'select': function (combo, records) {
index = records.internalId;
filterCombo(combo, index);
},
'render': function (combo) {
index = combo.getSelection().internalId;
filterCombo(combo, index);
}
}
});
}
});
ребята - Спасибо. Но как я могу заставить фильтр работать так же хорошо, когда уже есть установленное значение. В форме редактирования, пока я не выберу новое значение, фильтр работать не будет.
@Ambasador Вы можете вызывать эту функцию где хотите. Я называю это слушателем «рендеринга». См. Обновленный ответ.
Спасибо. Ваш ответ правильный и я действительно помог
Какая у вас версия ExtJS?