Работа с фильтром в публичной части

Условно, работу с фильтром на странице можно разделить на несколько частей:

  • Общая работа с фильтрами (получение фильтра, изменение фильтра и другие внешние воздействия на фильтр)
  • Работа с событиями фильтра (выполнение действий при срабатывании события фильтра)

Работа с фильтром

Вся работа начинается с получения объекта фильтра, а поскольку на странице может быть много фильтров, то эта задача выделена объекту BX.Main.filterManager, который является объектом-хранилищем объектов фильтра. Мы не будем рассматривать его работу подробно, а остановимся лишь на некоторых его аспектах:

  1. Получить все зарегистрированные (на момент выполнения кода) фильтры, можно через метод getList (BX.Main.filterManager.getList())
  2. Получить конкретный фильтр по его идентификатору можно через метод getById (BX.Main.filterManager.getById( <id> ))

В дальнейшем мы предполагаем что в переменной filterInstance содержится объект который мы получили через getById метод.

Некоторые полезные команды:

filterInstance.adjustFocus(); - переместить фокус на поле “Поиск”. В случае если текущее окно находится в фокусе, выполнение этого кода активирует часть фильтра отвечающего за Поиск и переместит курсор пользователя в него.

filterInstance.getParam( <param name>, <default value> ); - вернет значение параметра из объекта фильтра. Полный список параметров можно посмотреть в params-свойстве (filterInstance.params). Например, можно проверить является ли фильтр lazyload (filterInstance.getParam('LAZY_LOAD'))

filterInstance.resetFilter( <withoutSearch> ); - сбрасывает значения фильтра. Если <withoutSearch> = true, поисковая строка (если она была задана) остается, в других случаях полная очистка фильтра.

filterInstance.getFilterFieldsValues(); - возвращает текущие значения фильтра. Ключ FIND-текст который пользователь ввел в поисковую строку.

Получение мета-описания поля

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

Для получения фильтра который явно указан на поле нужно использовать метод getFieldByName:

var namedField = filterInstance.getFieldByName( <field name> );
console.log(namedField);

однако для lazyload придется использовать promise:

filterInstance.getLazyLoadField( <field name> )
	.then((namedField)=>{
		console.log(namedField);
	})

Помните, что данный код является асинхронным, поэтому нужно учесть это в своих разработках.

Мы написали обобщенный асинхронный метод для получения мета-информации о поле и вы можете воспользоваться следующим помощником:

BX.Main.Filter.prototype.getFieldDesc = function ( fieldName )
{
	return new Promise((resolve, reject) => {

		var field = this.getFieldByName( fieldName );

		if ( field )
		{
			resolve(field);
			return;
		}

		if ( !this.getParam('LAZY_LOAD') )
		{
			reject();
			return;
		}

		return this.getLazyLoadField(fieldName).then(
			(field) => { resolve(field) },
			(error) => { reject(error) }
		);
	});
};

Пример использования:

filterInstance.getFieldDesc( <field name> ).then(
	(foundedField) => { console.log('Field found: ', foundedField)},
	(error) => { console.log('Whoops! field missed');}
);

Изменение состава полей

Иногда необходимо изменять состав полей фильтра и для этого необходимо сделать ряд последовательных действий:

  1. Получить мета-описание поля
  2. Расширить предустановленный набор полей
  3. Добавить поле в текущий пресет
  4. Синхронизировать поля в текущем открытом фильтре

Общий код который добавляет поле с кодом SOME_FIELD_NAME на форму выглядит так:

filterInstance.getFieldDesc('SOME_FIELD_NAME').then(
	(foundedField) => {

		// Check exist in fileds
		var foundId = filterInstance.params.FIELDS.findIndex((filterField)=>{
			if ( filterField['ID'] == "field_"+foundedField['ID'])
			{
				return true;
			}
		});

		if ( foundId < 0 )
		{
			filterInstance.params.FIELDS.push(foundedField);
			filterInstance.getPreset().addField(foundedField);
		}

		filterInstance.syncFields();
	},
	(error) => {
		console.log('Whoops! field missed');
	}
);

Применить пресет

В случае если вы знаете идентификатор пресета применить его можно через API методы.

Например, для применения пресета filter_my можно воспользоваться кодом:

filterInstance.getApi().setFilter({preset_id:'filter_my'});

Установить фильтр

Установить произвольный фильтр можно в 2 этапа: изменение полей, а затем применение.

Помните что для установки значения поле должно быть выведено на форме

Например: мы хотим заполнить поле TITLE значением и применить его к странице:

filterInstance.getApi().setFields({"TITLE": "семинар"});
filterInstance.getApi().apply();

События

Фильтр, как и другие публичные элементы Битрикс24 подразумевает наличие полезных событий. На момент написания статьи сам фильтр имеет следующие события:

  • Показ полей фильтра (show) - в момент когда пользователь нажал на поисковую строку, после открытия области изменения фильтра.
  • Скрытие полей фильтра (blur) - в момент когда окно полей фильтра исчезает.
  • Событие применения фильтра (до применения beforeApply и в момент apply).

На событиях показа/скрытия полей фильтра можно получить доступ к всему объекту фильтра и произвести визуальные изменения, а так же подписки на события:

BX.addCustomEvent('BX.Main.Filter:blur', function(filterInstance) {
	console.log('Filter hidden: ', filterInstance);
});
BX.addCustomEvent('BX.Main.Filter:show', function(filterInstance) {
	console.log('Filter displayed: ', filterInstance);
});

Событие применения фильтра (apply) удобно использовать при разработке своих пользовательских интерфейсов, когда по нажатию нужно перерисовать область на экране:

BX.addCustomEvent('BX.Main.Filter:apply', function(filterId, action, filterInstance) {
	console.log('Submit filter', filterId);
	console.log("With action (clear, apply): ", action);
	console.log('Filter instance: ', filterInstance);
});