Colin R
Colin R

Reputation: 25

Yii2 dropDownList - Trouble updating multiple fields

Hi I am creating a dropdown list in Yii2 and am having trouble update multiple fields. I am new to this and have been searching for 2 days to try and find an answer with no luck.

I have two databases and 3 tables.

db1.area (contains id and name of a branch)

db2.majorregion ( id and name of major region)

db2.majorregionbranch (id, branchid[area.id], branchname[area.name], majorregionid)

I can pull and display the data into the drop down lists with no problems.

Here is where I get stuck.

I am pulling the id and name from the Area model, then choosing that name, then updating the major region assignment.

My trouble is updating both the area.id and area.name as branchid and branchname to db2.majorregionbranch. It will only seem to update the branchid and not the branchname as well.

The second dropdown for majoregionid work no problem.

Can anyone point me in the right direction as I seem to be going in circles with no luck.

Please let me know if you need any more info from me.

Here is my _form.php (generated with gii crud and the modified for dropdownlist)

<?php

use yii\helpers\Html;
use yii\widgets\ActiveForm;
use yii\helpers\ArrayHelper;
use app\models\MajorRegion;
use app\models\Area;

/* @var $this yii\web\View */
/* @var $model app\models\MajorRegionBranch */
/* @var $form yii\widgets\ActiveForm */
?>

<div class="major-region-branch-form">

    <?php $form = ActiveForm::begin(); ?>

    <?= $form->field($model, 'BranchID')->dropDownList(
        ArrayHelper::map(Area::find()->all(),
                         'id', 
                         'name'),
       ['prompt'=>'Select Branch']
    ) ?>

    <?= $form->field($model, 'MajorRegionID')->dropDownList(
        ArrayHelper::map(MajorRegion::find()->all(),
                        'ID', 
                        'MajorRegionName'), 
        ['prompt'=>'Select Major Region']
    ) ?>

    <div class="form-group">
        <?= Html::submitButton($model->isNewRecord ? 
            'Create' : 
            'Update', 
           ['class' => $model->isNewRecord ? 
                       'btn btn-success' :
                       'btn btn-primary']) ?>
    </div>

    <?php ActiveForm::end(); ?>
</div>

EDIT/Update: Adding in Table details.

area id and name are to be inserted into MajorRegionBranch as branch_id and branch_name, id from MajorRegion is to be inserted into MajorRegionBranch as major_region_id.

Both area id(branch_id) and major_region_id work fine, what doesn't work is inserting the area name(branch_name)

mysql> describe MajorRegionBranch;
+-----------------+-------------+------+-----+---------+-------+
| Field           | Type        | Null | Key | Default | Extra |
+-----------------+-------------+------+-----+---------+-------+
| ID              | int(32)     | NO   | PRI | NULL    |       | 
| branch_id       | int(32)     | YES  | MUL | 0       |       | 
| branch_name     | varchar(32) | YES  |     | NULL    |       | 
| major_region_id | int(32)     | YES  |     | 0       |       | 
+-----------------+-------------+------+-----+---------+-------+

mysql> describe MajorRegion;      
+-------------------+-------------+------+-----+---------+----------------+
| Field             | Type        | Null | Key | Default | Extra          |
+-------------------+-------------+------+-----+---------+----------------+
| ID                | int(32)     | NO   | PRI | NULL    | auto_increment | 
| major_region_name | varchar(32) | YES  |     | NULL    |                | 
+-------------------+-------------+------+-----+---------+----------------+

mysql> describe area;
+------------------------------+------------+------+-----+---------+-------+
| Field                        | Type       | Null | Key | Default | Extra |
+------------------------------+------------+------+-----+---------+-------+
| id                           | int(11)    | NO   | PRI | NULL    |       | 
| name                         | text       | NO   |     | NULL    |       | 
+------------------------------+------------+------+-----+---------+-------+

----More updates---- Here is the snippet from my controller for the create method

public function actionCreate()
{
    $model = new MajorRegionBranch();

    if ($model->load(Yii::$app->request->post()) && $model->save()){
        return $this->redirect(['view', 'id' => $model->ID]);
    } else {
        return $this->render('create', [
            'model' => $model,
        ]);
    }
}

Upvotes: 1

Views: 1493

Answers (1)

robsch
robsch

Reputation: 9728

The reason is your form takes only two properties of MajorRegionBranch into account: the two id properties. The form does not contain an input for the branch name. Of course, you don't want that, two dropdowns should be sufficient.

However, when the form gets submitted on create or update, the model object will be loaded and only receives those two id values . So 'name' in the model does not get a new value. The model doesn't know that the name should correspond to the id. There isn't this kind of magic.

You have different ways so solve this. You could:

  • modify the actions so that you set the name 'manually' (probably after load() but before save()/validate()
  • overwrite beforeSave() or save() in the model to set the name 'manually'
  • overwrite load() in the model to set the name 'manually'
  • implement setBranchId($value) in your model to set the name 'manually' at this point in time
  • put a hidden field into the form for the name ($form->field($model, 'BranchName')->hidden()) and set the value by JavaScript when dropDown has changed or before form gets submitted (this is a not so robust solution, the user could manipulate the name)
  • use the AttributeBehavior for the branch name property to automatically assign a value
  • ...

I would prefer the first approach since I don't like that the active record model object itself starts a query to fetch the name. It could look like this (untested):

public function actionCreate()
{
    $model = new MajorRegionBranch();

    $model->load(Yii::$app->request->post());

    //Next 3 lines will fetch the correct name for the branch name attribute
    $postedFormData = Yii::$app->request->post(MajorRegionBranch::formName());
    $area = Area::find()->where(['id' => $postedFormData['BranchID']])->one();
    $model->BranchName = $area->name;

    if ($model->save()){
        return $this->redirect(['view', 'id' => $model->ID]);
    } else {
        return $this->render('create', [
            'model' => $model,
        ]);
    }
}

Upvotes: 1

Related Questions