Yii CForm,嵌套表单Ajax验证

时间:2013-03-01 06:28:08

标签: yii nested-forms

我创建了以下嵌套表单数组;

return array(

    'elements' => array(
        'contact' => array(
            'type' => 'form',
            'elements' => array(
                'first_name' => array(
                    'type' => 'text',
                ),
                'last_name' => array(
                    'type' => 'text',
                )
            ),
        ),
        'lead' => array(
            'type' => 'form',
            'elements' => array(
                'primary_skills' => array(
                    'type' => 'textarea',
                ),
            ),
        ),
    ),

    'buttons' => array(
        'save-lead' => array(
            'type' => 'submit',
            'label' => 'Create',
            'class' => 'btn'
        ),
    )
);

我有这样的视图页面

echo $form->renderBegin();
echo $form['lead'];
echo $form['contact'];
echo $form->buttons['save-lead']; 
echo $form->renderEnd();

我的actionCreate就像这样

$form = new CForm('application.views.leads.register');
$form['lead']->model = new Lead;
$form['contact']->model = new Contact;

// how can i perform ajax validation only for $form['contact']
$this->performAjaxValidation($model); 

//if contact form save btn is clicked
if ($form->submitted('save-lead') && $form['contact']->validate() &&

    $form['lead']->validate()
) {

    $contact = $form['contact']->model;
    $lead = $form['lead']->model;
    if ($contact->save()) {
        $lead->contact_id = $contact->id;
        if ($lead->save()) {
            $this->redirect(array('leads/view', 'id' => $lead->id));
        }
    }
}

ajax验证方法是

protected function performAjaxValidation($model)
{
    if (isset($_POST['ajax']) && $_POST['ajax'] === 'contact') {
        echo CActiveForm::validate($model);
        Yii::app()->end();
    }
}

所以我的问题是如何在$ form ['contact']和$ form ['lead']元素上单独执行ajax验证?

3 个答案:

答案 0 :(得分:1)

您可以在页面中包含多个表单,但不应嵌套它们。 嵌套表单无效。

答案 1 :(得分:0)

您应该进行自己的验证

在你必须添加的控制器的actionCreate和actionUpdate中(我有主模型“Invoice”和辅助“InvoiceDetails”,并且InvoiceDetails可以有多个表单)。但当然形式不能嵌套!

     public function actionCreate()
    { 
     ...
     $PostVar = 'Invoices';
     if (Yii::app()->request->isAjaxRequest)
                { //    if ajax
                $this->performAjaxValidation($model, strtolower($PostVar) . '-form');
                $PostVar = ucfirst($PostVar);

                if (isset($_POST[$PostVar]))
                {
                    $model->attributes = $_POST[$PostVar];
                    $dynamicModel = new InvoiceDetails(); //your model
                    $valid = self::validate($model, $dynamicModel);


                    if (!isset($_POST['ajax']))
                    {

                        if (isset($_POST['InvoiceDetails']))
                        {
                            $allDetails = array();
                            $allDynamicModels = $_POST['InvoiceDetails'];

                            //your own customization
                            foreach ($allDynamicModels as $key => $value)
                            {
                                $InvDet = InvoiceDetails::model()->findByPk($_POST['InvoiceDetails'][$key]['id']);
                                if (!isset($InvDet))
                                {
                                    $InvDet = new InvoiceDetails();
                                }
                                $InvDet->attributes = $_POST['InvoiceDetails'][$key];
                                $InvDet->save();
                                $allDetails[] = $InvDet;
                            }
                        }

                        $model->invoicedetails = $allDetails;

                        if ($model->save())
                        {
                            echo CJSON::encode(array('status' => 'success'));
                            Yii::app()->end();
                        }
                        else
                        {
                            echo CJSON::encode(array('status' => 'error saving'));
                            Yii::app()->end();
                        }
                    }
                    // Here we say if valid
                    if (!isset($valid))
                    {
                        echo CJSON::encode(array('status' => 'success'));
                    }
                    else
                    {
                        echo $valid;
                    }

                    Yii::app()->end();


                }
                else
                {

                    $this->renderPartial('_form', ...);

                }
            }
            else
            {
                // not AJAX request

                $this->render('_form', ...));


            }

答案 2 :(得分:0)

嵌套表单无效。您可以使用scenarios在不同的实例中验证表单。

示例:

`if ($form->submitted('save-lead'){
    $form->scenario = 'save-lead';
    if($form->validate()) {
    $form->save();
    }
} else {
    $form->scenario = 'contact';
    if($form->validate()){
      $form->save();
    }
}
$this->render('_form', array('form'=>$form);`