使用Ajax在yii2中的表单中添加更多字段 - php

我有一个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)动态-无AJAX

使用所需的所有字段来构建表单,只需将每个“方案”包含在单独的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代码以显示正确的块,具体取决于选择了哪个下拉选项。
以下是使用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的优势。缺点是您需要知道要为每个选项显示的字段,并且当您不知道n多少时,它不允许您累计n个字段。

2)使用Ajax

如果要使用ajax调用加载额外的表单字段,则必须进行controller/action组合,该组合将根据您在GET中传递的类型返回这些字段。

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

public function actionAjaxFields($type)
{
    $html = '';
    if($type == "class")
    {
        $html .= Html::textInput('Field1');
    }
    elseif($type == "prompt")
    {
        $html .= Html::textInput('Field2');
    }
    else
    {
        // etc...
    }
    return $html;
}

请注意,您还可以将用户ID传递给此方法,这将允许您生成模型并使用Html::activeTextInput(),但是您将无法利用ActiveForm功能。

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

var responsePromise = $http.get("controller/ajax-fields", {params: {type: <type-from-dropdown>}});

不幸的是,我对angularjs不太了解,所以这是我可以在javascript方面提供的帮助的程度。我敢肯定,在google / stackoverflow上,有关绑定事件以及将数据附加到angularjs中的DOM上的信息足以使您正常运行。

让我知道在Yii2方面是否可以提供任何其他帮助。

PHP:对数组排序 - php

请如何排序以下数组Array ( 'ben' => 1.0, 'ken' => 2.0, 'sam' => 1.5 ) 至Array ( 'ken' => 2.0, 'sam' => 1.5, 'ben' =&…

转义字符无法正常工作 - php

我试图在PHP中创建html内容,并且为onclick事件提供了一个名为uchat的div函数。该函数采用一个字符串的名称参数。如下所示:$name = "Php string"; $echostr .= "<div onClick='uchat(\'$name\')'> &l…

PHP strtotime困境 - php

有人可以解释为什么这在我的服务器上输出为true吗?date_default_timezone_set('Europe/Bucharest'); var_dump( strtotime('29.03.2015 03:00', time()) === strtotime('29.03.2015 04:00�…

PHP-全局变量的性能和内存问题 - php

假设情况:我在php中运行一个复杂的站点,并且我使用了很多全局变量。我可以将变量存储在现有的全局范围内,例如$_REQUEST['userInfo'],$_REQUEST['foo']和$_REQUEST['bar']等,然后将许多不同的内容放入请求范围内(这将是适当的用法,因为这些数据指的是要求自…

PHP PDO组按列名称查询结果 - php

以下PDO查询返回以下结果:$db = new PDO('....'); $sth = $db->prepare('SELECT ...'); 结果如下: name curso ABC stack CDE stack FGH stack IJK stack LMN overflow OPQ overflow RS…