Lal
Lal

Reputation: 1628

Yii CForm, Nested Forms Ajax Validation

I have created the following nested forms array;

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'
        ),
    )
);

i have view page like this

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

my actionCreate is like this

$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 validation method is

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

so my question is how can i perform ajax validation on $form['contact'] and $form['lead'] elements individually?

Upvotes: 4

Views: 718

Answers (3)

Lalitesh Upadhyaya
Lalitesh Upadhyaya

Reputation: 311

Nested Forms are invalid. You can use scenarios to validate the form at different instances.

Example:

`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);`

Upvotes: 0

Denis Volkov
Denis Volkov

Reputation: 59

You should make your own validation

in actionCreate and actionUpdate of your controller you must add (i have main model "Invoice" and secondary "InvoiceDetails", and there could be more than 1 form for InvoiceDetails). But of course forms cannot be nested!

     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', ...));


            }

Upvotes: 0

TUNER88
TUNER88

Reputation: 923

You can have several forms in a page but they should not be nested. Nested forms are invalid.

Upvotes: 1

Related Questions