Ajax загрузка и подсчёт тв параметров в MODX

Александр
Александр
581
7
Содержание:
  1. Комментарии
Александр, здравствуйте! Подскажите пожалуйста, как можно сделать чтобы у тв полей или своих полей, при загрузке страницы в результатах mFilter2, pdoResources или просто при выводе поля в шаблоне, выводилось определённое количество параметров а остальные подгружать аяксом только при нажатии (показать все 15)?

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

  1. Александр Мальцев
    Александр Мальцев
    02.03.2020, 16:30
    Здравствуйте!
    Реализовать подгрузку данных через AJAX, например, при нажатии на кнопку «Показать все» можно различными способами.
    Вот, например один из них.
    1. Создаём php файл, например «get_fields.php» и кладём его в папку «assets». В этом файле на основе полученного id будет получать нужные данные ресурса и отдавать их в формате JSON. В качестве примера, например, будем возвращать pagetitle и description ресурса.
    Сниппет «get_fields.php»:
    <?php
    
    if (empty($_SERVER['HTTP_X_REQUESTED_WITH']) || $_SERVER['HTTP_X_REQUESTED_WITH'] != 'XMLHttpRequest') {
      return;
    }
    require_once dirname(dirname(__FILE__)) . '/config.core.php';
    require_once MODX_CORE_PATH.'model/modx/modx.class.php';
    $modx = new modX();
    $modx->initialize('web');
    $modx->getService('error','error.modError', '', '');
    if (empty($_GET['id'])) {
      exit();
    }
    
    // получаем переданный id
    $id = (int)$_GET['id'];
    
    // создаём запрос и получаем нужные данные
    $query = $modx->newQuery('modResource');
    $query->where( array('id' => $id) );
    $resource = $modx->getObject('modResource', $query);
    
    $output = [];
    if ($resource) {
      // добавляем в массив нужные данные
      $output['pagetitle'] = $resource->get('pagetitle');
      $output['description'] = $resource->get('description');
    }
    
    header('Content-Type: application/json');
    echo json_encode($output);
    exit();
    
    2. В качестве примера выводится список ресурсов на страницу будет так:
    [[!pdoResources?
      &parents=`3`
      &depth=`0`
      &limit=`10`
      &tpl=`@INLINE <div data-id="[[+id]]" style="margin-bottom: 15px;">Ресурс, имеющщий id = [[+id]] <div class="more"><button type="button" class="ajax-more">Подгрузить остальное</button></div></div>`
    ]]
    
    В атрибут «data-id» мы будем помещать id ресурса. А подгрузку данных будет производить при нажатии на кнопку с классом «ajax-more».

    3. Теперь нам осталось только создать JavaScript код, который будет обрабатывать события при нажатии на кнопку с классом «ajax-more». В этом обработчике мы будем получать id ресурса из атрибута data-id и отправлять его на сервер, а после получения нужных полей от сервера помещать их в элемент в котором находилась эта кнопка:
    $(function() {
      $(document).on('click', '.ajax-more', function(e) {
        var _this = e.target;
        var id = $(_this).closest('[data-id]').attr('data-id');   
        $.getJSON({
          data: { 'id': id },
          url: '/assets/get_fields.php',
          success: function (data) {
            var output = '';
            var title = '<h2>' + data['pagetitle'] + '</h2>';
            var description = '<p>' + data['description'] + '</p>';  
            output = title + description;
            _this.parentElement.innerHTML = output;
          }
        });
      });
    });
    
    1. Александр
      Александр
      03.03.2020, 20:20
      Здравствуйте! Спасибо Вам за решение. Александр а как это применить к тв которые выводятся в результатах mFilter2? Пытался аналогичным способом, как указан title и description в скрипте и сниппете указать название тв color, но так не работает.

      В скрипте
      var color = '<h2>' + data['color'] + '</h2>';
      в сниппет
      $output['color'] = $resource->get('color');
      .
      1. Александр Мальцев
        Александр Мальцев
        05.03.2020, 15:07
        TV находится не в самом ресурсе, а в отдельной таблице. Её получить так нельзя.
        Пример, в котором показано как её можно получить:
        // создаём запрос и получаем нужные данные
        $query = $modx->newQuery('modResource');
        $query->where( array('id' => $id) );
        $resource = $modx->getObject('modResource', $query);
        $output = [];
        if ($resource) {
          $color = '';
          // получаем tv
          $tvr = $modx->getObject('modTemplateVarResource', array(
            'tmplvarid' => 2, // id tv
            'contentid' => $id
          ));
          if ($tvr) {
            $color = $tvr->get('value');
          }
          // добавляем в массив нужные данные
          $output['pagetitle'] = $resource->get('pagetitle');
          $output['description'] = $resource->get('description');
          $output['color'] = $color;
        }
        
        1. Александр
          Александр
          05.03.2020, 18:47
          Чем больше вникаю, тем больше понимаю, что это крутое решение, спасибо Вам.

          1) Александр а если тянуть поля со своей таблицы компонента в моём случае extendresource, то изменить нужно в этом месте:
          $tvr = $modx->getObject('modTemplateVarResource', array(
          правильно я понимаю?

          2) Как можно сделать чтобы при загрузке страницы, определённое количество параметров тв загружалось а остальные только при нажатии (Показать ещё 17)? Или в данном случае сделать это не получиться а нужно вызывать поле обычным образом и в нём ограничивать сколько показывать параметров, далее ставить кнопку с ajax подгрузкой?

          3) Как можно вывести количество параметров привязанных к ресурсу (Показать все 20)?

          4) Как правильно добавить второе тв?

          5) Как можно разделить запятой выводимые параметры, сейчас подгружаются так белый||чёрный||красный?
          Как я понимаю в данном случае не играет роли какой разделитель указан в параметрах вывода у тв.
          1. Александр Мальцев
            Александр Мальцев
            07.03.2020, 08:41
            Пожалуйста!
            1. Чтобы выбрать ещё данные нужно либо добавить ещё один запрос или сделать более комплексный запрос, выбирающий всё сразу.
            Например, чтобы добавить ещё один запрос для выборки нужных данных нужно его просто добавить:
            if ($resource) {
              $color = '';
              // получаем tv
              $tvr = $modx->getObject('modTemplateVarResource', array(
                'tmplvarid' => 2, // id tv
                'contentid' => $id
              ));
              if ($tvr) {
                $color = $tvr->get('value');
              }
            
              $ext1 = '';
              $ext2 = '';
              $modx->addPackage('extendresource', MODX_CORE_PATH . 'components/extendresource/model/');
              $query = $modx->newQuery('extendResource');
              $query->where(array('resource' => $id));
              $extendResource = $modx->getObject('extendResource', $query);
              if ($extendResource) {
                // получим значение поля ext1 в extendResource
                $ext1 = $extendResource->get('ext1');
                // получим значение поля ext1 в extendResource
                $ext2 = $extendResource->get('ext2');
              }
            
              // добавляем в массив нужные данные
              $output['pagetitle'] = $resource->get('pagetitle');
              $output['description'] = $resource->get('description');
              $output['color'] = $color;
              $output['ext1'] = $ext1;
              $output['ext2'] = $ext2;
            }
            2. Тут всё просто, которые нужно выбирайте и выводите обычным способом. А те, которые нужно подгрузить потом, например, при нажатии кнопки, выбирайте в «get_fields.php», а затем выводите их на страницу.

            3. Выбирайте любые поля, которые вам нужно в «get_fields.php», а затем их выводите.

            4. Также, как и первое. Ну или писать комплексный запрос.
            // 1 TV поле, например color
            $color = '';
            // получаем tv
            $tvr = $modx->getObject('modTemplateVarResource', array(
              'tmplvarid' => 2, // id 1 tv поля
              'contentid' => $id
            ));
            if ($tvr) {
              $color = $tvr->get('value');
            }
            // 2 TV поле, например size
            $size = '';
            // получаем tv
            $tvr = $modx->getObject('modTemplateVarResource', array(
              'tmplvarid' => 3, // id 2 tv поля
              'contentid' => $id
            ));
            if ($tvr) {
              $size = $tvr->get('value');
            }
            ...
            
            5. Это же php код, можно использовать все функции, которые есть в php. Например, использовать функцию str_replace. Она позволяет заменить все вхождения строки поиска (в данном случае "||") на строку замены (в данном случае ", ").
            1. Александр
              Александр
              10.03.2020, 03:11
              Александр, здравствуйте! По некоторым моментам всё понятно, огромное спасибо, но в большей мери касаемо 4 — го пункта, не могу не как разобраться, добавил второе поле, всё работает, но как можно сделать чтобы эти два поля имели отдельные кнопки для подгрузки (Подгрузить поле color), (Подгрузить поле size) и каким способом можно подсчитать привязанные к ресурсу параметры у поля и вывести цифрой (Подгрузить поле color 10 параметров), (Подгрузить поле size 8 параметров)?
              1. Александр Мальцев
                Александр Мальцев
                14.03.2020, 16:10
                Здравствуйте! Тут будет всё аналогично, либо создаёте дополнительный параметр и передаёте его вместе с id, либо делаете для этого поля запрос на другой файл на сервере. Для реализации первого варианта вам необходимо будет добавить в php конструкцию switch. С помощью неё вы можете организовать выполнения определённых действий в зависимости от значения этого дополнительного параметра. Для реализации второго варианта вам необходимо будет просто создать ещё один php файл и прописать в нём аналогичную логику, но, для параметра color.

                Для подсчёта количества параметров всё аналогично. Либо вы это выполняете сразу в MODX на этапе формирования страницы, либо потом через AJAX. В случае AJAХ действия будут аналогичными, создаёте сценарий на языке JavaScript, который, например будет выполняться после загрузки DOM, в этом сценарии пишите запрос на сервер, на сервере пишите логику для возвращения количества параметров. Далее на JavaScript после получения этих данных подставляете их на страницу.
    Войдите, пожалуйста, в аккаунт, чтобы оставить комментарий.