Renderpartial上的Yii客户端验证不起作用

时间:2013-04-23 16:08:39

标签: ajax yii renderpartial

我有一个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()。没有骰子。

3 个答案:

答案 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()来验证您的团队成员