5

我有一个 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设置为真。没有骰子。切换renderPartial()render()。没有骰子。

4

3 回答 3

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);没有为该字段创建脚本。

于 2013-04-24T00:23:40.657 回答
1

实际问题是 ActiveForm 将其属性保存在“设置”数据属性中进行验证。我看到您已经在使用索引,因此您需要将新元素添加到此设置对象以使验证正常工作。在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 将知道新字段并验证它们。

于 2014-03-25T08:26:15.823 回答
0

好吧,在这种情况下,设置processOutput为 true renderPartial(为了使客户端验证适用于新添加的字段)将无济于事,因为它仅适用于CActiveForm表单并且您的视图中没有任何表单_member(仅输入字段)。

处理此类问题的一种简单方法是仅使用 ajax 验证,并CActiveForm::validateTabular()在您的控制器中使用来验证您的团队成员。

于 2013-04-24T08:35:31.643 回答