В этой инструкции, я бы хотел рассказать как сделать вашу форму похожей на форму поста у плагина RainLab.Blog.
На самом деле, процесс не отличается от того, который я описывал в статье про установку сайдбара, но отличается лишь "встраиваемым кодом" и тем, что в качестве полей, которые находятся на цветном фоне используется не SecondaryTabs - а обычные поля без вкладок, которые вы указываете обычно в самом начале своего файла fields.yaml
.
Приступим:
Первым делом, в класс контроллера нужно добавить переменную:
public $bodyClass = 'compact-container breadcrumb-fancy';
Пример:
namespace OctoClub\Tutorial\Controllers;
use BackendMenu;
use Backend\Classes\Controller;
class Items extends Controller
{
public $bodyClass = 'compact-container breadcrumb-fancy';
// [...]
}
Данные два класса уберут отступы у формы, и раскрасят хлебные крошки.
Теперь перейдем к view шаблонам нашего контроллера. Открываем create.htm
, который лежит в папке рядом с контроллером.
И начинаем заменять код.
Здесь будет больше удалений чем в варианте с сайдбаром.
Всю форму удаляем...
// [..]
<?php if (!$this->fatalError): ?>
<?= Form::open(['class' => 'layout']) ?>
<div class="layout-row">
<?= $this->formRender() ?>
</div>
<?= Form::close() ?>
<?php else: ?>
// [..]
И меняем на...
// [..]
<?php if (!$this->fatalError): ?>
<div class="layout fancy-layout">
<?= Form::open([
'class' => 'layout',
'data-change-monitor' => 'true',
'data-window-close-confirm' => e(trans('rainlab.blog::lang.post.close_confirm')),
'id' => 'post-form'
]) ?>
<?= $this->formRender() ?>
<?= Form::close() ?>
</div>
<?php else: ?>
// [..]
Абсолютно тоже самое делаем и в файле update.htm.
Сохраняем. И если зайти сейчас на страницу создания записи, вы уже можете увидеть что все практически готово.
Но не хватает кнопок "сохранить", "сохранить и закрыть" и "закрыть". Если посмотреть как они сделаны у RainLab.Blog они находятся сразу под названием.
Вывести их туда очень просто, через фрагмент, который мы укажем в fields.yaml
.
Открываем fields.yaml
вашей модели и вставляем туда тулбар.
toolbar:
type: partial
path: post_toolbar
cssClass: collapse-visible
Пример:
fields:
name:
label: Название
span: auto
type: text
slug:
label: Ссылка
span: auto
preset:
field: name
type: slug
type: text
toolbar:
type: partial
path: post_toolbar
cssClass: collapse-visible
secondaryTabs:
fields:
description:
label: Описание
size: large
span: full
type: richeditor
tab: Контент
Возвращаемся в папку контроллера, и создаем здесь этот фрагмент _post_toolbar.htm
В него вставляем верстку наших кнопок, можете просто копировать.
<?php
$isCreate = $this->formGetContext() == 'create';
$pageUrl = isset($pageUrl) ? $pageUrl : null;
?>
<div class="form-buttons loading-indicator-container">
<!-- Save -->
<a
href="javascript:;"
class="btn btn-primary oc-icon-check save"
data-request="onSave"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>"
data-request-before-update="$el.trigger('unchange.oc.changeMonitor')"
<?php if (!$isCreate): ?>data-request-data="redirect:0"<?php endif ?>
data-hotkey="ctrl+s, cmd+s">
<?= e(trans('backend::lang.form.save')) ?>
</a>
<?php if (!$isCreate): ?>
<!-- Save and Close -->
<a
href="javascript:;"
class="btn btn-primary oc-icon-check save"
data-request-before-update="$el.trigger('unchange.oc.changeMonitor')"
data-request="onSave"
data-load-indicator="<?= e(trans('backend::lang.form.saving')) ?>">
<?= e(trans('backend::lang.form.save_and_close')) ?>
</a>
<?php endif ?>
<!-- Preview -->
<a
href="<?= URL::to($pageUrl) ?>"
target="_blank"
class="btn btn-primary oc-icon-crosshairs <?php if (!false): ?>hide<?php endif ?>"
data-control="preview-button">
<?= e(trans('backend::lang.form.preview_title')) ?>
</a>
<?php if (!$isCreate): ?>
<!-- Delete -->
<button
type="button"
class="btn btn-default empty oc-icon-trash-o"
data-request="onDelete"
data-request-confirm="<?= e(trans('rainlab.blog::lang.post.delete_confirm')) ?>"
data-control="delete-button"></button>
<?php endif ?>
</div>
Мы успешно добавили тулбар с кнопками. Вы можете добавить туда и свои кнопки, например для действия "назад".
По-сути это все.
Но есть маленькая деталь, которую можно довести до конца.
Если вы взглянете на мой скриншот, вы увидите что поле "описание" сюда не вписывается, и хочется чтобы оно растягивалось на всю вкладку.
Сделать это невероятно просто, и требует лишь правок в файле fields.yaml вашей модели.
Переходим к этому файлу.
secondaryTabs:
fields:
description:
label: Описание
size: large
span: full
type: richeditor
tab: Контент
Если вы заметили, поле "описание" стоит не в обычном tabs а именно в secondaryTabs, и это не просто так. Визуально вкладки отличаются, и именно secondaryTabs выглядят "лучше всего" и не имеет внутреннего отступа для полей внутри вкладки.
tabs:
secondaryTabs:
Процесс "растяжки" поля на весь экран имеет небольшой подводный камень, который достаточно легко правиться, но все-равно не очень приятно что разработчики не придумали более "элегантного" способа.
Первое что надо сделать это удалить у поля
label: Описание
size: large
И добавить ему значение stretch: true
. Так-же значение stretch: true
надо добавить самим secondaryTabs
Вот что должно у вас получится:
secondaryTabs:
stretch: true
fields:
description:
span: full
stretch: true
type: richeditor
tab: Контент
Если вы сейчас откроете страницу с формой, вы увидите что все готово.
Вы наверно спокойно выдохните и спросите "В чем подводный камень? Ведь все как нужно и больше ничего не надо".
Не все так просто! Если откроете другую вкладку, где например вы будете добавлять картинки, вы увидите следующее...
Внутри вкладки ведь нет отступа, мы его сами убрали. Поэтому все остальные поля, кроме красивого поля "описания" будут не очень красиво тереться обо все края.
Но ничего страшного! У команды разработчиков OctoberCMS есть очень "своеобразное" решение данной проблемы. Какое именно? JS!
....мда я тоже не ожидал такого
Приступим к костылям. Создадим в папке вашего плагина папки assets/js. И создаем там файл js скрипта, называйте как хотите, я назвал его item-form.js
, и добавил туда этот код:
$(function(){
$('#Form-secondaryTabs .tab-pane.layout-cell:not(:first-child)').addClass('padded-pane')
})
Все верно. Мы всем вкладкам кроме первой даем класс padded-pane
, который как раз и добавит нам отступа.
Теперь давайте скажем контролеру добавить этот скрипт на страницу.
просто в тело функции __construct()
добавляем вызов функции $this->addJS()
Финальный вид нашего контроллера
<?php namespace Octoclub\Tutorial\Controllers;
use Backend\Classes\Controller;
use BackendMenu;
class Items extends Controller
{
public $implement = [
'Backend\Behaviors\ListController',
'Backend\Behaviors\FormController'
];
public $listConfig = 'config_list.yaml';
public $formConfig = 'config_form.yaml';
public $bodyClass = 'compact-container breadcrumb-fancy';
public function __construct()
{
parent::__construct();
BackendMenu::setContext('Octoclub.Tutorial', 'items', 'items');
$this->addJs('/plugins/octoclub/tutorial/assets/js/item-form.js');
}
}
И вуаля! отступы есть везде кроме первой вкладки.
На этом все. Мы создали Fancy форму в стиле RainLab.Blog и Static Pages.