Тулбар для формы бэкенда

Делаем панель toolbar с кнопками управления и ссылкой на фронтенд-страницу для формы бэкенда (страницы Создать/Редактировать) для макета fancy-layout.

Первым делом в определении полей добавляем поле form_toolbar с типом partial, которому назначаем CSS-класс collapse-visible:

plugins/authorName/blog/models/post/fields.yaml
form_toolbar:
    type: partial
    cssClass: collapse-visible

Затем в папке контроллера создаём файл _form_toolbar.php, где будет прописана структура тулбара. Обратите внимание, что название файла _form_toolbar.php начинается с нижнего подчёркивания.

plugins/authorName/blog/controllers/posts/_form_toolbar.php
<?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 wn-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 wn-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 wn-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 wn-icon-trash-o"
            data-request="onDelete"
            data-request-confirm="Вы действительно хотите удалить эту запись?"
            data-control="delete-button"
        ></button>
    <?php endif ?>
</div>

Кнопка сворачивания панели

Если мы хотим чтобы шапка формы компактно сворачивалась, делаем следующее.

В самый низ файла _form_toolbar.php добавляем:

plugins/authorName/blog/controllers/posts/_form_toolbar.php
<!-- Кнопка сворачивания панели -->
<a href="javascript:;" class="tab-collapse-icon tabless">
    <i class="icon-chevron-up"></i>
</a>

В файле контроллера внутри метода __construct для действия (экшенов) update или create подключаем JavaScript для кнопки сворачивания формы

plugins/authorName/blog/controllers/Posts.php
public function __construct()
{
    // ... какой то код

    /**
     * Это страница бекенд формы (страница Создать/Редактировать)
     */
    if ($this->action === 'update' || $this->action === 'create') {
        $this->addJs('$/authorName/blog/assets/js/form-collapse.js');
    }
}

Не забудьте в указаном пути исправить authorName на ваше имя разработчика.

Создаём файл form-collapse.js и добавляем в него следующий код:

plugins/authorName/blog/assets/js/form-collapse.js
/**
 * Скрипт для сворачивания шапки формы в fancy-layout
 */

let keyStorageCollapse;

function toggleCollapseForm() {
    document.getElementById('Form-outsideTabs').classList.toggle('collapsed');

    localStorage.setItem(keyStorageCollapse, localStorage.getItem(keyStorageCollapse) == 1 ? 0 : 1);
}

/**
 * Добавляет строкам метод makeFirstToUpperCase, который делает первую букву строки заглавной
 * @returns исходная строка с первой заглавной буквой
 */
String.prototype.makeFirstToUpperCase = function() {
    return this.charAt(0).toUpperCase() + this.slice(1);
}

/**
 * @returns string Ключ для localStorage - backendFormCollapseAuthorPluginModel
 */
function getKeyStorageCollapse() {
    let pathnameArr = window.location.pathname.split('/');
    pathnameArrLength = pathnameArr.length;

    let keyStorageArr;

    if (pathnameArr[pathnameArrLength - 1] === 'create') {
        keyStorageArr = pathnameArr.slice(pathnameArrLength - 4, pathnameArrLength - 1);
    }
    else {
        keyStorageArr = pathnameArr.slice(pathnameArrLength - 5, pathnameArrLength - 2);
    }

    let keyStorageSuffix = keyStorageArr.map(str => str.toLowerCase().makeFirstToUpperCase()).join('');

    return 'backendFormCollapse' + keyStorageSuffix;
}

document.addEventListener('DOMContentLoaded', () => {
    let btnCollapse = document.querySelector('.tab-collapse-icon');

    if (btnCollapse) {
        keyStorageCollapse = getKeyStorageCollapse();

        if (localStorage.getItem(keyStorageCollapse) == 1) {
            document.getElementById('Form-outsideTabs').classList.add('collapsed');
        }

        btnCollapse.addEventListener('click', toggleCollapseForm);
    }
});

Кнопка на страницу на фронте

Добавим в тулбар кнопку, которая будет вести на фронтенд-страницу записи.

Если урл на страницу на фронте зависит от полей формы (к примеру от slug /blog/posts/:slug), то в определении полей устанавляваем нашему полю тулбара зависимость (свойство dependsOn) со значением [slug]. Таким образом при изменении поля Slug будет тут же обновляться ссылка на фронтенд страницу.

plugins/authorName/blog/models/post/fields.yaml
form_toolbar:
    type: partial
    dependsOn: [slug]
    cssClass: collapse-visible

Если урл страницы по id (например /blog/posts/:id), то в этом случае зависимость dependsOn добавлять полю тулбара не нужно. Просто пропустите это действие.


Во внутрь div с классом form-buttons

<div class="form-buttons loading-indicator-container">

    <!-- Тут уже есть кнопки -->

</div>

вставляем ссылку ведущую на фронтенд страницу:

plugins/authorName/blog/controllers/posts/_form_toolbar.php
<?php if (!$isCreate): ?>
    <a
        href="<?= \Cms\Classes\Page::url('blog/post', ['slug' => $model->slug]) ?>"
        class="btn btn-primary wn-icon-arrow-up-right-from-square"
        target="_blank"
        rel="noopener noreferrer"
        data-toggle="tooltip"
        data-placement="top"
        data-delay="300"
        title="Открыть страницу записи"
    ></a>
<?php endif ?>

В атрибуте href указано значение получаемое из PHP. Вот тут можно узнать пояснение этому коду.

Вместо этого можете прописать ссылку таким образом:

href="/blog/posts/<?= $model->slug ?>"

На этом всё.

По такому же принципу можно добавлять в тулбар любые другие элементы.

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

*** чтобы писать комментарии.