我有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(); ?>
根据选定的下拉值,我必须在同一模型的相同形式中添加更多字段。将添加哪些字段完全取决于下拉值。
我该怎么做?
答案 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方面获得任何额外帮助,请告诉我。