unclead / yii2-multiple-input

Yii2 widget for handle multiple inputs for an attribute of model
https://unclead.github.io/yii2-multiple-input/
BSD 3-Clause "New" or "Revised" License
393 stars 127 forks source link

Is it possible to keep the selected value of a DepDrop when submit returns error? #360

Open sayed201201180 opened 3 years ago

sayed201201180 commented 3 years ago

I have a dropdown and a DepDrop for each row. When there is an error in submission, only the DepDrop value is lost since there is a function to retrieve the data options. I have tried with regular dropdowns, and I have tried to pass the selected value to the DepDrop’s function or to capture it with POST. I tried to see how I can keep the values using a function inside the model, which I already do for “required” validation. I have never found a solution. Any help is appreciated thanks.

image

View:

echo $form->field($model, 'selected_attributes',
        [
            'options'=>['id'=>'select-attributes']
        ])->widget(MultipleInput::className(), [
            'id' => 'my_id',
            'min' => 1,
            'cloneButton' => false,
            'enableError' => true,
            'rowOptions' => [
                'id' => 'row{multiple_index_my_id}',
            ],
            'columns' => [
                [
                    'name'  => 'id',
                    'type'  => 'hiddenInput',
                    'options' => [
                        'id'=>'id_{multiple_index_my_id}',
                    ]
                ],
                [
                    'name'  => 'attribute_id',
                    'type'  => 'dropDownList',
                    'title' => 'Attribute',
                    'items' => ArrayHelper::map($attributes,'id','attribute_name'),
                    'options' => [
                        'id'=>'attribute_id_{multiple_index_my_id}',
                        'prompt'=>'Choose ...',

                    ],
                ],

                [
                    'name'  => 'attribute_value_id',
                    'type'=> DepDrop::classname(),
                    'title' => 'Value',
                    'options'=> [
                        'pluginOptions' => [
                            'depends' => ['attribute_id_{multiple_index_my_id}'],
                            'url'=>Url::to(['shop-item/get-attribute-values']),
                            'initialize' => true,
                            'initDepends'=>['attribute_id_{multiple_index_my_id}'],
                            //'params' => ['attribute_value_id_{multiple_index_my_id}'],

                        ],
                        'options' => ['placeholder' => 'Choose ...']
                    ],                    
                ],

                [
                    'name'  => 'additional_charge',
                    'type'  => 'textInput',
                    'title' => 'Additional Charge',
                ], 
            ]

        ])->label('Attributes');

Controller:

public function actionGetAttributeValues() {
        Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

        if (isset($_POST['depdrop_parents'])) {
            $parents = $_POST['depdrop_parents'];
            if ($parents != null) {
                $attr_id = $parents[0];
                $attribute = Attribute::find()->where(['id'=>$attr_id])->one();

                $data = null;
                foreach ($attribute->attributeValues as $value){
                    $data[] = ["id"=>$value->id, "name"=>$value->value];
                }

                /*$param1 = null;
                if (!empty($_POST['depdrop_params'])) {
                    $params = $_POST['depdrop_params'];
                    $param1 = $params[0];
                }*/

                return ['output'=>$data, 'selected'=>''];

            }
        }
        return ['output'=>'', 'selected'=>''];
    }

Validation function in model:

public function rules()
    {
        return [
            ['selected_attributes', 'validateValues'],
            //['selected_attributes', 'keepValues'],
        ];
    }

public function validateValues($attribute)
    {
        foreach($this->$attribute as $index => $value) {
            $attr_id = ArrayHelper::getValue($value, 'attribute_id', null);
            $attr_val_id = ArrayHelper::getValue($value, 'attribute_value_id', null);
            $this->internalValidateValue($index, $attr_id, 1);
            $this->internalValidateValue($index, $attr_val_id, 2);
        }
    }

    private function internalValidateValue($index, $data, $type)
    {
        $requiredValidator = new yii\validators\RequiredValidator();
        $error = null;

        $requiredValidator->validate($data, $error);
        if (!empty($error)) {
            if ($type == 1){
                $key = sprintf('selected_attributes[%d][attribute_id]', $index);   
            }
            else{
                $key = sprintf('selected_attributes[%d][attribute_value_id]', $index); 
            }
            $this->addError($key, "Please select a value");
        }
    }
ProgDMMTD3 commented 1 year ago

Hello, did you find any solution for it? I am having a similar problem, it happens that I have a select2 and two DepDrops dependent on it, apart in the same form add a MultipleInput in which a column is of the DepDrop type that also depends on Select2, by adding a new row to the MultipleInput all the DepDrops dependent on select2 are initialized and I don't understand why, can anyone name a solution?