我有一个Yii表单,它从另一个模型调用渲染部分(团队has_many team_members)。我想通过ajax调用部分视图来添加team / _form中的成员。所有工作(调用,显示,保存)除了ajax验证(服务器和客户端)。如果我提交表格,会员的模型没有验证,即使在客户端,它也没有验证必填字段。
有任何线索吗?
// _形式
<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'team-form',
'enableAjaxValidation'=>true,
'enableClientValidation'=>true,
'clientOptions'=>array(
'validateOnSubmit'=>true,
'validateOnChange'=>true
),
'htmlOptions' => array('enctype' => 'multipart/form-data'),
)); ?>
//控制器
public function actionMember($index)
{
$model = new TeamMember();
$this->renderPartial('_member',array(
'model'=> $model, 'index'=> $index
)
,false,true
);
}
public function actionCreate()
{
$model=new Team;
$members = array();
if(isset($_POST['Team']))
{
$model->attributes=$_POST['Team'];
if(!empty($_POST['TeamMember'])){
foreach($_POST['TeamMember'] as $team_member)
{
$mem = new TeamMember();
$mem->setAttribute($team_member);
if($mem->validate(array('name'))) $members[]=$mem;
}
}
$this->redirect(array('team/create','id'=>$model->id,'#'=>'submit-message'));
}
$members[]=new TeamMember;
$this->performAjaxMemberValidation($members);
$this->render('create',array(
'model'=>$model,'members'=>$members
));
}
// _构件
<div class="row-member<?php echo $index; ?>">
<h3>Member <?php echo $index+1; ?></h3>
<div class="row">
<?php echo CHtml::activeLabel($model, "[$index]name",array('class'=>'member')); ?>
<?php echo CHtml::activeTextField($model, "[$index]name",array('class'=>'member')); ?>
<?php echo CHtml::error($model, "[$index]name");?>
</div>
</div>
ProcessOutput
设置为true。没有骰子。
将renderPartial()
切换为render()
。没有骰子。
答案 0 :(得分:6)
如果你看一下CActiveForm::run:
$cs->registerCoreScript('yiiactiveform');
//...
$cs->registerScript(__CLASS__.'#'.$id,"jQuery('#$id').yiiactiveform($options);");
然后您将了解您的验证将无效,因为您渲染部分而不是整个页面。这些脚本显示在页面底部。所以你应该通过执行这些脚本来解决这个问题。
渲染部分后,尝试获取应存储在scipts
数组中的activeform脚本:
$this->renderPartial('_member',array('model'=> $model, 'index'=> $index));
$script = Yii::app()->clientScript->scripts[CClientScript::POS_READY]['CActiveForm#team-form'];
之后,将其与渲染的html一起发送到页面:
echo "<script type='text/javascript'>$script</script>"
另外请记住,在您将在页面上附加收到的html之前,如果您还没有(通过渲染另一个表单,或jquery.yiiactiveform.js
),则应该包含registerCoreScript('yiiactiveform')
来调用ajax请求。否则会引发javascript错误。
希望这会有所帮助。
修改强>
对不起我不明白你是表格的一部分,而不是整体。但是您的验证不会完全适用于同一个问题。因为没有为该字段创建jQuery('#$id').yiiactiveform($options);
脚本。
答案 1 :(得分:1)
实际问题是ActiveForm将其属性保存在“settings”数据属性中进行验证。我看到你已经在使用索引了,所以你需要将新元素添加到这个设置对象,以便验证工作。在ajax响应之后,这是必须做的:
//Get the settings object from the form
var settings = $("#form").data('settings');
//Get all the newly inserted elements via jquery
$("[name^='YourModel']", data).each(function(k, v) {
//base attribute skeleton
var base = {
model : 'YourModel',
enableAjaxValidation : true,
errorCssClass : 'error',
status : 1,
hideErrorMessage : false,
};
var newRow = $.extend({
id : $(v).attr('id'),
inputID : $(v).attr('id'),
errorID : $(v).attr('id') + '_em_',
name : $(v).attr('name'),
}, base);
//push it to the settings.attribute object
settings.attributes.push(newRow);
});
//update the form
$("#form").data('settings', settings);
```
这样,ActiveForm将知道新字段并将验证它们。
答案 2 :(得分:0)
好吧,在processOutput
中将renderPartial
设置为true(为了使客户端验证适用于新添加的字段)在这种情况下无效,因为它只适用于CActiveForm
表单并且您的_member
视图中没有任何表单(仅限输入字段)。
处理此类问题的简单方法可能是使用仅ajax验证,并在控制器中使用CActiveForm::validateTabular()
来验证您的团队成员