例如,我们在示例视图中有这个ActiveForm
实现:
<?php $form = ActiveForm::begin(); ?>
<?=$form->field($model, 'first_name')->textInput(['maxlength' => true]); ?>
<?=$form->field($model, 'last_name')->textInput(['maxlength' => true]); ?>
<div id="additional-form-fields"></div>
<a href="#" id="load-additional-form-fields">
Load more fields
</a>
<?php ActiveForm::end(); ?>
现在,我想在此表单中添加更多ActiveField
/ ActiveForm
个字段,并将它们放在带有Ajax的#additional-form-fields
元素中,我会做一个简单的jQuery
回调:
$('#load-additional-form-fields').click(function() {
$.get('/site/additional-fields', {}, function(data) {
$('#additional-form-fields').html( data );
});
});
additional-fields
内的操作SiteController
可能是:
public function actionAdditionalFields() {
$model = new User;
return $this->renderAjax('additional-fields', [
'model' => $model,
// I could pass a 'form' => new ActiveForm, here, but it's a big NO-NO!
]);
}
只有当我在此操作视图中不使用任何其他ActiveField
字段时,这才能完美运行:
<?=$form->field($model, 'biography')->textInput(['maxlength' => true]); ?>
<?=$form->field($model, 'country')->textInput(['maxlength' => true]); ?>
<?=$form->field($model, 'occupation')->textInput(['maxlength' => true]); ?>
当然,我必须在此视图中以某种方式传递或设置$form
,但在此视图中的任何位置都不能使用其他ActiveForm::begin()
/ ActiveForm::end()
,因为它会创建另一个<form>
标记,因此当我注入Ajax响应时,我最终会在<form>
内找到<form>
...
现在,我的问题如下:由于我想使用ActiveForm
,如何通过多个请求共享ActiveForm
的实例?
是可行的/可能的,如果是的话,请帮我理解如何?
到目前为止,我已经尝试将$form
放入会话中,但这肯定不起作用而不是一个选项。与此不同的是,我在将参数传递给renderAjax
时尝试过:
[
'model' => $model,
'form' => new ActiveForm,
]
在这种情况下,我得到以下内容:
<script src="...">
...你明白了)是否有共享$form
的实例?
答案 0 :(得分:1)
好的,我已经设法做到这一点,所以我将在这里发布解决方案,我将在Github上打开一个问题 - 在将来的版本中可能会有用。
yii2\widgets\ActiveForm.php
我在ActiveForm
类中添加了以下属性:
/**
* @var boolean whether to echo the form tag or not
*/
public $withFormTag = true;
我已将run()
方法改为此(检查// <-- added
):
public function run()
{
if (!empty($this->_fields)) {
throw new InvalidCallException('Each beginField() should have a matching endField() call.');
}
$content = ob_get_clean();
if($this->withFormTag) { // <-- added
echo Html::beginForm($this->action, $this->method, $this->options);
} // <-- added
echo $content;
if ($this->enableClientScript) {
$id = $this->options['id'];
$options = Json::htmlEncode($this->getClientOptions());
$attributes = Json::htmlEncode($this->attributes);
$view = $this->getView();
ActiveFormAsset::register($view);
$view->registerJs("jQuery('#$id').yiiActiveForm($attributes, $options);");
}
if($this->withFormTag) { // <-- added
echo Html::endForm();
} // <-- added
}
因此,如果我们实例化一个这样的表格:
$form = ActiveForm::begin([
'withFormTag' => false,
]);
它不会echo
<form>
标记,但会呈现所有ActiveField
项目,如果$this->enableClientScript = true;
,它将创建各自的JavaScript / jQuery验证程序。
在基类中应用上一个修复后,我需要在我的视图中执行以下操作:
<?php $form = ActiveForm::begin([
'withFormTag' => false,
'id' => 'w0',
]); ?>
我必须传递id
参数,因为ActiveForm类的每个下一个实例都会增加1
,我希望我的JavaScript / jQuery验证器应用于父表单,默认情况下从0
开始 - &gt; w0
。
这就是诀窍!
以下是Github问题:https://github.com/yiisoft/yii2/issues/12973