График работы для модели
А может вынести дни в отдельную модель и сделать связь с основной моделью?
Можно сделать поле типа text в модели дать ему модификатор $jsonable
и хранить данные о графике работ в виде json массива.
Выводить через nestedForm в бекенде.
Я так понимаю для этого нужно вот этот виджет пилить:
php artisan create:formwidget Acme.Blog CategorySelector
Правильно? Или это не тот будет виджет?
я когда делал расписание графика работы, я просто добавил одно поле schedules определил в модели как jsonable, а в формах сделал репитер с семью значениями. у меня вроде никакой проблемы не было
Из документации:
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
{
// ????????????????
}
- Изменено
Koresh Но я не совсем понимаю где и как определить у себя. Глядя на этот код, ощущения что нужно в файле Plugin.php
Все очень просто. Открывай свою модель, в которой хочешь сделать jsonable поле, и создай там переменную.
Пример
class Item extends Model
{
/// [...]
protected $jsonable = [
'open_hours'
];
/// [...]
}
Примечание: в базе данных поле обязательно должно быть типа text
- Изменено
Пример из 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']
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) - метка Закрыто.
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();
, каждое поле по отдельности передавать или как?