How to update dynamic field in yii2

送分小仙女□ 提交于 2019-12-14 03:20:56

问题


I want to create dynamic field with jquery without using any library. I have two filed in form but one filed label i want to create multiple time which is actually question option it can be more then one time.

In below form.php you see that label field i create with jquery in multiple time. I can save them but i am not understand how i will show those filed which was more then one time in update case. Really sorry for my english.

Controller

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

     if ($model->load(Yii::$app->request->post())) {
           if(sizeof(array_filter($_POST['QuestionsOptions']['label'])) > 0){
             foreach($_POST['QuestionsOptions']['label'] as $key => $row){
                  $model->setIsNewRecord(true);
                  $model->option_id = null;
                  $model->label = $row;
                  $model->save();
             } 
          }
         // exit;
            return $this->redirect(['view', 'id' => $model->option_id]);
        } else {
            return $this->renderAjax('create', [
                'model' => $model,
            ]);
        }
    }

Model

namespace app\models;
use Yii;

class QuestionsOptions extends \yii\db\ActiveRecord
{
    public static function tableName()
    {
        return 'questions_options';
    }
    public function rules()
    {
        return [
            [['question_id', 'label', 'type'], 'required'],
            [['question_id'], 'integer'],
            [['type'], 'string'],
            [['dated', 'updated'], 'safe'],
            [['label'], 'string', 'max' => 255],
            [['question_id'], 'exist', 'skipOnError' => true, 'targetClass' => SurveysQuestions::className(), 'targetAttribute' => ['question_id' => 'question_id']],
        ];
    }
    public function attributeLabels()
    {
        return [
            'option_id' => 'Option ID',
            'question_id' => 'Question ID',
            'label' => 'Label',
            'type' => 'Type',
            'dated' => 'Dated',
            'updated' => 'Updated',
        ];
    }
    public function getQuestionsAnswers()
    {
        return $this->hasMany(QuestionsAnswers::className(), ['option_id' => 'option_id']);
    }
    public function getQuestion()
    {
        return $this->hasOne(SurveysQuestions::className(), ['question_id' => 'question_id']);
    }
}

form.php

<?php

use yii\helpers\Html;
use yii\widgets\ActiveForm;

?>

<div class="surveys-questions-form">

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

    <?php

        if(isset($_GET['option_id']) and $_GET['option_id'] > 0)
            $id= $_GET['option_id'];
        else 
            $id= $model->option_id;
        echo $form->field($model, 'question_id')->hiddenInput(['value' => $id])->label(false);
    ?>

   <div class="col-md-6">
    <div id="question_wrapper">
        <?= $form->field($model, 'type')->dropDownList([ 'text' => 'Text', 'numbers' => 'Numbers', 'date' => 'Date', 'texarea' => 'Texarea', 'checkbox' => 'Checkbox', 'radio' => 'Radio', 'rating' => 'Rating', ], ['prompt' => '']) ?>
        <div id="add_more_field">
            <?= $form->field($model, 'label[]')->textInput(['maxlength' => true]) ?>

        </div>
        <div class="form-group">
            <?php
                echo Html::a('Add more', 'javascript:void(0);', [
                    'id' => 'surveys-questions-new-button', 
                    'class' => 'pull-right btn btn-primary btn-xs'
                ])
            ?>
        </div>
    </div>
   </div>
    <div class="col-md-12">
    <div class="form-group">
        <?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?>
    </div>
     </div>
    <?php ActiveForm::end(); ?>

</div>
<?php
$script = <<< JS
$(document).ready(function(){

    $('#surveys-questions-new-button').on('click', function () {
        $("#add_more_field").clone().appendTo("#question_wrapper"); 
    });

}); 

JS;
$this->registerJs($script);
?>

Maybe other thing is also not right in my code please can suggest me I am really want help.


回答1:


I have few comments to improve and rework your code:

  1. Create QuestionOptionsForm that may load your dynamically added options/labels. Use this model for iteration the options (that may be loaded from request or DB). Don't use statements like $_GET['option_id'] (especially in a view).

  2. When you add new options (dynamically) on the form, add integer-index for the field names. For example label[45]. I used usually special html template with replacements. Use this way instead clone of existing rows. For example:

    <div class="js-new-option-template">
        <input type="text" name="option[{{OPTION_ID}}][label]"/>
        <input type="hidden" name="option[{{OPTION_ID}}][is_new_option]"/>
    </div>
    

    NOTE: you need to separate existing option IDs from the dynamically generated in a JS code. You can use is_new_option hidden field for this.

  3. When you restore the existing options, index them using their IDs.

  4. Then when you iterate options, load models for existing options, and create new models for the dynamically generated.

    // ...
    foreach ($modelForm->options as $optionId => $optionData) {
    
        // Prepare data
        $isNewModel     = \yii\helpers\ArrayHelper::getValue($optionData, 'is_new_option', true);
        $optionLabel    = \yii\helpers\ArrayHelper::getValue($optionData, 'label');
        $optionQuestion = \yii\helpers\ArrayHelper::getValue($optionData, 'question_id');
    
        // Create or find options model
        $modelOption = $isNewModel
            ? new QuestionsOptions()
            : QuestionsOptions::findOne($optionId);
    
        if (!$modelOption) {
            throw new \yii\web\NotFoundHttpException('Cannot be found option record with the id = ' . $optionId);
        }
    
        // Populate and save model
        $modelOption->label       = $optionLabel;
        $modelOption->question_id = $optionQuestion;  // foreign key
    
        if (!$modelOption->save()) {
            throw new \yii\base\Exception('Cannot be saved new option record.');
        }
    }
    
  5. If necessary, you can delete from DB options, that has been deleted on the form.



来源:https://stackoverflow.com/questions/42417814/how-to-update-dynamic-field-in-yii2

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!