Компоненты
Поля с автоподбором (autocomplete)
В случае большого количества элементов для выбора значения поля в выпадающем списке, например подкатегорий или городов,
удобно заменить select на поле с автоподбором вариантов.
Реализовать такой тип поля позволяет метод autocomplete(field_name, field_title, callback_search, callback_default, placeholder)
$form->autocomplete(
'subcat_id', # атрибут `name` поля формы
$this->langAdmin('Подкатегория'), # заголовок поля
function ($query) { # callback автоподбора вариантов
$result = [];
if (!empty($query)) {
$filter = [
':q' => ['title LIKE :q', ':q' => '%'.$query.'%'],
];
$data = $this->model->catsListing($filter); # получаем подходящие данные из модели
foreach ($data as $v) {
$result[] = [$v['id'], $v['title']];
}
return $result;
},
function ($id) { # callback ранее сохраненного значения
$data = $this->model->catData($id);
return ! empty($data['title']) ? $data['title'] : '';
},
$this->langAdmin('Введите название подкатегории') # placeholder
);
Третьим параметром метода autocomplete()
является callback автоподбора вариантов:
- принимает в качестве аргумента
$query
- строка поиска, - требует наличия необходимого метода модели, который и будет осуществлять поиск по таблице БД,
- возвращать должен массив в формате
[[$id_1, $title_1], [$id_2, $title_2], ...]
.
Следующим параметром является callback ранее сохраненного значения при редактированиии записи из списка:
- принимает в качестве аргумента
$id
- id подкатегории текущей записи, - требует наличия необходимого метода модели, который и будет возвращать
title
значения поля, - возвращать должен с троку с заголовком ранее сохраненного значения или пустую строку.
Теги
Теги позволяют задать дополнительные характеристики в виде ключевых слов к объекту, что удобно использовать при поиске по списку.
Подробнее о создании компонента Tags ($tagsComponent
) вы можете узнать из статьи.
Для добавленния тегов и вывода их в список в админ-контроллере создаем достаточно простой метод:
/**
* Список тегов
*/
public function tags()
{
# получаем объект компонента работы с тегами \bff\db\Tags
$tagsComponent = $this->initTags();
return $tagsComponent->manage();
}
Ключевым является вызов метода manage()
- управляет списком, формой добавления и редактирования тегов.
Связываем объект, к примеру публикацию, с тегами. Для этого в форме добавления/редактирования публикации создаем поле выбора тегов
при помощи метода компонента формы tagsComponent($tagsComponent, field_title, field_width)
.
$form->tagsComponent(
$tagsComponent, # компонент работы с тегами
$this->langAdmin('Теги'), # заголовок поля
675 # ширина поля в px
);
Есть альтернативный вариант использования поля тегов в форме объекта(публикации) -
метод компонента формы
tags(field_name, field_title, сallback_autocomplete, callback_default, is_rotate, placeholder)
.
$form->tags(
'post_tags', # атрибут `name` поля формы
$this->langAdmin('Теги'), # заголовок поля
function ($query) { # callback автоподбора тегов
$result = [];
if (!empty($query)) {
$filter = [
':q' => ['title LIKE :q', ':q' => '%'.$query.'%'],
];
$data = $this->model->tagsListing($filter); # получаем подходящие данные из модели
foreach ($data as $v) {
$result[] = array($v['id'], $v['title']);
}
}
return $result;
},
function ($ids) { # callback ранее сохраненных значений
$data = $this->model->tagsListing(['id' => $ids]);
foreach ($data as & $v) {
$v['value'] = $v['id'];
}
return $data;
},
true,
'Введите название, например (one)'
);
Удобство такого способа работы с тегами состоит в том, что есть возможность управлять автоподбором тегов в сallback_autocomplete, таким образом теги могут храниться в таблице БД любого вида и форма создания и список тегов может быть задан любым удобным способом. Аналогично полю автозаполнения сallback_autocomplete для поля тегов
- принимает в качестве аргумента
$query
- строку поиска, - требует наличия необходимого метода модели, который и будет осуществлять поиск по таблице тегов в БД,
- возвращать должен массив в формате
[[$id_tag_1, $title_tag_1], [$id_tag_2, $title_tag_2], ...]
.
Следующим параметром является callback_default ранее сохраненных тегов для связанной сущности публикации, актуально при редактировании:
- принимает в качестве аргумента
$ids
- ids ранее сохраненных тегов в формате[$tag_id_1, $tag_id_2, $tag_id_3, ...]
, - требует наличия необходимого метода модели, который и будет возвращать данные по искомым тегам,
- обязательно наличие данных по тегам в формате
[[ 'title' => $title, 'value' => $id ], ...]
При таком подходе храним теги объекта в виде массива в поле 'post_tags'
основной таблицы объектов(публикаций) типа TEXT
,
при этом название поля может быть любым, главное учесть соответствие с ключем поля в форме.
Конструктор контента Publicator
В качестве конструктора контента рекомендуем использовать Publicator, позволяющий форматировать текст, загружать изображения, добавлять видео, делать цитаты и заголовки.
Подробнее о создании компонента Publicator ($publicatorComponent
) и задании его настроек $publicatorSettings
вы можете узнать из статьи.
Рассмотрим публикатор как поле формы в админ-панели.
Объявление такого конструктора выполняется довольно просто, использовав метод
publicator(field_name, field_search_name, is_lang, controls, settings)
Параметрами являются название поля в БД, в котором будут храниться непосредственно данные из конструктора в виде строки json,
а также требуется наличие в таблице БД поля для осуществления поиска по текстовому содержимому контента, данные поля должны быть типа TEXT
.
$form
->publicator(
'content', # данные(поле) конструктора
'content_search' # данные(поле) для текстового поиска
);
Приведем пример как можно задавать разрешенные типы блоков конструктора в форме, оставив возможность добавлять только текст и изображения:
$form->publicator(
'content', # данные(поле) конструктора
'content_search', # данные(поле) для текстового поиска
true, # использовать мультиязычность
[ # разрешенные блоки
\bff\db\Publicator::blockTypeText,
\bff\db\Publicator::blockTypePhoto,
],
$publicatorSettings # настройки компонента
);
Динамические свойства (Dynprops)
Динамические свойства позволяют комплексно добавлять свойства к объекту и удобно использовать их в разрезе фильтрации по списку. Подробнее о данном компоненте вы можете прочитать в данной статье.
Выбор динамических свойств
Выбор динамических свойств осущеcтвляется в форме создания/редактирования объекта в связке с обязательным выбором категории объекта.
Так при создании объекта выбираем к какой категории он будет относиться, далее задаем значения свойств выбранной категории.
В форме связываем выбор категории с добавлением поля типа "Динамические свойства" при помощи метода dynprops(object_dp, field_owner)
,
параметрами являются объект компонента Dynprops $dynpropsComponent
и наименование поля выбранной категории (cat_id):
$form->select('cat_id', $this->langAdmin('Категория'), false, function($field) use($form) {
# получаем список категорий и формируем список в виде HTML::options
$data = $this->model->catsListing();
$result = [];
if ( ! $form->recordID()) {
# для нового объекта добавляем пункт "Выбрать"
$result[] = '<option value="0">'.$this->langAdmin('Выбрать').'</option>';
}
$val = $field->value();
foreach ($data as $v) {
# помечаем выбранную категорию (при редактировании)
$result[] = '<option value="'.$v['id'].'"'.($val == $v['id'] ? ' selected="selected"' : '').'>'.$v['title'].'</option>';
}
return join('', $result);
);
# Указываем на необходимость отобразить дин.свойства категории при выборе из списка, передаем объект компонента и название поля выбора категории
$form->dynprops($dynpropsComponent, 'cat_id');
Сохраняются выбранные динамические свойства вместе с остальными полями публикации в обработчике сохранения формы:
$form->onSave(function($id, $data) {
return $this->model->postSave($id, $data);
});
Добавление динамических свойств в список категорий
В списке категорий, возможность добавлять динамические свойства доступна в колонке Действие (рядом с редактированием и удалением). Осуществляется при помощи метода onDynprops(dynpropsObject)
, параметром является ранее созданный компонент динамических свойств:
$list->onDynprops($dynpropsComponent);