Как реализовать табы Bootstrap в MODX REVO + MIGX

Всем ДВС!
Подскажите может кто нибудь сталкивался с реализацией табов





Всего табов 6, 4 открытые, и 2 закрытые






Сначала хотел реализовать через pdoResources и каждому ресурсу присвоить поля для отображения в табах, но не получилось т.к. tabs Bootstrap(у) необходима связь между пангинацией (вкладками) и самим телом. А тело выполнено в виде контейнера с блоками (в моем случае ресурсами).

Вот код:

<div class="price-tabs">
            <!-- табы -->
                <ul class="nav nav-tabs row" role="tablist">
                    <div class="col-md-1"></div>
                    <li role="presentation" class="active col-md-2"><a href="#level-1" aria-controls="level-1" role="tab" data-toggle="tab"><i class="icon-3"></i><span>1 класс</span></a></li>
                </ul>
            <!-- табы(конец) -->
            <!-- Табы контент -->
            <div class="tab-content">
                <div role="tabpanel" class="tab-pane fade in active" id="level-1">
                  <div class="row row-flex">
                    <div class="col-md-3 col-xs-12">
                      <div class="table-price">
                        <h2 class="text-center">Экспресс</h2>
                        <p class="table-count text-center">100 <i class="fa fa-rub" aria-hidden="true"></i></p>
                        <p class="table-time text-center"><i class="fa fa-clock-o" aria-hidden="true"></i> 25 минут</p>
                        <ul class="list-unstyled table-list text-left">
                          <li>Мойка автомобиля напором воды без шампуня</li>
                        </ul>
                        <a class="btn btn-default table-btn btn-block" href="#" role="button">Записаться</a>
                      </div>
                    </div>
                    <div class="col-md-3 col-xs-12">
                      <div class="table-price">
                        <h2 class="text-center">Экспресс "ПЛЮС"</h2>
                        <p class="table-count text-center">200 <i class="fa fa-rub" aria-hidden="true"></i></p>
                        <p class="table-time text-center"><i class="fa fa-clock-o" aria-hidden="true"></i> 35 минут</p>
                        <ul class="list-unstyled table-list text-left">
                          <li>Мойка с использованием шампуня</li>
                          <li>Без сушки кузова</li>
                        </ul>
                        <a class="btn btn-default table-btn btn-block" href="#" role="button">Записаться</a>
                      </div>
                    </div>
                    <div class="col-md-3 col-xs-12">
                      <div class="table-price-sale">
                      <h2 class="text-center">Стандарт</h2>
                        <p class="table-count-sale text-center">300 <i class="fa fa-rub" aria-hidden="true"></i></p>
                        <p class="table-time-sale text-center"><i class="fa fa-clock-o" aria-hidden="true"></i> 45 минут</p>
                        <ul class="list-unstyled table-list-sale text-left">
                          <li>Мойка с использованием шампуня</li>
                          <li>Мойка порогов, арок колес, ковриков</li>
                          <li>Сушка автомобиля</li>
                          <li>Продувка воздухом</li>
                        </ul>
                        <a class="btn btn-default table-btn-sale btn-block" href="#" role="button">Записаться</a>
                      </div>
                    </div>
                    <div class="col-md-3 col-xs-12">
                      <div class="table-price">
                      <h2 class="text-center">Комфорт</h2>
                        <p class="table-count text-center">400 <i class="fa fa-rub" aria-hidden="true"></i></p>
                        <p class="table-time text-center"><i class="fa fa-clock-o" aria-hidden="true"></i> 45-60 минут</p>
                        <ul class="list-unstyled table-list text-left">
                          <li>Мойка с использованием шампуня</li>
                          <li>Мойка порогов, арок колес, ковриков</li>
                          <li>Пылесос салона</li>
                          <li>Сушка автомобиля</li>
                          <li>Продувка воздухом</li>
                        </ul>
                        <a class="btn btn-default table-btn btn-block" href="#" role="button">Записаться</a>
                      </div>
                    </div>
                  </div>

                  <div class="title-page text-center">
                    
                    <h3>
                      <a role="button" data-toggle="collapse" href="#collapseExample" aria-expanded="false" aria-controls="collapseExample" href="">
                        <span>
                          <i class="fa fa-arrow-circle-o-down" aria-hidden="true"></i>
                        </span>
                      </a>
                    </h3>
                    <p class="text-center">Дополниьельно</p>
                  </div>

                  <div class="collapse" id="collapseExample">
                  <div class="row row-flex">
                    <div class="col-md-4 col-md-offset-2 col-xs-12">
                      <div class="table-price">
                      <h2 class="text-center">Комплекс</h2>
                        <p class="table-count text-center">550 <i class="fa fa-rub" aria-hidden="true"></i></p>
                        <p class="table-time text-center"><i class="fa fa-clock-o" aria-hidden="true"></i> 45-60 минут</p>
                        <ul class="list-unstyled table-list text-left">
                          <li>Мойка с использованием шампуня</li>
                          <li>Мойка порогов, арок колес, ковриков</li>
                          <li>Пылесос салона и багажника</li>
                          <li>Чистка пластика (обделки салона)</li>
                          <li>Мойка стекол изнутри</li>
                          <li>Сушка автомобиля</li>
                          <li>Продувка воздухом</li>
                        </ul>
                        <a class="btn btn-default table-btn btn-block" href="#" role="button">Записаться</a>
                      </div>
                    </div>
                    <div class="col-md-4 col-xs-12">
                      <div class="table-price">
                      <h2 class="text-center">Престиж</h2>
                        <p class="table-count text-center">750 <i class="fa fa-rub" aria-hidden="true"></i></p>
                        <p class="table-time text-center"><i class="fa fa-clock-o" aria-hidden="true"></i> от 60 минут</p>
                        <ul class="list-unstyled table-list text-left">
                          <li>Мойка с использованием шампуня</li>
                          <li>Мойка порогов, арок колес, ковриков</li>
                          <li>Пылесос салона и багажника</li>
                          <li>Чистка пластика (обделки салона)</li>
                          <li>Мойка стекол изнутри</li>
                          <li>Чернение резины</li>
                          <li>Покрытие воском</li>
                          <li>Сушка автомобиля</li>
                          <li>Продувка воздухом</li>
                        </ul>
                        <a class="btn btn-default table-btn btn-block" href="#" role="button">Записаться</a>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
           </div>
Можно попробовать реализовать в виде дополнительных полей, но это 5 классов машин, в каждом по 5 видов мойки, в каждом виде около 5-7 полей, это около 150 штук, просто не вариант такую грамотень городить)

Может быть кто нибудь сталкивался с данной проблемой, есть готовое решение, или какая то информация по этому поводу?
Сергей
09 апреля 2018, 13:45
modx.pro
2 582
0

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

Баха Волков
09 апреля 2018, 21:02
0
Migx в Migx и fenom.
    Сергей
    09 апреля 2018, 21:04
    0
    Добрый вечер!
    У меня тройная вложенность получается, сейчас как раз колдую!
    Что то мне уже кажется что 3 уровня не получится.
    Но попробую потом отпишу!
      Баха Волков
      09 апреля 2018, 21:06
      +1
      Получится-получится
        Сергей
        09 апреля 2018, 21:07
        0
        Если долго мучится!) Ночь длинная)
          Сергей
          09 апреля 2018, 21:21
          0
          А есть в MIGX first b last tpl?

          А то у меня вверстка получается
          .col-md-3 * 4
          .col-md-4 col-md-offset-2 * 2
          Как их вывести то?

          Или возможно вывести pdoResources а внутри уже MIGX?

          Отбой pdoResouces нужно тогда ресурсы создавать…
            Баха Волков
            10 апреля 2018, 07:42
            0
            Я почему и на fenom перешел, так как разные операции да еще и со сложными массивами и проверками сильно упрощаются.

            Ну а в вашем случае, в чанке результата доступны плейсхолдеры (Вот документация)

            [[+idx]] the index of each item, begins allways with 1
            [[+_first]] returns 1, if in first row
            [[+_last]] returns 1, if in last row
            [[+_alt]] returns 1 every second row
            [[+total]] count of all rows, replace 'total' with your totalVar

            С их помощью творите что вам угодно
              Сергей
              10 апреля 2018, 12:55
              0
              Ну я победил примерно к 4 часам ночи. Может не совсем правильное решение, но меня устраивает. К вечеру опубликую решение.
      Сергей
      10 апреля 2018, 15:27
      0
      Добрый день!
      В общем нашел решение, хочу выложить возможно кому то будет полезно, т.к. я бился над этой проблемой около 17 часов…

      Задача была следующая, есть прайс-лист, он выполнен в виде вкладок (tab bootstrap), нужно настроить все так, что бы конечный пользователь сайта без труда мог редактировать данные табы из админки.



      Сначала я хотел реализовать это с помощью pdoResources но для этого необходимо:
      1) Создать структуру ресурсов
      2) Городить мега вызов сниппета, чанками типа
      &tpl_N
      ,
      &tpl_nN
      , т.к body вкладок имело по 6 элементов (ресурсов).
      3) Создать MIGX поля для вывода информации, цены, время работ, выполняемых услуг.

      Поэтому в итоге я отказался от этой затеи, посчитал что конечный пользователь не разберется, так как он очень далек от всего этого.

      Написав на форуме и попутно штудируя интернет, я пришел к решению вложенности MIGX в MIXG.

      Прочитав куча информации, просмотрев куча примеров и изучив несколько видео приступил к работе.

      Структура MIXG полей у меня получилась следующая:

      Родительское поле - 1 класс (1 уровень)
      		Дочернее поле - Экспресс (2 уровень)
      				Дочернее поле - Цена (3 уровень)
      				Дочернее поле - Время (3 уровень)
      				Дочернее поле - Услуги (3 уровень)
      Создал три поля с типом ввода MIGX:

      1 - class-auto
      2 - price-meta
      3 - price-tabs

      1) Вкладки формы class-auto:
      [{"caption":"Категория транспорта",  "fields": [ 
          {"field":"className","caption":"Название категории"},
          {"field":"categoryList","caption":"Конкретные категории","inputTV":"price-meta"}
      ]}]
      Разметка колонок
      [
      {"header": "Цена", "dataIndex": "className"}
      ]
      На выходе получаем следующее:


      Устанавливаю значение для шаблона на котором я хотел выводить данное поле (главная страница).

      2) Вкладки формы price-meta:
      [{"caption":"Группа прайс-листов",  "fields": [ 
          {"field":"priceName","caption":"Способ мытья"},
          {"field":"priceList","caption":"Конкретный прайс-лист","inputTV":"price-tabs"}
      ]}]
      Разметка колонок
      [
      {"header": "Способ мытья", "dataIndex": "priceName"}
      ]
      Доступно для шаблонов ни чего не устанавливаю.

      На выходе получаю следующее:





      Теперь я могу добавить второй уровень вложенности
      Экспресс
      Экспресс ПЛЮС
      Стандарт 
      и.т.д.
      3) Вкладки формы price-tabs:
      [  
          { "caption":"Прайс-лист",  "fields": 
              [ 
                  {
                      "field":"price",
                      "caption":"Цена (например: 250)"
                  }
                  ,
                  {
                      "field":"time",
                      "caption":"Время проводимых работ (например: 25)"
                  },
                  {
                      "field":"main-active",
                      "caption":"Класс блока для выделения (main-active)"
                  }
                  ,
                  {
                      "field":"desc",
                      "caption":"Перчисление услуг (например: <li>Ваша услуга</li>)",
                      "inputTVtype": "textarea"
                  }
              ]
          }
      ]
      Разметка колонок
      [
      {"header": "Цена", "width": "150", "sortable": "true", "dataIndex": "price"},
      {"header": "Время", "width": "150", "sortable": "true", "dataIndex": "time"},
      {"header": "Услуги", "width": "150", "sortable": "true", "dataIndex": "desc"},
      {"header": "Класс активного блока", "width": "150", "sortable": "true", "dataIndex": "main-active"}
      ]
      Доступно для шаблонов ни чего не устанавливаю.

      На выходе получаю следующее:





      Теперь я могу добавить третий уровень вложенности, значения цены, времени проводимых работ и услуги которые относятся к тому или другому методу мойки машины.

      Все готово, теперь необходимо осуществить вызов сниппета getImageList и отобразить все на сайте.

      Первым делом выводим сниппет в шаблоне на котором я хотел выводить все данный, у меня этот чанк называется [[$Price]]
      <div>
      [[!getImageList?
              &tvname=`class-auto`
              &tpl=`class-auto`
       ]]
      </div>
      Второй я создал чанк class-auto и в нем вывел
      <div class="row">
      	<div class="col-md-2">
      		<h1>[[+className]]</h1>
      	</div>
      </div>
      <div class="row>
      [[!getImageList?
          &value=`[[+categoryList]]`
          &tpl=`price-class`
      ]]
      </div>
      Третий чанк price-class имеет вывод, т.к. у меня по 6 элементов в теле вкладок, я решил осуществить вывод с классом col-md-2:
      <div class="col-md-2>
      [[!getImageList?
              &value=`[[+priceList]]`
              &tpl=`price-meta`
      ]]
      </div>
      И последний чанк price-meta
      <div class="body-tabs [[+main-active]]">
              <h4 class="body-tabs-title">[[+priceName]]</h4>
              <p class="body-tabs-price">[[+price]] <i class="fa fa-rub" aria-hidden="true"></i>.</p>
              <hr>
              <p class="body-tabs-time"><i class="fa fa-clock-o" aria-hidden="true"></i> [[+time]] минут</p>
              <hr>
              <p class="body-tabs-desc">[[+desc]]</p>
              <hr>
              <p class="text-center"><a href="" class="btn btn-primary btn-small">Записаться</a></p>
          </div>
      Сначало я все делал без разметки вкладок что бы понять как и что будет выводится.
      Получилась следующая структура

      <div>
        <div class="row">
          <div class="col-md-2">
            <h1>1 класс</h1>
          </div>
        </div>
        <div class="row">
          <div class="col-md-2">
            <div class="body-tabs [[+main-active]]">
                  <h4 class="body-tabs-title">[[+priceName]]</h4>
                  <p class="body-tabs-price">[[+price]] <i class="fa fa-rub" aria-hidden="true"></i>.</p>
                  <hr>
                  <p class="body-tabs-time"><i class="fa fa-clock-o" aria-hidden="true"></i> [[+time]] минут</p>
                  <hr>
                  <p class="body-tabs-desc">[[+desc]]</p>
                  <hr>
                  <p class="text-center"><a href="" class="btn btn-primary btn-small">Записаться</a></p>
            </div>
          </div>
          И еще 5 элементов
        </div>
      </div>
      Я столкнулся с трудностью, которую так и не смог решить, если кто то подскажет буду очень признателен!!!
      Трудность состоит в том, что структура кода вкладок Bootstrap выглядит следующим образом:


      <div > <!-- блок обертка -->
      
            <ul> <!-- сами вкладки -->
              <li></li>
              <li></li>
              <li></li>
              <li></li>
              <li></li>
            </ul>
      
            <div> <!-- тело -->
              <div></div> <!-- элементы тела -->
              <div></div>
              <div></div>
              <div></div>
              <div></div>
              <div></div>
            </div>
      
        </div>
      А я получил что то типа:

      <div > <!-- блок обертка -->
      
            <ul> <!-- сами вкладки -->
              <li>1 класс</li>
            </ul>
      
            <div> <!-- тело -->
              <div></div> <!-- элементы тела -->
              <div></div>
              <div></div>
              <div></div>
              <div></div>
              <div></div>
            </div>
      
            <ul> <!-- сами вкладки -->
              <li>2 класс</li>
            </ul>
      
            <div> <!-- тело -->
              <div></div> <!-- элементы тела -->
              <div></div>
              <div></div>
              <div></div>
              <div></div>
              <div></div>
            </div>
      
        </div>
      Так как родительские пункты утверждены и они не измены я подумал что заказчик вряд ли захочет изменять их название, поэтому вывод в чанке [[$Price]] я сделал следующий:

      <div id="price">
            <div class="container">
              <div class="title-page text-center"><h1><span>НАШ ПРАЙС-ЛИСТ</span></h1></div>
                  <div class="price-tabs">
                      <ul class="nav nav-tabs text-center">
                          <li role="presentation" class="active">
                              <a href="#1level" aria-controls="1level" role="tab" data-toggle="tab" class="link-tabs">
                                  <i class="icon-3 icon-tabs"></i>
                                      <p>1 класс</p>
                                  </a>
                          </li>
                          <li role="presentation" >
                              <a href="#2level" aria-controls="2level" role="tab" data-toggle="tab" class="link-tabs">
                                  <i class="icon-1 icon-tabs"></i>
                                      <p>2 класс</p>
                                  </a>
                          </li>
                          <li role="presentation" >
                              <a href="#3level" aria-controls="3level" role="tab" data-toggle="tab" class="link-tabs">
                                  <i class="icon-2 icon-tabs"></i>
                                      <p>3 класс</p>
                                  </a>
                          </li>
                          <li role="presentation" >
                              <a href="#4level" aria-controls="4level" role="tab" data-toggle="tab" class="link-tabs">
                                  <i class="icon-8 icon-tabs"></i>
                                      <p>4 класс</p>
                                  </a>
                          </li>
                          <li role="presentation" >
                              <a href="#5level" aria-controls="5level" role="tab" data-toggle="tab" class="link-tabs">
                                  <i class="icon-6 icon-tabs"></i>
                                      <p>5 класс</p>
                                  </a>
                          </li>
                      </ul>
                      <div class="tab-content">
                          [[!getImageList?
                              &tvname=`class-auto`
                              &tpl=`class-auto`
                          ]] 
                      </div>
                  </div>
        
       
              <div class="btn-more text-center">
                  <a class="btn btn-primary btn-lg" href="#" role="button">
                      <i class="fa fa-list" aria-hidden="true"></i> Смотеть весь прайс-лист</a>
              </div>
          </div>
      </div>
      Элементы навигации я сделал статичными и вывел за пределы сниппета getImageList.
      Для работоспособности прописал классы
      href="#4level" aria-controls="4level"
      А в самом выводе тела указал следующий код:

      <div class="row row-flex tab-pane fade in [[+idx:is=`1`:then=`active`]]"  role="tabpanel" id="[[+idx]]level">
      [[!getImageList?
          &value=`[[+categoryList]]`
          &tpl=`price-class`
      ]]
      </div>
      Так как родительских пунктов у меня всего 5, и следовательно тел с элементами (табами) у меня тоже пять, я могу точно знать порядковый номер. Вывод плейсхолдера [[+idx]] соответствует прописанному классу в навигации.

      Так же есть проблема с классом .active для активной вкладки, она решается так:
      [[+idx:is=`1`:then=`active`]]
      если первый таб имеет порядковый номер 1, то ему присвоить класс
      active
      .

      Вот и все, пошаманив над стилями все получилось!

      Написал для себя, что бы не забыть как делать, ну и потратил на всю работу реально 17 часов, возможно кому то это приходится!!!
      Возможно решение корявое, но по крайней мере рабочее, лучше я со своими знаниями придумать ничего не смог!

      Вот итог:


      Вроде все протестировал все работает!

        Авторизуйтесь или зарегистрируйтесь, чтобы оставлять комментарии.
        8