使用ajax在yii2中向表单添加更多字段

时间:2015-04-12 06:24:44

标签: php ajax yii2

我有Yii2 form

<?php $form = ActiveForm::begin(['id' => 'que']); ?>
    <?php echo $form->field($model, 'type')
            ->dropDownList($questionTypes, [
                'class' => 'form-control ng-pristine ng-valid ng-touched',
                'prompt' => 'Select question type',
                'ng-model' => 'que.type',
                'ng-change' => 'addAnswerOptions(que);',
        ]);
    ?>
<?php ActiveForm::end(); ?>

根据选定的下拉值,我必须在同一模型的相同形式中添加更多字段。将添加哪些字段完全取决于下拉值。

我该怎么做?

1 个答案:

答案 0 :(得分:5)

根据您提供的信息,我建议您这样做。

1)动态 - 没有AJAX

使用您需要的所有字段构建表单,只包含每个&#34;场景&#34;在单独的div中,如下所示:

<?php $form = ActiveForm::begin(['id' => 'que']); ?>
    <?php echo $form->field($model, 'type')
            ->dropDownList($questionTypes, [
                'class' => 'form-control ng-pristine ng-valid ng-touched',
                'prompt' => 'Select question type',
                'ng-model' => 'que.type',
                'ng-change' => 'addAnswerOptions(que);',
        ]);
    ?>
    <div class="form-option" data-type="class" style="display:none;">
        <?php
            // ... fields here for case type == class
        ?>
    </div>
    <div class="form-option" data-type="prompt" style="display:none;">
        <?php
            // ... fields here for case type == prompt
        ?>
    </div>
    <div class="form-option" data-type="ng-model" style="display:none;">
        <?php
            // ... fields here for case type == ng-model
        ?>
    </div>
    <div class="form-option" data-type="ng-change" style="display:none;">
        <?php
            // ... fields here for case type == ng-change
        ?>
    </div>
<?php ActiveForm::end(); ?>

然后,您将需要注册Javascript代码以显示正确的块,具体取决于所选的下拉选项。 Bellow是使用JQuery的一个例子:

$(document).ready(function(){
    $('select.form-control').change(function(){
        $('.form-option').hide(); // hide all options if an option is showing
        var index = $('select.form-control').index();
        $('div[data-type="'+index+'"]').show(); //show the correct fields
    });
});

如果您要采用这种方式,我建议您使用AJAX validation表单。这样可以避免在页面重新加载时遇到麻烦。

提交表单后,您必须处理控制器中的每个案例。您可以使用一组简单的if()语句来检查下拉值。或者,您可以根据下拉值设置模型validation scenario

这样做的好处是它会更快,您将能够利用ActiveForm。缺点是您需要知道要为每个选项显示哪些字段,并且当您不知道多少{{1}时,它不允许您累积n个字段是的。

2)使用Ajax

如果您想使用ajax调用加载额外的表单字段,则必须制作n组合,该组合将返回字段,具体取决于您在controller/action中传递的类型

此操作将生成您要显示的字段的html。这是一个例子:

GET

请注意,您还可以将用户ID传递给此方法,这样您就可以生成模型并使用public function actionAjaxFields($type) { $html = ''; if($type == "class") { $html .= Html::textInput('Field1'); } elseif($type == "prompt") { $html .= Html::textInput('Field2'); } else { // etc... } return $html; } ,但是您将无法利用Html::activeTextInput()功能。

完成此操作后,您应该将函数绑定到下拉列表的更改事件,并使用以下内容:

ActiveForm

不幸的是我对angularjs了解不多,所以这是我在javascript方面提供帮助的程度。我确定google / stackoverflow上有关于绑定事件和将数据附加到angularjs中的DOM的信息足以让你运行。

如果我能在Yii2方面获得任何额外帮助,请告诉我。