
mFilter 1.6.0
Рабочий JS API для управления фильтрами со страницы, паттерны URL для диапазонов и исправления в админке: сохранение набора фильтров больше не теряет настройки и не путает ключи.
Новые возможности
JS API для одной формы и элементов вне формы
Кнопка, ссылка или селект сортировки в шапке теперь могут управлять фильтрами:
const filter = mfilterGet(); // без аргумента — форма на странице
filter.setFilter('vendor_id', [5, 7]); // выдача обновится сама
filter.addFilter('vendor_id', 9);
filter.removeFilter('vendor_id', 5);
filter.setFilter('price', { min: 1000, max: 5000 });
filter.setSort('price-asc'); // всё это — один запросmfilterGet()без аргумента возвращает форму фильтров на странице.- Новый метод
addFilter()добавляет значения к выбранным.removeFilter()снимает значение, переданное и числом, и строкой. - Вызовы API сами отправляют запрос: несколько вызовов подряд уходят одним, изменение во время загрузки — следующим.
- События
mfilter:success,mfilter:afterSubmitиmfilter:contentLoadedпередаютfilters,total,page,pageCount,sort,limit,tpl. mfilter:initотправляется после регистрации формы, поэтомуmfilterGet()работает уже в его обработчике.
Подробнее — JS API.
Паттерны URL для диапазонов
В шаблоне паттерна появились подстановки {min} и {max}. Паттерн ot-{min}-do-{max} для фильтра price даёт адрес /catalog/ot-1000-do-5000/ вместо /catalog/price--1000--5000/.
Обе подстановки нужны сразу: шаблон без них к диапазону не применяется, и адреса сайтов, где в поле вписано что-то другое, не меняются. Адреса формата ключ--от--до продолжают открываться.
Подробнее — Паттерны URL.
Исправления
- Паттерн URL с типом «Булево» открывал обратный фильтр. Адрес строится из значения фильтра —
1или0, — а при разборе1превращалось в0. Теперь принимаются оба написания:1/0иyes/no. - В адресах вместо слагов разделов стояли id, а
mfilter.slug_parent_prefixне действовал ни в одном режиме. Регрессия 1.5.0. Вид значения для слагов определялся по ключу фильтра, а по ключу для любого фильтра находился числовой тип. Теперь вид берётся из типа, заданного фильтру в наборе. - Сохранение набора фильтров в админке стирало настройки фильтров. В таблице набора видны ключ, источник, тип и заголовок; всё остальное из JSON набора —
sort,pinned,hide_zero,prefixи прочее — при сохранении пропадало. Фильтр, у которого поле отличается от ключа, сохранялся под ключом поля, и у него менялись адреса, слаги и SEO-шаблоны. - Две строки набора могли сохраниться под одним ключом. В колонке «Ключ» стоит поле фильтра, поэтому фильтр с ключом
brandи полемproduct_brandвиден какproduct_brand, и строка с ключомbrandмолча затирала его. Теперь сохранение отклоняется с указанием строк, а настоящий ключ виден под полем. - Фильтры без
typeв наборе форма выводила только числовыми. Набор, заданный списком ключей, или запись JSON безtype: форма определяла тип сама и пропускала все блоки, кроме числовых. Теперь она выводит фильтр с тем типом, с которым сервер посчитал его значения. - Для ключей
color,size,tagsисточник по умолчанию был «Данные товара». В MiniShop3 это JSON-поля, синхронизируемые с опциями товара, и фильтр с таким источником не работал. Теперь для них выбирается «Опции». - Страница раздела без товаров отдавала 500, если на ней вызван
mFilterNavс&cache=1. Пустой результат сниппет кэшировал так, что на PHP 8 это фатальная ошибка. Разделы с товарами работали. submit()стирал фильтры, которых нет в форме. Фильтр, выставленный кнопкой вне формы или исключённый через&exclude, пропадал при каждой отправке, смене сортировки и переходе на страницу.- На SEO-адресе фильтр без поля в форме уходил на сервер слагом — каталог оказывался пустым. Теперь
mFilterFormотдаёт фильтры, разобранные сервером, в атрибуте формыdata-mfilter-active-filters. - «Назад» в браузере менял только адрес. Теперь «Назад» и «Вперёд» восстанавливают форму и выдачу, по одному запросу.
- Управление формой из кода. Ползунок, выставленный из кода, двигается одним вызовом, и в запрос уходят точные границы, а не округлённые до шага. Селекты, текстовые поля и диапазоны сбрасываются, когда фильтр снят. Выбранная опция селекта больше не блокируется счётчиками.
Внимание при обновлении
Вызовы JS API отправляют запрос сами
setFilter() и removeFilter() раньше только меняли состояние, запрос уходил по submit(). Теперь запрос уходит сам. Цепочка setFilter(...).submit() по-прежнему отправляет один запрос, а код, который вызывал setFilter(), чтобы отметить значения без отправки, теперь получит запрос.
setSort(), setLimit() и setTpl() отправляют запрос не внутри вызова, а в следующей микрозадаче. Код, который сразу после setSort() проверял state.loading === true, увидит false.
Фильтры без type в наборе
Касается наборов, заданных списком ключей (["price", "color"]), и записей без type, внесённых в JSON вручную. Наборы, сохранённые в админке, тип задают всегда и не затронуты.
Тип назначается по ключу фильтра, поле field не учитывается:
| Ключи | Тип |
|---|---|
price, old_price, weight, width, height, length, menuindex, template, parent | number |
new, popular, favorite, published, deleted, hidemenu, isfolder, searchable, cacheable, richtext | boolean |
publishedon, createdon, editedon, pub_date, unpub_date, deletedon | date |
| остальные | default |
Типы parents, ms3_categories, vendors и colors для вывода и подсчёта значений по ключу не назначаются — задайте их в type явно.
До обновления форма считала такие фильтры числовыми и пропускала все нечисловые блоки. Теперь она выводит их с типом сервера, поэтому на странице могут появиться блоки, которых раньше не было.
Адреса фильтров по разделам
Адреса страниц фильтра по разделам (типы parents и ms3_categories) сменятся с category--15 на category--nazvanie-razdela. Старые адреса с id продолжают открываться.
