[СДЕЛАЙ САМ] mFilter2 фильтрация по диапазону дат.

Приветствую, к сожалению не нашёл приемлемого для себя решения данной задачи поэтому «написал» своё, в кавычках потому что немного подправил. На мой взгляд очевидно, что дата это число, а в mFilter2 есть фильтрация по диапазону чисел, значит нужно превратить дату в число. Чтобы при обновлении компонента ничего не сломалось, создадим свой класс фильтрации customfilter.class.php в папке core/components/msearch2/custom/filters/, потом прописываем в системную настройку mse2_filters_handler_class = CustomFiltersHandler
<?php

class CustomFiltersHandler extends mse2FiltersHandler
{
    public function buildDateRangeFilter(array $values, $name = '') {
        $tmp = array_keys($values);
        if (empty($values) || (count($tmp) < 2 && empty($this->config['showEmptyFilters']))) {
            return array();
        }

        sort($tmp);
        if (count($values) >= 2) {
            $min = array_shift($tmp);
            $max = array_pop($tmp);
        }
        else {
            $min = $max = $tmp[0];
        }

        $output = array(
            array(
                'title' => 'с',
                'value' => strtotime($min),
                'type' => 'decimal',
                'resources' => null,
                'name' => $name,
            ),
            array(
                'title' => 'по',
                'value' => strtotime($max),
                'type' => 'decimal',
                'resources' => null,
                'name' => $name,
            )
        );

        return $output;
    }

    public function filterDateRange(array $requested, array $values, array $ids) {
        $matched = array();

        foreach ($requested as $k => $v) {
            $requested[$k] = strtotime($v);
        }

        $min = min($requested);
        $max = max($requested) + 24 * 60 * 60;

        $tmp = array_flip($ids);
        foreach ($values as $number => $resources) {
            $number = strtotime($number);
            if ($number >= $min && $number <= $max) {
                foreach ($resources as $id) {
                    if (isset($tmp[$id])) {
                        $matched[] = $id;
                    }
                }
            }
        }

        return $matched;
    }
}
$max = max($requested) + 24 * 60 * 60; // прибавляем сутки на случай если начальная и конечные даты совпадают.
Это собственно почти всё. В вызов mFilter2 пишем
...
'filters' => ' resource|createdon:daterange'
...
Чанк tplFilter.outer.order|createdon у меня такой
<fieldset id="mse2_{$table ~ $delimeter ~ $filter}">
    <h4 class="filter_title h-6">Укажите период</h4>
    <div class="mse2_number_inputs row form">
        {$rows}
    </div>
</fieldset>
От стандартного чанка tpl.mFilter2.filter.slider он отличается только отсутствием слайдера, потому как к датам такой подход неприменим.
Чанк tplFilter.row.order|createdon выглядит так
{var $key = $table ~ $delimeter ~ $filter}
<div class="col-md-3 mb-3">
    <label for="mse2_{$key}_{$idx}" class="d-flex align-items-center justify-content-between">
        <input type="text" name="{$filter_key}" id="mse2_{$key}_{$idx}" value="{$value | date: 'd.m.Y'}"
               data-current-value="{$current_value | date: 'd.m.Y'}" class="bordered jsDate {$title == 'с' ? 'jsDateStart' : 'jsDateEnd'}"/>
    </label>
</div>
Тут я по title расставляю классы, чтобы понимать где какая дата, но в целом это не обязательно, потому как с классе фильтрации используются функции min/max, мне это нужно было для другой логики. Также к обоим полям я подключил <a href="http://t1m0n.name/air-datepicker/docs/index-ru.html">плагин для вывода календаря</a>, чтобы удобнее было выбирать даты. И всё работает. По-моему всё просто, надеюсь будет полезно не только мне.
Артур
29 марта 2021, 00:14
modx.pro
8
550
+8
Поблагодарить автора Отправить деньги

Комментарии: 1

Александр Мельник
29 марта 2021, 08:23
0
спасибо что поделились.
    Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
    1