D
D
Dmitry2017-08-20 19:48:56
MySQL
Dmitry, 2017-08-20 19:48:56

How to display data from a linked table in dropDownLIst in yii2?

Good evening.
There was a small issue with outputting data to a dropDownList from a related table.
There are three tables in the database:
1) Recipe // table with recipes
2) Ingredients // table with ingredients
3) RecipesIngredients // link table, store id of recipes and ingredients
Links are configured in the models:

// Recipe model
    public function getIngred()
    {
        return $this->hasMany(Ingredients::className(), ['id' => 'ingredient_id'])->viaTable('{{%recipes_ingredients}}', ['recipe_id' => 'id']);
    }

// Ingredients
    public function getRecipe()
    {
       return $this->hasMany(Recipe::className(), ['id' => 'recipe_id'])->viaTable('{{%recipes_ingredients', ['ingredient_id' => 'id']);
    }

Also in the Ingredients model there is a method that displays all available ingredients.
public static function getActiveIngred()
    {
        return ArrayHelper::map(self::find()->where(['status' => self::STATUS_ACTIVE])->orderBy('name')->all(), 'id', 'name');
    }

In the RecipeController controller, the action to create the recipe
public function actionCreate()
    {
        $model = new Recipe();
        for($i=0; $i<5; $i++){
            $ingredient[] = new Ingredients();
        }

        $ingreds = Yii::$app->request->post('Ingredients');

        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            foreach($ingreds as $ingred){
                $recipe_ingred = new RecipesIngredients();
                $recipe_ingred->recipe_id = $model->id;
                $recipe_ingred->ingredient_id = $ingred['name'];
                $recipe_ingred->save();
            }
            return $this->redirect(['view', 'id' => $model->id]);
        } else {
            return $this->render('create', [
                'model' => $model,
                'ingredient' => $ingredient
            ]);
        }
    }

Form to create a recipe
<?= $form->field($model, 'name')->textInput(['maxlength' => true]) ?>

        <?php
           foreach($ingredient as $key => $value){
             echo $form->field($value, '['.$key.']name')->dropDownList(Ingredients::getActiveIngred(), ['prompt' => 'Выбрать']);
           }

        ?>
  
        <?= $form->field($model, 'status')->dropDownList(Recipe::getStatusesArray()) ?>
        <?= Html::submitButton($model->isNewRecord
                               ? 'Сохранить'
                               : 'Обновить',
                               ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>

Everything works fine, when creating a recipe, a form is displayed with a field for the name of the recipe and five drop-down lists for selecting ingredients.
But while editing I got a problem.
How can I display dropdown lists with ingredients already selected?
I tried using the Ingredients::getActiveIngred() method , the required number of ingredients is displayed in the form (which were selected when creating the record, selects), but instead of the saved ingredient, the prompt "Select" is displayed.
Tell me, what did I miss?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Dmitry, 2017-08-21
@slo_nik

The solution is:

foreach($ingredient as $key => $value){
   echo $form->field($value, '['.$key.']name')->dropDownList(Ingredients::getActiveIngred(),
                                                             !$value->isNewRecord ?
                                                               [
                                                                 'options' => [
                                                                                $value->id => ['selected' => true]
                                                                              ]
                                                               ]
                                                             : ['prompt' => 'Выбрать']);
}

Now, when creating a new record, each select will have "Select", and when editing a record, the saved ingredient will go first.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question