Наверх

Простой AJAX-фильтр для MODX с помощью pdoPage

Да, ещё один способ реализации Ajax-фильтра на сайте =)

Начнём с простого вывода на странице обычного списка ресурсов. Обязательно добейтесь, чтобы нормально работала AJAX-пагинация, потому что своих механизмов работы с AJAX мы писать не будем, а будем использовать методы AJAX, которые есть в pdoPage.

<div id="pdopage">
  <div class="rows row">
  {'!pdoPage' | snippet : [
    'ajaxMode' => 'default',
    
    'parents' => 0,
    'limit' => 3,
    
    'includeTVs' => 'height,weight,speed_type,price',
    'tvPrefix' => '',
    
    'tpl' => '@INLINE 
      <div class="col-sm-6 col-md-4">
        <div class="thumbnail">
          <div class="caption">
            <h3>{$pagetitle}</h3>
            <p>Вес: {$weight}</p>
            <p>Высота: {$height}</p>
            <p>Тип: {$speed_type}</p>
          </div>
        </div>
      </div>',
  ]}
  </div>
  {'page.nav' | placeholder}
</div>


Для фильтров я буду использовать такую вёрстку. Но вёрстка тут особой роли не играет — главное указать правильные классы в JS-коде.

<form class="form-horizontal" id="filters" action="">
  <div class="form-group">
    <label class="col-sm-1 control-label">Вес</label>
    <div class="col-sm-5">
      <input type="number" name="weight" class="form-control" placeholder="47">
    </div>
    <label class="col-sm-1 control-label">Высота</label>
    <div class="col-sm-5">
      <input type="number" name="height" class="form-control" placeholder="120">
    </div>
  </div>
  
  <div class="form-group">
    <label class="col-sm-1 control-label">Тип</label>
    <div class="col-sm-11">
      <div class="btn-group" data-toggle="buttons">
        <label class="btn btn-default">
          <input type="radio" name="speed_type" value="fast"> Быстрые
        </label>
        <label class="btn btn-default">
          <input type="radio" name="speed_type" value="slow"> Медленные
        </label>
      </div>
    </div>
  </div>

  <div class="form-group">
    <label class="col-sm-1 control-label">Цена</label>
    <div class="col-sm-11">
      <div class="btn-group" data-toggle="buttons">
        <label class="btn btn-default">
          <input type="checkbox" name="price[]" value="0-20000"> до 20 000 руб.
        </label>
        <label class="btn btn-default">
          <input type="checkbox" name="price[]" value="20000-50000"> 20 000—50 000 руб.
        </label>
        <label class="btn btn-default">
          <input type="checkbox" name="price[]" value="50000-100000"> 50 000—100 000 руб.
        </label>
        <label class="btn btn-default">
          <input type="checkbox" name="price[]" value="100000-"> от 100 000 руб.
        </label>
      </div>
    </div>
  </div>
</form>

JS-код обработки фильтров выглядит как-то так:

$(document).on('change keyup', '#filters input', function(){
    // Проверяем, что pdoPage подключён
    if (typeof(pdoPage) == 'undefined') return;
    
    // Собираем значения всех фильтров в единый массив
    var fields = {};
    $.each($('#filters').serializeArray(), function(){
        // Если параметр не является массивом (чекбоксом), то все просто
        if (this.name.indexOf('[]') <= 0) {
            fields[this.name] = this.value;
        } else {
            // Для чекбоксов посложнее
            var name = this.name.replace('[]','');
            if (typeof(fields[name]) == 'undefined') {
                fields[name] = [];
            }
            fields[name].push(this.value);
        }
    });
    
    // И отправляем этот массив на сервер.
    $.post(document.location.href, {
            action: 'filter',
            fields: fields,
            // Параметр hash - обязательный (он содержит настройки pdoPage)
            hash: pdoPage.configs.page.hash
        }, function(data) {
            // Просим pdoPage загрузить новый список ресурсов
            var tmp = document.location.href.split('?');
            pdoPage.keys.page = 0;
            pdoPage.loadPage(tmp[0], pdoPage.configs.page);
        });
});

Уже сейчас при изменении значения фильтров список ресурсов будет обновляться. Теперь осталось «объяснить», как обрабатывать фильтры. Для этого создаём плагин на событие OnHandleRequest:

<?php
if ($modx->context->key == 'mgr' || empty($_SERVER['HTTP_X_REQUESTED_WITH']) || $_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest') return;
switch ($_POST['action']) {
    case 'filter':
        $output = array('success' => false, 'message' => '');
        
        // Проверяем, что hash получен и параметры pdoPage существуют
        if (isset($_POST['hash']) && !empty($_POST['hash'])
            && isset($_SESSION['pdoPage'][$_POST['hash']])
            && !empty($_SESSION['pdoPage'][$_POST['hash']])) {

            $hash = (string) $_POST['hash'];
            
            // Указываем только ТВ, доступные для фильтрации
            $tvs = array('height','weight','speed_type');
            
            // Наполняем условие выборки
            $where = array();
            foreach ($tvs as $tv) {
                switch ($tv) {
                    case 'price[]':
                        // Пример обработки чекбоксов
                        if (isset($_POST['fields']['price']) && !empty($_POST['fields']['price'])) {
                            $where_price = [];
                            foreach ($_POST['fields']['price'] as $range) {
                                $value = explode('-', $range);
                                if (count($value) != 2) {
                                    continue;
                                }
                                $min = (int) $value[0];
                                $max = (int) $value[1];
                                $where_range = 'CAST(`TVprice`.`value` AS DECIMAL(13,3)) >= ' . $min;
                                if ($max) {
                                    $where_range .= ' AND CAST(`TVprice`.`value` AS DECIMAL(13,3)) <= ' . $max;
                                }
                                $where_price[] = '(' . $where_range . ')';
                            }
                            $where[] = '(' . implode(' OR ', $where_price) . ')';
                        }
                        break;
                    default:
                        if (isset($_POST['fields'][$tv]) && $_POST['fields'][$tv] !== '') {
                            $where[$tv] = $_POST['fields'][$tv];
                        }
                        break;
                }
            }
            
            // Добавляем это условие в параметры pdoPage "на лету"
            $_SESSION['pdoPage'][$hash]['where'] = $where;
            
            $output['message'] = $where;
            $output['success'] = true;
        } else {
            $output['message'] = 'Error';
        }
        echo $modx->toJSON($output);
        die();
        break;
    default:
        break;
}

Теперь наши фильтры работают. Единственное — pdoPage «не знает», что показывать, когда ни один результат не найден. Чтобы такой случай учесть, создадим файл pdopage.custom.js и укажем его в параметре frontend_js:

{'!pdoPage' | snippet : [
    'ajaxMode' => 'default',
    'frontend_js' => '/assets/components/pdotools/js/pdopage.custom.js',

    'parents' => 0,
    'limit' => 3,
    // ...
}

В стандартном коде мы добавим только условие else на случай, если ответ от сервера будет пустым:

// ...
pdoPage.loadPage = function (href, config, mode) {

    // ...

    $.post(config['connectorUrl'], params, function (response) {
        if (response && response['total']) {
            // ...
        } else { // Добавляем условие else
            wrapper.find(rows).html('Ничего не найдено');
            wrapper.find(pagination).html('');
            wrapper.removeClass('loading');
            wrapper.css({opacity: 1});
            if (config['mode'] == 'default') {
                $('html, body').animate({scrollTop: wrapper.position().top - 50 || 0}, 0);
            }
        }
    }, 'json');
};
// ...

На этом простой AJAX-фильтр готов.


44 комментария

  1. Алексей Архипенко 11 марта 2019, 14:39(Комментарий был изменён) # 0
    Что-то не работает фильтр, а куда последний код добавлять нужно?

    С Уважением,

    Алексей
    1. Илья Уткин 11 марта 2019, 14:50 # 0
      Надо скопировать стандартный JS-файл от pdoTools и в этой копии внести нужные изменения.
    2. Ishvan 07 апреля 2019, 14:10 # 0
      Уже сейчас при изменении значения фильтров список ресурсов будет обновляться. Теперь осталось «объяснить», как обрабатывать фильтры. Для этого создаём плагин на событие OnHandleRequest:
      вот дошел до сюда… но не происходит изменений в списках ресурсов
      1. Илья Уткин 08 апреля 2019, 07:08 # 0
        Изменений и не должно быть. Список должен просто обновляться — «мигать».
      2. Илья 20 апреля 2019, 23:39 # 0
        Огромное спасибо. Метод рабочий.
        Можете помочь с дополнением таким.
        Добавил в вызов условие:
        &where=`[[!#GET.where]]`
        В него передаются параметры:
        <div class="dropdown-menu">
        <a class="dropdown-item" href="[[~[[*id]]]]">Все</a>
        <div class="dropdown-divider"></div>
        <a class="dropdown-item" href="[[~[[*id]]]]?where=team_p1 > team_p2">Победы</a>
        <a class="dropdown-item" href="[[~[[*id]]]]?where=team_p1 = team_p2">Ничьи</a>
        <a class="dropdown-item" href="[[~[[*id]]]]?where=team_p1 < team_p2">Поражения</a>
        </div>
        
        Т.е. сравниваются значения ТВ у ресурса и выводятся как надо.
        Получается ваш метод работает как Ajax, а мои ссылки перезагружают страницу и фильтр по ajax скидывается.
        Вот мне нужно это всё как то соединить. Помогите с решением.
        1. Илья Уткин 22 апреля 2019, 15:52 # 0
          Вам нужно переделывать ваши ссылки на AJAX-поля, как speed_type в примере.
          1. Илья 23 апреля 2019, 09:13(Комментарий был изменён) # 0
            Добрый день!
            Нужна помощь.
            Фильтр переделал.
            Сезон - Вид игры - Турнир - это фильтр
            Ниже должно отображаться, то что выбрали в фильтре, т.е. например так?
            Фильтр: 2018, Регби-15, Чемпионат Москвы
            И ниже:
            Всего матчей: 22
            Побед: 10
            Ничьих: 5
            Поражений: 7
            А только потом уже результаты… Готов отблагодарить.
        2. Илья 22 апреля 2019, 16:03 # 0
          Спасибо за ответ. Так и сделал.
          1. Дмитрий 07 июня 2019, 18:09 # 0
            А как тут сделать ценовой ползунок?
            1. Николай 12 июня 2019, 19:43 # 0
              Спасибо большое за такое замечательное и функциональное решение!!!
              Подскажите, пожалуйста, а как сделать так, чтобы результат запроса подгружался не «на лету», а после нажатия кнопки? но при этом страница полностью не перезагружалась?
              1. Андрей 30 июля 2019, 13:56 # 0
                Подскажите пожалуйста, никак не могу составить условие between, такое ощущение, что передается строка, а не целое число. Вот код:
                // фильтр цена
                            if(!empty($_POST['fields']['price_from']) && empty($_POST['fields']['price_to'])) {
                                $where['cost:>='] = (int) $_POST['fields']['price_from'];
                            }
                            elseif(!empty($_POST['fields']['price_from']) && !empty($_POST['fields']['price_to'])  && (int)$_POST['fields']['price_to'] != 10000) {
                                $where[] = array(
                                        'cost:>=' => (int) $_POST['fields']['price_from'],
                                        'AND:cost:<=' => (int) $_POST['fields']['price_to']
                                    );
                            }elseif(!empty($_POST['fields']['price_to'])  && (int)$_POST['fields']['price_to'] != 10000) {
                                $where['cost:<='] = (int) $_POST['fields']['price_to'];
                            }
                1. Илья Уткин 30 июля 2019, 14:02 # 0
                  ТВ в MODX хранятся в виде текста. Вам нужно добавить в запрос преобразование типа данных. Вот, например, сортировка с преобразованием типа: ilyaut.ru/cheats/sorting-on-tv-number-for-pdoresources/
                  1. Андрей 30 июля 2019, 15:27 # 0
                    Спасибо переписал, заработало, может кому поможет:
                    $where[] = 'CAST(`TVcost`.`value` AS DECIMAL(13,3)) >= ' . (int)$_POST['fields']['price_from'] . ' AND CAST(`TVcost`.`value` AS DECIMAL(13,3)) <= ' . (int)$_POST['fields']['price_to'];
                2. Кирилл 02 августа 2019, 15:02 # 0
                  Здравствуйте. Спасибо за статью, у меня получилось сделать фильтр как написано и все работает. Мне не хватает функционала фильтрации и не достает опыта доработать. Я хочу сделать фильтр с чек-боксами, чтобы был множественный выбор. Например, цвет: белый, синий, красный. В ресурсах сделать TV color с чек-боксами: white||blue||red. В html добавил в плагине указал $tvs = array('color');
                  В результате сейчас получаю два вопроса:
                  1) при выборе одновременно нескольких чек-боксов в фильтре — выводятся только ресурсы с соответствием только 1 чек-боксу
                  2) если в ресурсе, в TV отмечено несколько значений, например white||blue, то при выборе фильтра только по чек-боксу white этот товар не будет показан
                  Буду признателен, как все читатели блога, если вы сможете дополнить функционал.
                  1. Islam 29 августа 2019, 05:14 # 0
                    Доброго времени суток. Хотел узнать, нашли ли Вы решение данной проблемы?
                    1. Илья Уткин 29 августа 2019, 08:10 # 0
                      Это не такая простая задача, как кажется на первый взгляд. Тут надо серьёзно дорабатывать выборку и фильтрацию. Если у вас есть небольшой бюджет, напишите мне на ilyautkin@mail.ru — обсудим стоимость и я вам помогу. Потом решение можно будет оформить и выложить для всеобщего доступа.
                  2. roflman 31 октября 2019, 06:09(Комментарий был изменён) # 0
                    Твшка отправляется, данные нормальные в хэше она в where стоит, но все равно не меняются даные на странице, моргает да, но все остается на своих местах, получается
                    феном обязательно нужен?
                    В кэше пдо показывает значение вхере, есил их вписать в ручную при загрузке странице выведет необходимое, но не филттрует, если я включаю феном страница полностью вешается

                    Сам плагин
                    <?php
                    switch ($_POST['action']) {
                        case 'filter':
                            $Data = $_POST;
                            $output = array('success' => false, 'message' => '');
                            
                            // Проверяем, что hash получен и параметры pdoPage существуют
                            if (isset($Data['hash']) && !empty($Data['hash'])
                                && isset($_SESSION['pdoPage'][$Data['hash']])
                                && !empty($_SESSION['pdoPage'][$Data['hash']])) {
                    
                                $hash = (string) $Data['hash'];
                                
                                // Наполняем условие выборки
                                $where = array();
                                $ds = "";
                                foreach($Data['fields'] as $key => $value){
                                    switch ($key){
                                        case 'range':
                                            $range_TV = $key['range_field'];
                                            $where_filter = [];
                                            $min = $key['_from'];
                                            $max = $key['_to'];
                                            //range:{'range_field':'hui',_from:2500,_to:5236}
                                            $where_range = "AST(`TV{$range_TV}`.`value` AS DECIMAL(13,3)) >= {$min}";
                                            if ($max) {
                                                $where_range .= " AND CAST(`TV{$range_TV}`.`value` AS DECIMAL(13,3)) <= {$max}";
                                            }
                                            $where_filter[] = '(' . $where_range . ')';
                    
                                            $where[] = '(' . implode(' OR ', $where_filter) . ')';
                                            break;
                                        default:
                                            if (isset($key) && $key !== '' && $key != 'official') {
                                                $where[$key] = $value;
                                            }
                                            break;
                                    }
                                }
                                // Добавляем это условие в параметры pdoPage "на лету"
                                $_SESSION['pdoPage'][$hash]['where'] = $modx->toJSON($where);
                                
                                $output['message'] = $where;
                                $output['success'] = true;
                            } else {
                                $output['message'] = 'Error';
                            }
                            echo $modx->toJSON($output);
                            die();
                            break;
                        default:
                            break;
                    }
                    
                    сам вывод на странице

                        						[[!pdoPage?
                            						&parents=`[[*id]]`
                            						&tpl=`FilteredItem`
                            						&element=`msProducts`
                            						&depth=`4`
                            						&level=`4`
                            						&limit=`9`
                            						&where=`{"template:=":5}`
                            						&ajaxMode=`default`
                            						&ajaxElemWrapper=`#w0`
                            						&ajaxElemRows=`#w0 .rows`
                            						&ajaxElemPagination=`.pagination`
                            						&ajaxElemLink=`.pagination a`
                            						&pageLimit=`3`
                            						&tplPageFirstEmpty=``
                            						&tplPageLastEmpty=``
                            						&tplPageLast=``
                            						&tplPageActive=`@INLINE <li><a href="[[+href]]">[[+pageNo]]</a></li>`
                            						&tplPageFirst=``
                            						&tplPageSkip=`@INLINE <li class="disabled"><span>...</span></li>`
                            						&tplPagePrev=`@INLINE <li class="control"><a href="[[+href]]"><</a></li>`
                            						&tplPageNext=`@INLINE <li class="control"><a href="[[+href]]">></a></li>`
                            						&includeTVs=`tv.image,wheel_diametr,wheel_load_index,wheel_name,wheel_price,wheel_profile,wheel_quantity,wheel_speed_index,wheel_symbol_speed_index,is_summer__or__winter_tyre2,wheel_vendor,wheel_width,wheel_load_index_from`
                        						]]
                    
                    1. Илья Уткин 31 октября 2019, 07:28 # 0
                      Здравствуйте. Напишите на почту ilyautkin@mail.ru — помогу настроить.
                    2. Maksim 20 мая 2020, 14:16 # 0
                      Спасибо за статью! Фильтрация работает с пагинацией из коробки. Но при режиме «Загрузка кнопкой»:

                      <div id="pdopage">
                          [[!+page.nav]]
                          <div class="rows">
                              [[!pdoPage?
                                  &parents=`0`
                                  &ajaxMode=`button`
                                  &limit=`5`
                              ]]
                          </div>
                      </div>
                      


                      Кнопка не отрисовывается в зависиомсти от результата (только при перезагрузки страницы), пример: перезагружаю страницу, кнопка «показать еще», жму на нее до тех пор пока загружать нечего — кнопка прячется. Жму на фильтр — фильтр срабатывает, выводятся нужные ресурсы, но кнопка не появляется, хотя должна, ресурсов больше чем параметре &limit.

                      Решается это как-то?
                      1. Илья Уткин 20 мая 2020, 14:48 # 0
                        Неа, я, к сожалению, с такой задачей не сталкивался. Если найдёшь решение, напиши здесь, пожалуйста — для будущих запросов.
                        1. Илья Р 04 июля 2020, 23:09(Комментарий был изменён) # 0
                          Доброго дня, решил эту проблему так (только у меня пагинация &mode='scroll', но это судя по всему не важно), когда вы доходите до конца пагинации, то свойство pdoPage.Reached становится true и пагинация заканчивается, чтобы при клике по фильтру убрать эту беду попробуйте вписать в js перед загрузкой нового списка ресурсов:

                          // чтобы пагинация пагинила)
                          pdoPage.Reached = false;
                          
                          pdoPage.keys.page = 0;
                          pdoPage.loadPage(tmp[0], pdoPage.configs.page);
                          
                          И спасибо Илье Уткину за статью, смог сделать фильтрацию по опциям товара
                          1. Alexandr Ivashchenko 08 октября 2021, 01:21(Комментарий был изменён) # 0
                            а можете пожалуйста уточнить. куда конкретно вставить эти строки нужно? я сюда добавил но не работает так…
                            // И отправляем этот массив на сервер.
                                        $.post(document.location.href, {
                                                action: 'filter',
                                                fields: fields,
                                                // Параметр hash - обязательный (он содержит настройки pdoPage)
                                                hash: pdoPage.configs.page.hash
                                            }, function(data) {
                                                // Просим pdoPage загрузить новый список ресурсов
                                                var tmp = document.location.href.split('?');
                                                // чтобы пагинация пагинила)
                                                pdoPage.Reached = false;
                                                
                                                pdoPage.keys.page = 0;
                                                pdoPage.loadPage(tmp[0], pdoPage.configs.page);
                                                
                                            });
                            1. Александр 07 февраля 2022, 08:42 # 0
                              я решил это просто, напишите просто что-то типа такого

                              $('.btn-more').show() внутри вызова function(data)
                              1. Александр 07 февраля 2022, 09:43 # 0
                                хотя она и не выключается
                            2. Александр 07 февраля 2022, 08:41 # 0
                              Reached — это событие для скролла
                              в случае с button — она просто пропадает
                            3. Danik 12 января 2023, 14:20 # 0
                              Добавьте колбэке в js:
                              $.post(document.location.href, {
                                          action: 'filter',
                                          fields: fields,
                                          // Параметр hash - обязательный (он содержит настройки pdoPage)
                                          hash: pdoPage.configs.page.hash
                                      }, function(data) {
                                          // Просим pdoPage загрузить новый список ресурсов
                                          var tmp = document.location.href.split('?');
                                          pdoPage.keys.page = 0;
                                          pdoPage.loadPage(tmp[0], pdoPage.configs.page);
                              	    //Добавить строчки ниже
                                          pdoPage.callbacks.after = function(config, response) {
                              		if (response.total <= config.pageLimit || response.page == response.pages) {
                              			$(config.more).hide();
                              		} else {
                              			$(config.more).show();
                              		}
                              		$('#pdopage').removeClass('loading');
                                              $('#pdopage').css('opacity', 1);
                              	    }
                                      });
                              
                            4. Иван 01 июня 2020, 09:55 # 0
                              Подскажите. А как сделать сброс фильтров.
                              1. Илья Уткин 01 июня 2020, 11:02 # 0
                                Можно просто обновить страницу — тогда будет показан результат без фильтрации.
                                1. Иван 01 июня 2020, 12:59 # 0
                                  Без перезагрузки надо. Просто сбросить фильтры
                                  1. Илья Уткин 01 июня 2020, 13:10 # 0
                                    Напишите на ilyautkin@mail.ru — думаю, рублей за 500 могу доработать, добавить такую кнопку. Нужны будут доступы.
                              2. Вадим 08 июня 2020, 12:56 # 0
                                Здравствуйте, Илья! Заранее извиняюсь за возможно глупый вопрос, но подскажите пожалуйста, как можно отследить то, что записывает плагин в параметр where?
                                1. Илья Уткин 08 июня 2020, 13:38 # 0
                                  Что значит «отследить»? Если нужно просто посмотреть структуру, то можно добавить здесь запись в лог:

                                  // Добавляем это условие в параметры pdoPage "на лету"
                                  $_SESSION['pdoPage'][$hash]['where'] = $where;
                                  $modx->log(1, 'WHERE: ' . print_r($where, true));
                                2. Яна 07 декабря 2020, 23:27 # 0
                                  Огонь спасибо) очень помог, надо было фильтр буквально по двум полям, а покупать компонент за 3000 не хотелось =)
                                  1. Moisey 01 декабря 2021, 12:58 # 0
                                    Низкий поклон дружище! Это как раз, то что мне сейчас нужно. С твоей помощью сделал очень быстро фильтрацию и сортировку.
                                    1. Александр 07 февраля 2022, 08:44 # 0
                                      Здравствуйте, Илья.
                                      Вопрос вот в чем. Подскажите, пожалуйста, как реализовать эту фильтрацию со своим id, вместо id=«pdoPage» и с несколькими id, если на странице несколько независимых выводов pdopage, каждый из которых со своей работающей пагинации по кнопке?
                                      1. Илья Уткин 07 февраля 2022, 09:15 # 0
                                        Думаю, вам нужен параметр ajaxElemWrapper, ну и остальные — ajaxElemRows, ajaxElemPagination, ajaxElemLink
                                        1. Александр 07 февраля 2022, 09:30 # 0
                                          я с ними и делаю и все работает. Но в случае с применением Вашего фильтра в консоли ошибка " Uncaught TypeError: Cannot read properties of undefined (reading 'hash') "

                                          {'!pdoPage' | snippet: [
                                          'includeContent'=>1,
                                          'parents' => 35,
                                          'sortby' => 'publishedon',
                                          'sortdir' => 'DESC',

                                          'limit'=> 12,
                                          'totalVar' => 'reviewsPdo_total',
                                          'pageVarKey' => 'reviewsPdo',
                                          'pageNavVar' => 'reviewsPdo_nav',

                                          'ajaxMode' => 'button',
                                          'ajaxElemMore' => '#reviewsPdo .btn-more',
                                          'ajaxTplMore' => '@INLINE Показать еще',

                                          'ajaxElemWrapper'=> '#reviewsPdo',
                                          'ajaxElemRows' => '#reviewsPdo .rows',
                                          'ajaxElemPagination' => '#reviewsPdo .pagination',
                                          'ajaxElemLink' => '#reviewsPdo .pagination a',

                                          'includeTVs' => '',
                                          'tvPrefix' => '',
                                          'tpl' => '@FILE chunk/reviews/reviews__item.tpl',
                                          'toPlaceholder' => 'reviewsPdo',
                                          ]}
                                          {if $_modx->getPlaceholder('reviewsPdo_total') != 0}
                                          {$_modx->getPlaceholder('reviewsPdo')}


                                          {$_modx->getPlaceholder('reviewsPdo_nav')}




                                          {/if}

                                          1. Илья Уткин 07 февраля 2022, 10:04 # 0
                                            А, ну надо смотреть, как в JS на странице указывается hash и поменять код, который его отправляет на сервер. Тут я не помощник — сам с такой задачей не сталкивался
                                            1. Александр 07 февраля 2022, 11:07 # 0
                                              да, благодарю
                                      2. Danny 08 февраля 2022, 07:48 # 0
                                        А как бы обновить плейсхолдер total на странице? Он у меня как показывает первоначальное количество так и остается, хотя сбоку от него находится навигация и она прекрасно обновляется
                                        1. Сергей 25 февраля 2023, 13:47 # 0
                                          Илья, добрый день!
                                          А как быть с migx? По ним в тема не затронута совсем к сожалению. А на практике таких TV встречается много. Как фильтровать по полю таких TV. Какие изменения потребует плагин на примере ниже, если само TV — migx_size, а поле по которому нужно фильтрануть — size
                                          case 'migx_size':
                                          if (isset($_POST['fields']['migx_size']) && $_POST['fields']['migx_size'] !== '') {
                                          $where['migx_size'] = $_POST['fields']['migx_size'];
                                          }
                                          break;
                                          1. Илья Уткин 27 февраля 2023, 03:51 # 0
                                            Добрый день. Да, для поля MIGX вам нужно писать отдельный обработчик.
                                          2. Денис 11 августа 2023, 18:13(Комментарий был изменён) # 0
                                            Доброго. У меня не получилось сделать, чтобы заработало. У меня такой вопрос, сниппет OnHandleRequest он как видит? А то я его создал, но негде не указал, может я что-то упускаю?

                                            Или он сам срабатывает при отправке запроса?
                                            1. Danny 25 августа 2023, 10:20 # 0
                                              OnHandleRequest — это системное событие для плагина, а не для сниппета. Если хотите фильтровать сниппетом, то он должен вызываться на той же странице, где находится форма и в нем не надо будет проверять событие, а просто отлавливать Ajax-запрос.

                                            Авторизация

                                            через сервис Loginza:


                                            Шаблоны MODX

                                            1 2 Дальше »

                                            Объектная
                                            модель
                                            MODX