Работа с фильтром в публичной части
Table of Contents
Условно, работу с фильтром на странице можно разделить на несколько частей:
- Общая работа с фильтрами (получение фильтра, изменение фильтра и другие внешние воздействия на фильтр)
- Работа с событиями фильтра (выполнение действий при срабатывании события фильтра)
Работа с фильтром
Вся работа начинается с получения объекта фильтра, а поскольку на странице может быть много фильтров, то эта задача выделена объекту BX.Main.filterManager
, который является объектом-хранилищем объектов фильтра.
Мы не будем расматривать его работу подробно, а остановимся лишь на некоторых его аспектах:
- Получить все зарегистрированные (на момент выполнения кода) фильтры, можно через метод
getList
(BX.Main.filterManager.getList()
) - Получить конкретный фильтр по его идентификатору можно через метод
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');}
);
Изменение состава полей
Иногда необходимо изменять состав полей фильтра и для этого необходимо сделать ряд последовательных действий:
- Получить мета-описание поля
- Расширить предустановленный набор полей
- Добавить поле в текущий пресет
- Синхронизировать поля в текущем открытом фильтре
Общий код который добавляет поле с кодом 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);
});