Взаимосвязанные преднастроенные фильтры

Доброго времени суток, сообщество! Столкнулся со следующей проблемой и надеюсь на вашу помощь.

В разделе есть два преднастроенных фильтра: Дистрибьютор и ShipTo . Нужно чтобы после выбора значения в фильтре "Дистрибьютор" обновлялся параметр "filter" для фильтра "ShipTo".

Подробнее: В фильтре "ShipTo" пользователь должен иметь возможность выбрать запись только из тех, которые есть у Дистрибьютора, выбранного в фильтре "Дистрибьютор", на детали ShipTo.

Как реализовать фильтр в общем понятно. Но проблема в том, что фильтр инициализируется лишь раз, а мне надо чтобы при выборе одного фильтра проходила "переинициализация" другого.

Надеюсь понятно объяснил, это было не легко :smile:

Прилагаю код моих преднастроенных фильтров:

initFixedFiltersConfig: function(recursion) {
                    var self = this;
                    var fixedFilterConfig = {
                        entitySchema: this.entitySchema,
                        filters: [
                            {
                                name: "SxDistributor",
                                caption: this.get("Resources.Strings.SxDistributorFilterCaption"),
                                addSxDistributorCaption: this.get("Resources.Strings.SxAddDistributorFilterCaption"),
                                referenceSchemaName: "Account",
                                entityColumn: {
                                    isLookup: true
                                },
                                notNeedCurrentUser: true,
                                dataValueType: this.Terrasoft.DataValueType.LOOKUP,
                                filter: function(){
                                    // Получаем список контрагентов у которых есть тип "Дистрибьютор"
                                    if(self.get('AccountId').length > 0) {
                                        //  Фильтруем контрагентов по полученному списку
                                        return Terrasoft.createColumnInFilterWithParameters(
                                            "Id", self.get('AccountId'));
                                    }else{
                                        return false;
                                    }
                                },
                                getFilter: function (filterInfo) {
                                    if(filterInfo.value) {
                                        /*  Генерируем фильтр для ShipTo   */
                                        var ShipToId = [];  //  Список ShipTo выбранного Контрагента
                                        var esq = Ext.create('Terrasoft.EntitySchemaQuery', {
                                            rootSchemaName: 'SxShipTo'
                                        });
                                        esq.addColumn('Id');
                                        esq.filters.add('SxAccount',
                                            esq.createColumnFilterWithParameter(
                                                Terrasoft.ComparisonType.EQUAL, 'SxAccount', filterInfo.value[0]));
                                        esq.getEntityCollection(function (response) {
                                            if (response.success) {
                                                ShipToId = [];
                                                response.collection.each(function (item) {
                                                    ShipToId.push(item.values.Id);
                                                });
                                                self.set('ShipToId', ShipToId);

                                                // TODO Надо обновить filter для фильтра ShipTo
                                            }
                                        }, this);

                                        /*  Фильтруем раздел по полю Контрагент    */
                                        var filter;
                                        filterInfo.value && (filter = Terrasoft.createColumnInFilterWithParameters(
                                            "SxAccount", filterInfo.value));
                                        return filter;
                                    }
                                }
                            },

                            {
                                name: "SxShipTo",
                                caption: this.get("Resources.Strings.SxShipToFilterCaption"),
                                addSxShipToCaption: this.get("Resources.Strings.SxAddShipToCaption"),
                                referenceSchemaName: "SxShipTo",
                                entityColumn: {
                                    isLookup: true
                                },
                                notNeedCurrentUser: true,
                                dataValueType: this.Terrasoft.DataValueType.LOOKUP,
                                filter: function(){
                                    //  Получаем список записей ShipTo выбранного Контрагента
                                    if(self.get('ShipToId').length > 0) {
                                        return Terrasoft.createColumnInFilterWithParameters(
                                            "Id", self.get('ShipToId'));
                                    }else{
                                        //  Если ShipTo пустой ставим невыполнимый фильтр. Список пуст.
                                        return Terrasoft.createColumnIsNullFilter("Id");
                                    }
                                },
                                getFilter: function (filterInfo) {
                                    //  Фильтруем раздел по полю ShipTo
                                    var filter;
                                    filterInfo.value && (filter = Terrasoft.createColumnInFilterWithParameters(
                                        "SxShipTo", filterInfo.value));
                                    return filter;
                                }
                            }
                        ]
                    };
                    this.set("FixedFilterConfig", fixedFilterConfig);
                }

Нравится

1 комментарий

Вячеслав, добрый день!

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

Как вариант, можно вызвать повторную инициализацию всех фильтров, добавив вызов метода self.initFilters() примерно в том месте, где у Вас расположен комментарий

// TODO Надо обновить filter для фильтра ShipTo

плюс использовать флаг для избежания зацикливания. Также необходимо учесть случай, когда происходит очистка значения фильтра "Дистрибьютор" (во время работы над Вашим вопросом у меня это вызвало больше всего проблем).

Вот примерный список изменений, который Вы можете добавить для работы функционала:

1) Изменить метод getFilter первого фильтра примерно так:

getFilter: function (filterInfo) {
	if (!self.get("ChildFiltersInitializing")) {
		if(filterInfo.value) {
			/*  Генерируем фильтр для ShipTo   */
			var ShipToId = [];  //  Список ShipTo выбранного Контрагента
			var esq = Ext.create('Terrasoft.EntitySchemaQuery', {
				rootSchemaName: 'SxShipTo'
			});
			esq.addColumn('Id');
			esq.filters.add('SxAccount',
			esq.createColumnFilterWithParameter(
				Terrasoft.ComparisonType.EQUAL, 'SxAccount', filterInfo.value[0]));
			esq.getEntityCollection(function (response) {
				if (response.success) {
					ShipToId = [];
					response.collection.each(function (item) {
						ShipToId.push(item.values.Id);
					});
					self.set('ShipToId', ShipToId);
 
					// TODO Надо обновить filter для фильтра ShipTo
 
					self.set("ChildFiltersInitializing", true);
					self.initFilters();
				}
			}, this);
		} else {
			if ((self.get("ChildFiltersInitializing") !== undefined) && self.get("ShipToId")) {
				self.set("ShipToId", null);
				self.set("ChildFiltersInitializing", true);
				self.initFilters();
			}
		}
	}
 
	/*  Фильтруем раздел по полю Контрагент    */
	var filter;
	filterInfo.value && (filter = Terrasoft.createColumnInFilterWithParameters(
		"SxAccount", filterInfo.value));
	return filter;
}

2) добавить переопределение метода onFilterUpdate для инициализации флага:

onFilterUpdate: function() {
	this.callParent(arguments);
	if (this.get("ChildFiltersInitializing")) {
		this.set("ChildFiltersInitializing", false);
	}
}

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

Показать все комментарии