phpyii2checkboxlist

Utilising Yii2.0 checkboxlist for Parent-child relation models


i have a Questions model and Answers model in which Question to Answer is one-many relation. How do i implement checkboxlist in Yii2 so that it will display in a form as follows:

Form: 

Question 1 description
     [checkbox] Answer 1 description
     [checkbox] Answer 2 description

Question 2 Description
     [checkbox] Answer 3 description
     [checkbox] Answer 4 description

Question 3 Description
     [checkbox] Answer 5 description
     [checkbox] Answer 6 description

[Save button]

When i click save and for eg. Answer 1 and Answer 3 is checked, post should return "1,3" in a string. How do i do that using checkboxlist? I tried with my codes but right now it only captures values of Answer 5 and Answer 6 if they are checked. If Answer 1 to Answer 4 is checked, it they are not captured. Should be something wrong with my loop.

Hope someone can help me please.. Thanks alot

Updated:I restructured my codes but still it only captures values from the answers belonging to last question:

<?php
$form = ActiveForm::begin([
    'id' => 'form',
    'type' => ActiveForm::TYPE_HORIZONTAL,

]);
?>

<?php

$qnamodel = $questionmodel->joinWith('answermodel')->all();
$selected_array = array_map('intval', explode(',', $selected_list));    
foreach($qnamodel as $num=>$per_qn)
{

        echo '<div class="form-group"><div class="col-sm-9">'.$per_qn->QN_DESC.'</div></div>';

        foreach($per_qn->answermodel as $per_ans)
        {

            $arr_list[$per_qn->QA_TABLE_ID][$per_ans->QA_ANS_TABLE_ID] = $per_ans->ANS_DESC;
        }


        $recordmodel->ANS_TABLE_ID = $selected_array;

    echo $form->field($recordmodel, 'ANS_TABLE_ID', ['template' => "{label}\n{input}\n{hint}"])->checkboxList($arr_list[$per_qn->QA_TABLE_ID], $selected_array, ['separator' => '<p>'])->label(false);


echo '<p><br />';
}

?>

<?= Html::submitButton('save', ['class' => 'btn btn-primary']) ?>
<?phpgmst
ActiveForm::end();
?>


In Question Model
    public function getAnswermodels()
    {
        return $this->hasMany(Answermodel::className(), ['QN_TABLE_ID' => 'QA_TABLE_ID']);
    }

In Answer Model
    public function getQNTABLE()
    {
        return $this->hasOne(Questionmodel::className(), ['QA_TABLE_ID' => 'QN_TABLE_ID']);
    }

Solution

  • If I've understood you view logic correctly, you ought to be able to do something like this. I've put in generic field names and table names to make the code a bit easier to read. I've also stripped out some of the other code to make it easier to see what's going on. This should replace the whole of your posted code for the view;

        foreach ($model->questions as $question) {
            echo '<p>' . $question->description . '</p>';
            if ($question->answers) {
                echo $form->field($question, 'answers[' . $question->id . '][]')->checkboxList(yii\helpers\ArrayHelper::map($question->answers, 'id', 'description'), ['separator' => '<p>']);
            }
        }
    

    This first part loops through all the possible questions for the model. If that question has answers, then it displays a checkbox list for those answers. The arrayHelper is an easy way of getting an array of values from an array of models; given an array of models, you use this to get an array indexed by id, with labels from the description.

    It's really important to note that checkboxlist will submit the data as an array, so the name of the attribute needs to be an array. So the attribute for the checkboxlist needs to be of the form 'answers[' . $question->id . '][]'. When the form is submitted you will get an attribute named answer, with an index of the question id, with a sub-array of the answers selected for that question. This way you will know what question the answer has been selected for. I hope that this helps!