Javascript-форум (https://javascript.ru/forum/)
-   ExtJS (https://javascript.ru/forum/extjs/)
-   -   Фильтрация значений combobox (https://javascript.ru/forum/extjs/77668-filtraciya-znachenijj-combobox.html)

Ambassador 04.06.2019 17:20

Фильтрация значений combobox
 
Приветствую.
Для поля combobox, в окне редактирования, необходимо сделать так что бы поле изменялось только на одно значение вверх или вниз, как при создании новой записи или при редактировании.
....
{
                xtype: 'combobox',
                name: 'status',                   
                fieldLabel: 'Status',
                displayField: 'name',
                valueField: 'id',                   
                queryMode: 'local',
                store: new Ext.data.ArrayStore({
                    id: 0,
                    fields: ['id','name'],
                    data: [[1, 'Новая'], [2, 'В работе'], [3, 'В ожидании'], [4, 'Закрытая'], [5, 'Архивная']]
                }),              
                listeners: {
                    'select': function (combo, record) {
                       
                        index = record.internalId;
                        filterCombo(combo, index);
                    },
                    'render': function (combo) {
                        //index = combo.getSelection().internalId;
                        //filterCombo(combo, index);
                }
                }
},
....

Делаю при помощи событий select и render. Функция filterCombo выглядит так:

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;
                    }
                }
            );
}


1. При выполнении render , ругается на combo.getSelection() (ReferenceError: index is not defined). Почему?
2.Возможно ли реализовать данную логику более лаконично, к примеру во ViewController в методах addItem, editItem . Т.е фильтровать стор в момент открытия формы на добавление/редактирование, или это вариант не очень?
3. Если остановиться на 1ом пункте, то куда наиболее правильно будет вынести функцию filterCombo что бы не оставлять ее в представлении App.view.TestEdit
Пример на Fiddle
Спасибо

Pavel M. 10.06.2019 19:33

Цитата:

Сообщение от Ambassador
Для поля combobox, в окне редактирования, необходимо сделать так что бы поле изменялось только на одно значение вверх или вниз, как при создании новой записи или при редактировании.

Не понятно.
Что должно получиться?

Ambassador 18.06.2019 11:34

Цитата:

Сообщение от Pavel M. (Сообщение 508931)
Не понятно.
Что должно получиться?

Для выбора должно быть доступно только значение на одно больше или меньше , к примеру вот весь список значений комбы:
'Новая'
'В работе'
'В ожидании'
'Закрытая'
'Архивная'

необходимо что бы было так:
если пустое значение то:
'Новая'
если выбрано Новая то
'Новая'
'В работе'
если выбрано 'В работе' то:
'Новая'
'В работе'
'В ожидании'
если выбрано 'В ожидании' то:
'В работе'
'В ожидании'
'Закрытая'

Infarch 18.06.2019 15:40

Мне кажется, вам надо держать полный список значений в одном сторе, а в комбике использовать другой, чейновый с фильтром: https://docs.sencha.com/extjs/6.7.0/...ml#cfg-filters
Напишите должный фильтр и готово.
Еще вариант - отказатсья от комбика. А почему бы и нет? Для выставления всего двух статусов достаточно двух кнопок.

Pavel M. 18.06.2019 17:05

Можно так https://fiddle.sencha.com/#view/editor&fiddle/2t5d

В каждом пункте в store задано, какие еще id при его выборе отображаются

Ambassador 19.06.2019 15:57

Добрый день.
Pavel M. - Сделал по вашему примеру так:
....
{
                ....
                store: Ext.create('Ext.data.Store', {
                    fields: ['id', 'name', 'show'], // в show массив с id, которые показываем при выборе этого пункта
                    data: [
                        {id:1, name:"Пункт 1", show:[1, 2]},
                        {id:2, name:"Пункт 2", show:[1, 2, 3]},
                        {id:3, name:"Пункт 3", show:[2, 3, 4]},
                        {id:4, name:"Пункт 4", show:[3, 4, 5]},
                        {id:5, name:"Пункт 5", show:[4, 5, 6]},
                        {id:6, name:"Пункт 6", show:[5, 6]}       
                    ]
                }),   
                listeners: {
                    render: function (combo){
                        store = combo.getStore();
                        store.filter('id', 1);
                    },
                    select: function (combo, rec) {
                        store = combo.getStore();   
                        store.clearFilter(true);
                        store.filter({
                            property: 'id',
                            operator: 'in',
                            value: rec.get('show')
                        });
                    }
                }
            },
.....


Пример в fiddle
При создании новой записи работает как и требуется, но если редактируем имеющуюся,
то событие select срабатывает только когда выбран уже элемент, соответственно фильтрации по значениям 'show' не происходит.
По идее, если перенести фильтрацию в render, то можно добиться необходимого, но при этом мне обязательно нужно получать установленное значение комбы,
и вроде так должно работать, но как мне получать в render текущую запись?

listeners: {
                    render: function (combo){
                        currentRec.get('show')//currentRec - Должна быть установленная запись, но как мне ее получить в render ?
                        if(Ext.Object.isEmpty(currentRecShow)){
                            store = combo.getStore();
                            store.filter('id', 1);
                        }
                        else{
                            store = combo.getStore();   
                            store.clearFilter(true);
                            store.filter({
                                property: 'id',
                                operator: 'in',
                                value: currentRec.get('show')//rec.get('show')
                            });
                        }
                    },                   
                }

Возможно что мой вариант абсолютно не правильный. Тогда как сделать наиболее верное решение?

Ambassador 19.06.2019 16:00

Цитата:

Сообщение от Infarch (Сообщение 509172)
Мне кажется, вам надо держать полный список значений в одном сторе, а в комбике использовать другой, чейновый с фильтром: https://docs.sencha.com/extjs/6.7.0/...ml#cfg-filters
Напишите должный фильтр и готово.
Еще вариант - отказатсья от комбика. А почему бы и нет? Для выставления всего двух статусов достаточно двух кнопок.

Спасибо

Pavel M. 22.06.2019 21:16

Ambassador,
кто мешает, например, при открытии окна устанавливать фильтр комбобокса?
пример https://fiddle.sencha.com/#view/editor&fiddle/2t9o

попробуйте выбрать значение в комбо, закрыть окно и открыть заново

Ambassador 09.07.2019 12:55

Цитата:

Сообщение от Infarch (Сообщение 509172)
Мне кажется, вам надо держать полный список значений в одном сторе, а в комбике использовать другой, чейновый с фильтром: https://docs.sencha.com/extjs/6.7.0/...ml#cfg-filters
Напишите должный фильтр и готово.
Еще вариант - отказатсья от комбика. А почему бы и нет? Для выставления всего двух статусов достаточно двух кнопок.

Если реализовывать с помощью двух кнопок, то где можно подобный пример посмотреть? Или какой именно компонент использовать ?
Полагаю что нужен
xtype: 'segmentedbutton'
но тогда как в него подгружать значение поля status_id и id статусов доступные для переключения

Infarch 10.07.2019 10:06

Вы могли бы использовать actioncolumn в гриде. Вот кусок кода из одного проекта:
{
	xtype: 'actioncolumn',
	width: 50,
	align: 'center',
	items: [
		{
			icon: '/images/company7/desktop_toolbar_undo.gif',
			tooltip: Localtext.heading.revert_to_draft,
			getClass: function(v, meta, record){
				if( ! record.isRound || record.get('IsDraft') ) return 'x-hidden-display';
			},
			handler: 'doRevert'
		}
	]
}


Фишка вот в чем: создаете айтемы для всех возможных значений, но прячете неподходящие с помощью функции getClass. Когда хендлер сменит поле строки, getClass снова вызовется и обновит грид.


Часовой пояс GMT +3, время: 09:59.