Задача - вывести все настройки на одной странице для редактирования.
Замечание - на самом деле есть еще 2 поля - group (группа свойств, для группировки настроек на странице, сделал в виде табов) и type - тип поля (строка, текст, чекбокс...), но они сейчас не важны.
Возможно - велосипед, если, кто знает - как это сделать лучше, проще - отпишите.
Нестандартность сводится к тому, что динамическая модель, если я правильно понял, изначально предназначена для валидации.
Опишу основную идею, как решил задачу (сохранение вынес за рамки поста).
1. gii сгенерил crud и модель.
2. Добавил новый класс, наследуемый от yii\base\DynamicModel - нужен для возможности указать метки к полям.
Код: Выделить всё
<?php
namespace app\components\base;
class DynamicModel extends \yii\base\DynamicModel
{
protected $_labels = [];
public function attributeLabels()
{
return $this->_labels;
}
public function setAttributeLabels($labels = [])
{
$this->_labels = $labels;
}
}
Код: Выделить всё
public function actionProfile()
{
$options = [];
$data = [];
$labels = [];
/** @var Options[] $optionsRaw */
$optionsRaw = Options::find()
->orderBy(['title' => SORT_ASC])
->all();
// Группировка свойств, подготовка данных для динамической модели
foreach ($optionsRaw as $opt) {
$options[$opt->group_title][$opt->alias] = $opt;
$data[$opt->alias] = $opt->text_value;
$labels[$opt->alias] = $opt->title;
}
unset($optionsRaw);
// создание модели
$model = new DynamicModel($data);
$model->setAttributeLabels($labels);
return $this->render('profile', [
'options' => $options,
'model' => $model,
]);
}
Код: Выделить всё
<?php
use yii\bootstrap\ActiveForm;
/* @var $this yii\web\View */
/* @var $options array */
/* @var $gOptions \app\modules\admin\models\base\Options[] */
$this->title = 'Настройки';
$this->params['breadcrumbs'][] = $this->title;
?>
<?php $form = ActiveForm::begin() ?>
<div class="options-profile" id="profileOptions">
<div class="list-group col-lg-3 col-md-4 col-sm-4 col-xs-6">
<?php foreach ($options as $group => $gOptions) { ?>
<!-- md5 нужно просто для того, чтобы русские названия перевести в латинские, чтобы не заморачиваться с транслитерацией -->
<a href="#<?= md5($group)?>" class="list-group-item">
<?=$group?>
</a>
<?php } ?>
</div>
<div class="col-lg-9 col-md-8 col-sm-8 col-xs-6">
<?php foreach ($options as $group => $gOptions) { ?>
<div class="tab-pane" id="<?=md5($group)?>">
<?php foreach ($gOptions as $alias => $opt) { ?>
<?=$form->field($model, $alias)->textarea()?>
<?php } ?>
</div>
<?php } ?>
</div>
</div>
<?php ActiveForm::end(); ?>
<?php $this->registerJs("
// временная заглушка для табов
$(function(){
var p = $('#profileOptions');
$('.tab-pane', p).hide();
p.on('click', '.list-group-item', function() {
$('.tab-pane', p).hide();
$('.list-group-item', p).removeClass('active');
$(this).addClass('active');
$($(this).attr('href')).show();
return false;
});
$('.list-group-item:first', p).trigger('click');
});
");?>