我似乎在创建表单输入时遇到了一些麻烦,该表单输入允许复选框列表和嵌套集合一起工作。
我想要的是与bookbub完全相同的东西: http://i.imgur.com/PfpgSf5.jpg
现在我的数据库中的结构如下:
Category table
- id
- name
- parent_id
基本上,我的想法是在_form上显示所有内容,其中parent_id为null作为标题(无复选框)以及将parent_id作为相应标题下的复选框的所有内容。
然而,如果我们正在更新用户的偏好设置,那么我可以得到的唯一解决方案似乎不允许我选中复选框。然而它确实显示了我想要的东西。这是我到目前为止所做的:
ProfileReader(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吗?
答案 0 :(得分:0)
好的,经过几个小时我终于明白了。在此处发布我生成的代码,以便它可以帮助其他人。不要让我解释它,因为我自己没有完全理解它: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>']);
}
?>