Как ограничить выбор значений из выпадающего списка Extjs

В окне создания и редактирования записей у меня есть поле типа 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?

Например: если статус В работе, то для выбора были доступны только статусы Отложено и Новое.

Какая у вас версия ExtJS?

Zhorov 10.09.2018 08:05
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
1 325
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

1) FIDDLE: до выбора
2) FIDDLE: filterBy

Ответ принят как подходящий

Решение:

  • Используйте метод store 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 10.09.2018 23:27

@Ambasador Вы можете вызывать эту функцию где хотите. Я называю это слушателем «рендеринга». См. Обновленный ответ.

Zhorov 11.09.2018 08:02

Спасибо. Ваш ответ правильный и я действительно помог

Ambasador 11.09.2018 11:55

Другие вопросы по теме