Кажется, у меня возникли проблемы с созданием входных данных формы, которые позволяют флажкам и вложенным наборам работать вместе.
То, что я хотел бы, это что-то вроде того, что делает bookbub:
http://i.imgur.com/PfpgSf5.jpg
Прямо сейчас в моей базе данных она имеет следующую структуру:
Category table
- id
- name
- parent_id
По сути, моя идея состоит в том, чтобы отобразить все в _form, у которого parent_id имеет значение null в качестве заголовка (без флажка), и все, у кого parent_id установлен в качестве флажка под соответствующим заголовком.
Тем не менее, единственное решение, которое я могу найти, это не позволяет мне иметь уже отмеченные флажки, если мы обновляем пользовательские настройки. Это, однако, отображает вещи именно так, как я хотел бы. Вот что у меня так далеко:
ProfileReader’s (ProfileReader — моя модель, которая расширяет возможности пользователей хранить свои предпочтения) _form:
<?php
$primaryCategories = (new Category)->getPrimaryCategories();
//$selectedCategories = yii\helpers\ArrayHelper::map($model->categories, 'id', 'name');
foreach ($primaryCategories as $pc) {
echo '<p>'.$pc->name.'</p>';
if ($pc->subCategories) {
//the following never fully worked. It doesn't automatically check the boxes for relations that
//are already setup. You need to somehow use $model->categories[#] and 'id' for that to work
//echo $form->field($model->categories[#], 'id')->label(false)
echo $form->field($pc, 'subCategories[' . $pc->id . '][]')->label(false)
->checkboxList(yii\helpers\ArrayHelper::map($pc->subCategories, 'id', 'name'),
['separator' => '<p>']);
}
}
?>
ProfileReaderController:
public function actionUpdate()
{
$model = $this->findModel(\Yii::$app->user->identity->id);
if ($model == null) {
$model = new ProfileReader();
$model->user_id = \Yii::$app->user->identity->id;
}
if ($model->load(Yii::$app->request->post()) && $model->save()) {
//link the categories to the pen name
$categories = Yii::$app->request->post()['Category']['subCategories'];
$model->unlinkAll('categories', true);
foreach ($categories as $category) {
if ($category)
foreach ($category as $c) {
$c = (new Category)->findOne($c);
$model->link('categories', $c);
}
}
return $this->redirect(['update']);
} else {
return $this->render('update', [
'model' => $model,
]);
}
}
ProfileReader:
public function getCategories()
{
return $this->hasMany(Category::className(), ['id' => 'category_id'])
->viaTable('user_category', ['user_id' => 'user_id']);
}
Кто-нибудь знает, как я могу сделать эту работу? Возможно ли это даже в Yii2 с activeform?
Хорошо, через много часов я наконец-то понял это. Размещение моего результирующего кода здесь, чтобы он мог помочь кому-то еще. Не проси меня объяснить это, так как я сам не до конца понимаю: P
Также может быть хорошей идеей провести некоторое тестирование на нем, прежде чем бросать его в живую среду, я еще этого не делал.
обновить действие:
/**
* Updates an existing ProfileReader model.
* If update is successful, the browser will be redirected to the 'view' page.
* @param integer $id
* @return mixed
*/
public function actionUpdate()
{
$model = $this->findModel(\Yii::$app->user->identity->id);
if ($model == null) {
$model = new ProfileReader();
$model->user_id = \Yii::$app->user->identity->id;
}
if ($model->load(Yii::$app->request->post()) && $model->save()) {
//unlink the categories first to avoid duplicates
$model->unlinkAll('categories', true);
//link the categories to the pen name
foreach ($model->categoriesArray as $pc) {
if ($pc) {
foreach ($pc as $sc) {
$sc = (new Category)->findOne($sc);
$model->link('categories', $sc);
}
}
}
return $this->redirect(['update']);
} else {
//get the categories and separate them into groups based on parent_id
foreach ($model->categories as $c) {
$model->categoriesArray[$c->parent_id][] = $c;
}
return $this->render('update', [
'model' => $model,
]);
}
}
Модель ProfileReader (пришлось добавить переменную):
public $ CategoriesArray;
_form:
<label class="control-label">Categories</label>
<?php
$allCategories = (new Category)->getOrderedCategories();
foreach ($allCategories as $pc) {
echo '<p>'.$pc['name'].'</p>';
echo $form->field($model, 'categoriesArray['.$pc['id'].'][]')->label(false)
->checkboxList(yii\helpers\ArrayHelper::map($pc['subCategories'], 'id', 'name'),
['separator' => '<p>']);
}
?>
Других решений пока нет …