Фильтрация pdoPage и другие вопросы.

Всем добрый день.

Я не так давно начал работать с Modx, ранее занимался фронтендом. Столкнулся со следующей проблемой, может кто-то поможет ее решить или натолкнет на мысль, как сделать.

У меня есть Категории карточек товара, карточки у меня сделаны простыми ресурсами и выводятся через pdoPage.

Получается структура такая

Главная
Каталог 
    Блок услуг 1
        - услуга 1.1
        - услуга 1.2
        - услуга 1.3
    Блок услуг 2
        - услуга 2.1
        - услуга 2.2
        - услуга 2.3
Особенностью данного проекта является то, что на странице «Каталог» у нас есть список всех услуг в виде блока (в котором первая услуга показана), а остальные услуги входящие в этот блок просто открываются по нажатию на кнопку. По большому счету просто раскрывая остальные.


В более простом варианте это выглядит так, кнопка открыть показывает все остальные услуги этого раздела. Получается в случае «услуга 1.1» показыает услугу 1.2 и 1.3

================= 
=  Услуга 1.1    =   
=    открыть     =
=================
============= ====
=  Услуга 2.1    =   
=    открыть     =
=================
Я сделал это следующим образом

В шаблоне Каталога

[[pdoPage?
                           &parents=``
                           &depth=`1`
                           &resources=``
                           &where=`{"isfolder":"1"}` 
                           &tvPrefix=`0`
                           &tpl=`catalog-tpl`
                           &sortby=`{"menuindex":"ASC"}`
                           
                        ]]


А catalog=tpl

<div class="mb-4">
  
  [[pdoPage?
    &parents=`[[+id]]`
    &depth=`1`
    &limit=`1`
    &resources=``
    &where=`{"isfolder":"0"}` 
    &tvPrefix=`0`
    &tpl=`first-in-catalog`
    &sortby=`{"menuindex":"ASC"}`
    &includeTVs=`bet, sum, timet`
    &my= `[[+id]]`
]]  
  
  <div
    class="offer-card b-hidden _js_toggle-block"
    data-toggle-target="bank-offers-[[+id]]"
    data-toggle-group="bank-[[+id]]"
  >
    <div class="group-last-child">
        [[pdoPage?
            &parents=`[[+id]]`
            &depth=`1`
            &limit=``
            &offset=`1`
            &resources=``
            &where=`{"isfolder":"0"}` 
            &tvPrefix=`0`
            &tpl=`all-next-in-catalog`
            &sortby=`{"menuindex":"ASC"}`
            &includeTVs=`bet, sum, timet`
            
        ]]  

    </div>
  </div>
</div>

В целом карточки у меня работают исправно (первая выводится, остальные в аккордеоне), но тут возникли 3 вопроса:

1) Как можно сделать фильтрацию этих данных? То есть у меня есть фильтр и я в целом 3 дня искал в интернете решения, но почему-то не нашел. У меня получается есть поле, есть селект, есть чекбоксы и эти данные мне нужно фильтровать.

Могли бы вы подсказать в каком направлении мне копать? Я написал решение, которое проверяет все поля и формирует json и отправляет его через fetch на сервер. Но мне не понятно как его принимать и как обрабатывать, чтобы выбор работал.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title><?="Новая страница";?></title>
    <style>
      form {
        display: flex;
        flex-direction: column;
        max-width: 200px;
      }
    </style>
  </head>
  <body>
    <form id="formElem">
      <input type="text" name="name" />
      <input type="text" name="surname"/>
      <input type="checkbox" name="input">
      <select name="select">
        <option name="first" id="">Первый</option>
        <option name="two" id="">Второй</option>
      </select>
      <input type="submit" />
    </form>
  </body>
  <?php require 'point.php';?>
  <script>

     let formOne = document.querySelector('#formElem')

     formOne.onsubmit = async (e) => {
      e.preventDefault();
    

      let arrayFromForm = Array.from(formOne).filter((elem) => !!elem.value).map((elem) => {
        const {name, type} = elem;
        const value = type === 'checkbox' ? elem.checked : elem.value;
        return {name, value};
      })

      let response = await fetch('http://lesson-4/point.php', {
        method: 'POST',
        body: JSON.stringify(arrayFromForm),

      });

      alert(result.message);
    };
  </script>
</html>

Может я усложняю и есть решение проще :)

2) И если не затруднит посмотрите, правильно ли я продумал структуру или опять же есть варианты проще, а я их не знаю.

3) Где в целом можно прочитать подробную документацию с примерами по API modx, а так же по тому, как все работает внутри?

Прошу прощения за большой текст, очень хотелось бы разобраться :) Спасибо))
Разработчик
18 декабря 2022, 13:43
modx.pro
1 049
0

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

Артур Шевченко
18 декабря 2022, 17:47
+1
1) Как можно сделать фильтрацию этих данных?
Непонятно причём тут pdoPage, но если это каталог, то проще использовать связку MiniShop2 + mSearch2(для фильтрации); По поводу того как принимать данные с фронта можешь почитать тут

И если не затруднит посмотрите, правильно ли я продумал структуру или опять же есть варианты проще, а я их не знаю.
Структуру надо определять исходя из задачи и здравого смысла. Задачи мы не знаем.

Где в целом можно прочитать подробную документацию с примерами по API modx, а так же по тому, как все работает внутри?
Моё мнение: нет смысла читать всю документацию без разбора, всё равно всё не запомнишь. А так есть официальный сайт с документацией многое даже перевели на русский.
    Разработчик
    22 декабря 2022, 01:38
    0
    Спасибо за ответ)

    Тут не совсем стандартный проект, тут получается как каталог продуктов, что-то вроде рейтинга. Как такового каталога там нет.

    Я решил проблему через where у pdoResources

    Может косячно, но пока работает

    1. Вот тут я собрал все контейнеры (папки) в которых лежат ресурсы. Так как все ресурсы выводятся на одной странице по папкам. Где первый элемент наверху, остальные скрыты в контейнере, то сделал так.

    <div class="py-8 bg-light">
                    <div class="container">
                        <div class="group-last-child">
                            [[!pdoResources?
                               &depth=`1`
                               &where=`{"isfolder":"1"}`
                               &tvPrefix=``
                               &tpl=`Tpl-lvl-1-catalog-All-Deposits`
                               &sortby=`{"menuindex":"ASC"}`
                               &includeTVs=`valuta, time-if-deposit`
                            ]]       
                        </div>
                    </div>
                </div>

    На этот этапе я фильтрую результат, сделав сниппет-обертку
    Total — мне нужно для того, чтобы знать сколько элементов в папке и сравнивать с последним. Сравнивать с последним нужно для закрывающего тэга обертки. А открывается тег обертки на втором.

    [[!mySnippetFilter?
       &parents=`[[+id]]`
       &depth=`5`
       &tplFirst=``
       &resources=``
       &tvPrefix=``
       &tpl=`Tpl-lvl-2-Bank-All-Deposits`
       &sortby=`{"menuindex":"ASC"}`
       &includeTVs=`valuta, time-if-deposit, from-sum-deposit, bet-for-deposit`
       &setTotal=`1`
       &toPlaceholder=`myOut`
    ]]  
    [[+myOut]]

    Данный снипет является оберткой над pdoResources, нужен для фильтрации результата

    Сниппет представляет собой

    $where = Array();
    
    if(count($_POST['tv'])) {
        $where = array_merge($where, $_POST['tv'] );
        if (count($where['from-sum-deposit:<='])) {
            unset($where['from-sum-deposit:<=']);
        };  
        if (!empty($where['srok']) and $where['srok'] == 'all' ) {
            unset($where['srok']);
        }
    }
    
    $scriptProperties['where'] = json_encode($where);
    $html = $modx->runSnippet('pdoResources', $scriptProperties);
    echo $html;

    А вывожу я все это при помощи Fenom на странице

    {set $total = $_modx->getPlaceholder('total')} Присваиваю последний элемент переменной
    {if $idx == 1} // Если это первый элемент, для него определенный вывод
    Тут код чанка для первого элемента
    {else}
    {$idx == 2? 'код открытия оболочки для второго и последующих элементов, эта оболочка появляется и скрывается по кнопке' : ' '}
    код для элементов внутренних, начиная от второго и дальше
    {$idx == $total? 'проверка на последний элемент, получается если total равен idx тогда он последний и я закрываю два дива':''}
    {/if}
    Конечно тут накручено, но кое как с помощью получилось мне получить последний элемент в выдаче pdoResources))) Пока работает, в целом как мне нужно
    Алексей Смирнов
    18 декабря 2022, 19:40
    +1
    Если вы хотите фильтровать по параметрам, то лучше сразу использовать тот же mSearch2 платный (как Артур сказал). Но есть момент.
    Если у вас не услуги, а товары и нужна корзина, то минишоп — точно.
    Если у вас там услуги и нет корзины (и не предвидится) то можно оставлять на ресурсах.
    2. О какой структере вообще речь? О блоке услуг? ну у вас обстрактное представление, но этот вариан в любом случае в 80% случаях и используется.
    3. Сложно посоветовать. тут нужны для начала общие знания. а потом можно в поиске написать «Объектная модель MODx Revo API. Статья для понимания» + к этому modzone.ru/blog/2015/12/27/frontend-events-for-modx/
    ну если покапаться можно много найти.
    И помнить что есть стандартный парсер плейсхолдеров и есть феном который устанавливается вместе с PdoTools и дает больше свободы. И сайт делается либо на феноме либо на MODX парсере. их желательно не смешивать в виду специфичности.
      Разработчик
      22 декабря 2022, 01:40
      0
      Спасибо за ответ) Мне тут помогли немного, когда поставил Fenom, то все получилось сделать)) Ранее пробовал сделать без него и очень не хватало свободы))
      Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
      4