【问题标题】:How to update dynamic field in yii2如何更新yii2中的动态字段
【发布时间】:2017-02-23 13:58:07
【问题描述】:

我想在不使用任何库的情况下使用 jquery 创建动态字段。我有两个提交的表格,但一个提交label 我想创建多个时间,这实际上是问题选项,它可以不止一次。

在下面的 form.php 中,您会看到 label field 我多次使用 jquery 创建。我可以保存它们,但我不明白我将如何显示那些在update case 中提交的次数超过一次的文件。真的对不起我的英语。

控制器

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,
            ]);
        }
    }

型号

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);
?>

也许其他事情在我的代码中也不对,请建议我,我真的需要帮助。

【问题讨论】:

  • 我可以建议你一些事情,但之后你的验证将无法正常工作......

标签: yii2 yii2-advanced-app


【解决方案1】:

我有几个 cmets 可以改进和修改您的代码:

  1. 创建QuestionOptionsForm,它可以加载您动态添加的选项/标签。使用此模型迭代选项(可能从请求或数据库加载)。不要使用像$_GET['option_id'] 这样的语句(尤其是在视图中)。

  2. 当您在表单上(动态地)添加新选项时,为字段名称添加整数索引。例如label[45]。我通常使用带有替换功能的特殊 html 模板。使用这种方式代替现有行的克隆。例如:

    <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>
    

    注意:您需要将 现有 选项 ID 与 JS 代码中生成的 动态 分开。您可以为此使用 is_new_option 隐藏字段。

  3. 当您恢复现有选项时,使用它们的 ID 对它们进行索引。

  4. 然后,当您迭代选项时,为现有选项加载模型,并为动态生成的选项创建新模型。

    // ...
    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. 如有必要,您可以从 DB 选项中删除已在表单上删除的选项。

【讨论】:

  • 谢谢@IStranger。我没有得到它 $modelOption = $isNewModel?新的 QuestionsOptions(): QuestionsOptions::findOne($optionId);
  • 还有一件事,如果你把js代码放在最好的地方。当你有时间
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-11-12
  • 2018-11-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-23
  • 1970-01-01
相关资源
最近更新 更多