如何在yii2中更新动态字段 [英] How to update dynamic field in yii2

查看:64
本文介绍了如何在yii2中更新动态字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

控制器

公共函数 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();}}//出口;返回 $this->redirect(['view', 'id' => $model->option_id]);} 别的 {return $this->renderAjax('create', ['模型' =>$模型,]);}}

型号

namespace app\models;使用 Yii;类 QuestionsOptions 扩展 \yii\db\ActiveRecord{公共静态函数 tableName(){返回 '​​questions_options';}公共函数规则(){返回 [[['question_id', 'label', 'type'], 'required'],[['question_id'], '整数'],[['类型'],'字符串'],[['过时','更新'],'安全'],[['label'], 'string', 'max' =>[255],[['question_id'], 'exist', 'skipOnError' =>真,'targetClass' =>SurveysQuestions::className(), 'targetAttribute' =>['question_id' =>'question_id']],];}公共函数attributeLabels(){返回 ['option_id' =>'选项 ID','question_id' =>'问题ID','标签' =>'标签','类型' =>'类型','过时' =>'日期','更新' =>'更新',];}公共函数 getQuestionsAnswers(){返回 $this->hasMany(QuestionsAnswers::className(), ['option_id' => 'option_id']);}公共函数 getQuestion(){返回 $this->hasOne(SurveysQuestions::className(), ['question_id' => 'question_id']);}}

表单.php

<div class="surveys-questions-form"><?php $form = ActiveForm::begin();?><?phpif(isset($_GET['option_id']) 和 $_GET['option_id'] > 0)$id= $_GET['option_id'];别的$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 class="form-group"><?phpecho Html::a('添加更多', 'javascript:void(0);', ['id' =>'调查问题-新按钮','类' =>'拉右 btn btn-primary btn-xs'])?>

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

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

<?php$script = <<<JS$(document).ready(function(){$('#surveys-questions-new-button').on('click', function () {$("#add_more_field").clone().appendTo("#question_wrapper");});});JS;$this->registerJs($script);?>

也许我的代码中还有其他不正确的地方,请告诉我我真的需要帮助.

解决方案

我对改进和返工您的代码有几点意见:

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

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

    <input type="text" name="option[{{OPTION_ID}}][label]"/><input type="hidden" name="option[{{OPTION_ID}}][is_new_option]"/>

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

  3. 当您恢复现有选项时,请使用它们的 ID 将它们编入索引.

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

    //...foreach ($modelForm->options as $optionId => $optionData) {//准备数据$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');//创建或查找选项模型$modelOption = $isNewModel?新问题选项(): QuestionsOptions::findOne($optionId);如果(!$modelOption){throw new \yii\web\NotFoundHttpException('Cannot be found option record with the id = ' . $optionId);}//填充并保存模型$modelOption->label = $optionLabel;$modelOption->question_id = $optionQuestion;//外键如果 (!$modelOption->save()) {throw new \yii\base\Exception('不能保存新的选项记录.');}}

  5. 如有必要,您可以从数据库选项中删除已在表单上删除的内容.

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.

解决方案

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.

这篇关于如何在yii2中更新动态字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
其他开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆