Застрял уже наверное на неделю и никак не могу приступить к реализации такой штуки как График работы для модели.
Вот что имеется в виду:

У меня нет идей как это правильно реализовать в бекенде при создании/редактировании модели. Тут лучше спросить совета у опытных пользователей.

В БД для модели думаю создать колонку hours с типом данных string и туда заносить значения, чтоб потом их сплитить для вывода на фронтенд. Этот параметр не обязательный.
Примеры значений думаю что то из этих вариантов:

NULL
8:00, 20:00; 8:00, 20:00; 8:00, 20:00; 8:00, 20:00; 8:00, 20:00; 10:00, 15:00; Выходной, -;
8:00, 20:00, 8:00, 20:00, 8:00, 20:00, 8:00, 20:00, 8:00, 20:00, 10:00, 15:00, Выходной, -;

А вот как для бекенда реализовать форму, чтоб эти данные вносить и редактировать? Наверное нужно свой виджет форм писать и как то собирать это всё в одну строку.
Подскажите пожалуйста, а то даже не знаю с чего начать.

А не проще сделать записи типа День - значение и просто их выводить?

  • Koresh ответили на это сообщение.

    Electrica Но тут получается для одного дня - два значения. В HTML можно сделать через тег <select> и js-ом собрать данные, но это на фронте. А что делать на беке - у меня NULL идей.

    • Electrica ответили на это сообщение.

      Koresh ну можно три поля. День From To и все. ну я думаю это самый простой варинт

      • Koresh ответили на это сообщение.

        Electrica А как это потом в одну строку собрать для хранения в БД ? Вот меня именно это и смущает.

        А может вынести дни в отдельную модель и сделать связь с основной моделью?

        • Koresh ответили на это сообщение.

          Можно сделать поле типа text в модели дать ему модификатор $jsonable и хранить данные о графике работ в виде json массива.
          Выводить через nestedForm в бекенде.

          • Koresh ответили на это сообщение.
            • Изменено

            sko6 А может вынести дни в отдельную модель и сделать связь с основной моделью?

            Да нет, это вообще ни к чему. Тут просто как то из инпутов в одну строчку собрать данные.
            Вот как это должно выглядеть визуально:

            Правда чекбоксы наверное здесь вообще ни к чему.

            • reazzon ответили на это сообщение.

              Я так понимаю для этого нужно вот этот виджет пилить:

              php artisan create:formwidget Acme.Blog CategorySelector

              Правильно? Или это не тот будет виджет?

              я когда делал расписание графика работы, я просто добавил одно поле schedules определил в модели как jsonable, а в формах сделал репитер с семью значениями. у меня вроде никакой проблемы не было

              reazzon хранить данные о графике работ в виде json массива

              Да, согласен - с json массивом будет правильнее чем со строкой.
              Подскажите как в БД создать под это ячейку. Так нормально будет:

              $table->string('open_hours')->nullable();
              • reazzon ответили на это сообщение.

                Koresh

                $table->text('open_hours')->nullable();

                Koresh Вот как это должно выглядеть визуально:

                Через nestedForm такое делается, как я и говорил)

                • Koresh ответили на это сообщение.

                  Из документации:
                  nestedform - отображает вложенную форму как содержимое этого поля, возвращает данные как массив содержащихся полей.

                  ПРИМЕЧАНИЕ: чтобы использовать это с моделью, она должна быть присоединена к jsonable или другому атрибуту, который может обрабатывать хранение данных массива

                  Ссылка на доку: https://octobercms.com
                  Теперь нужно определить в модели поле open_hours как jsonable и можно пробовать настраивать этот nestedForm. Вроде бы я с ним впервые сталкиваюсь, будем пробовать.


                  Про $jsonable нашёл в доках такой пример кода:

                  \Backend\Models\User::extend(function($model) {
                      $model->addJsonable('some_data');
                  });

                  Но я не совсем понимаю где и как определить у себя. Глядя на этот код, ощущения что нужно в файле Plugin.php

                  use Model;
                  
                  class Plugin extends PluginBase
                  {
                  
                      \Backend\Models\Item::extend(function($model) {
                          $model->addJsonable('open_hours');
                      }
                      
                  }

                  Или же это нужно делать в php-файле модели? Есть файл \plugins\octoclub\acme\models\Item.php. Но я что то не понимаю как его сюда притулить:

                  class Item extends Model
                  {
                      // ????????????????
                  }
                  • reazzon ответили на это сообщение.
                    • Изменено

                    Koresh Но я не совсем понимаю где и как определить у себя. Глядя на этот код, ощущения что нужно в файле Plugin.php

                    Все очень просто. Открывай свою модель, в которой хочешь сделать jsonable поле, и создай там переменную.

                    Пример

                    class Item extends Model
                    {
                        /// [...]
                        protected $jsonable = [
                            'open_hours'
                        ];
                        /// [...]
                    }

                    Примечание: в базе данных поле обязательно должно быть типа text

                    • Koresh ответили на это сообщение.
                      • Изменено

                      Пример из fields.yaml файла с nestedForm с живого проекта.

                      headline:
                          tab: Вступительный экран
                          type: nestedform
                          usePanelStyles: false
                          form:
                              fields:
                                  title:
                                      label: Заголовок
                                      required: true
                                      span: storm
                                      cssClass: col-md-6 col-xs-12 col-md-offset-1
                      
                                  background:
                                      label: Картинка на фоне
                                      type: mediafinder
                                      span: storm
                                      cssClass: col-md-4 col-xs-12
                      
                                  description:
                                      label: Описание
                                      required: true
                                      type: textarea
                                      span: storm
                                      cssClass: col-md-6 col-xs-12 col-md-offset-1
                      
                                  specials:
                                      label: Преимущества
                                      prompt: Добавить блок
                                      type: repeater
                                      span: storm
                                      cssClass: col-md-6 col-xs-12 col-md-offset-1
                                      form:
                                          fields:
                                              text:
                                                  label: Текст
                                                  placeholder: У нас все дешевле!
                                                  span: auto
                                              color:
                                                  label: Цвет фона
                                                  type: colorpicker
                                                  span: auto
                                                  availableColors: ['#F44336', '#79b03b', '#2196f3']
                      • Koresh ответили на это сообщение.

                        reazzon Пример из fields.yaml файла с nestedForm с живого проекта.

                        У меня интернет вырубило и только включили. Я сразу в доках нашёл пример поля nestedForm, вставил его себе и сразу увидел что мне нужно. Там вообще всё ништяково получается - ещё круче чем я хотел изначально.
                        Сейчас разберусь со стилями и выложу что получилось.

                        reazzon Открывай свою модель, в которой хочешь сделать jsonable поле, и создай там переменную.

                        Спасибо! Сейчас так и сделаю.

                        • Изменено

                        Вот как получилась форма:

                        Установка времени:

                        Поле в fields.yaml

                        open_hours:
                            type: nestedform
                            usePanelStyles: false
                            span: open_hours
                            form:
                                fields:
                                    mo_open:
                                        label: Понедельник
                                        type: datepicker
                                        mode: time
                                    mo_close:
                                        type: datepicker
                                        mode: time
                                    tu_open:
                                        label: Вторник
                                        type: datepicker
                                        mode: time
                                    tu_close:
                                        type: datepicker
                                        mode: time
                                    we_open:
                                        label: Среда
                                        type: datepicker
                                        mode: time
                                    we_close:
                                        type: datepicker
                                        mode: time
                                    th_open:
                                        label: Четверг
                                        type: datepicker
                                        mode: time
                                    th_close:
                                        type: datepicker
                                        mode: time
                                    fr_open:
                                        label: Пятница
                                        type: datepicker
                                        mode: time
                                    fr_close:
                                        type: datepicker
                                        mode: time
                                    sa_open:
                                        label: Суббота
                                        type: datepicker
                                        mode: time
                                    sa_close:
                                        type: datepicker
                                        mode: time
                                    su_open:
                                        label: Воскресенье
                                        type: datepicker
                                        mode: time
                                    su_close:
                                        type: datepicker
                                        mode: time
                            tab: График работы

                        И вот такой css чтоб ровно встало:

                        /* График работы */
                        .span-open_hours {
                            width: 350px;
                            margin-left: 40px;
                        }
                        .span-open_hours .form-tabless-fields .span-full {
                            display: inline-block;
                            width: inherit;
                            float: none;
                        }
                        .span-open_hours .field-datepicker {
                            display: inline-block;
                            width: 85px;
                            margin-left: 15px;
                        }
                        .span-open_hours label {
                            display: inline-block;
                            width: 95px;
                            font-weight: bold;
                        }

                        Как сохраняет в БД пока не проверял. Мне ещё нужно немного посидеть и переделал БД для этой модели.

                        • Изменено

                        Проверил - всё сохраняется. Тип nestedform это круто, спасибо что с ним подсказали.
                        Но не всё прошло гладко, у датапикера октября есть недоработка - он с модом time сохраняет значения так:
                        2019-10-03 08:00:00, а мне нужно просто часы и минуты 08:00.
                        Пробую настройки поля сделать так:

                        mo_open:
                            label: Понедельник
                            type: datepicker
                            mode: time
                            format: 'H:i'
                            ignoreTimezone: true

                        но это не помогает, без изменений. Видать это недоработка в самой CMS.
                        Приходится время выводить так:

                        {{ model.open_hours.mo_open | date('H:i') }}

                        Ещё с таймзонами у меня проблема, но это от того что я не знаю как правильно пользоваться этим функционалом и карбоном. Наверное не сложно, но нужно хотя бы один раз попробовать.
                        Поэтому в перспективе на будущее у меня остаётся задача сделать для этой модели метку Открыто/Закрыто. То есть, если посетитель зашёл на страницу модели например в понедельник в интервале с 08:00 до 20:00, то показывается метка Открыто. В противном случае (время не входит в интервал 08:00-20:00) - метка Закрыто.

                        4 дня спустя

                        reazzon Через nestedForm такое делается, как я и говорил)

                        А можете подсказать какой тип данных передавать с фронта для сохранения/редактирования этого поля nestedForm?
                        Я через js передаю данные в функцию onSave из php-файла модели.
                        В ячейке БД данные хранятся так:

                        {"mo_open":"08:00","mo_close":"20:00","tu_open":"08:00","tu_close":"20:00","we_open":"05:00","we_close":"17:00","th_open":"05:00","th_close":"17:00","fr_open":"05:00","fr_close":"17:00","sa_open":"07:00","sa_close":"12:00","su_open":"","su_close":""}

                        Не пойму как мне передать данные перед $model->save();, каждое поле по отдельности передавать или как?

                        • reazzon ответили на это сообщение.