How to validate tabular data in yii?

2020-05-01 04:55发布

问题:

I have created a form which allows user to save tabular data. I have followed this tutorial . I have managed to add multiple instance for a Model and I am getting the data in the post and it is getting validate. The problem is with the error summary and the AJAX validation.

Below is my controller code, I have created an array for the second Model and passed it to the form.

$model = new UserAccountDetail;
$addresses = array();
array_push($addresses, new UserAddress);
array_push($addresses, new UserAddress);
$this->validateUserAccount($model,$addresses);
if(isset($_POST['UserAccountDetail']) && isset($_POST['UserAddress']))
{
    $model->attributes = $_POST['UserAccountDetail'];
    $model->validate();
    $addresses = array();
    for($i=0;$i<2;$i++)
    {
        if(isset($_POST['UserAddress'][$i]))
        {
            $address = new UserAddress;
            $address->attributes = $_POST['UserAddress'][$i];
            array_push($addresses, $address);
            $address->validate();
        }
    }
}
$this->render('accountinformation',array('model'=>$model,'addresses'=>$addresses));

Below is my ajax validation function:

protected function validateUserAccount($model,$addresses)
{
    if(isset($_POST['ajax']) && $_POST['ajax']==='user-account-detail-form')
    {
        echo CActiveForm::validate($model).CActiveForm::validateTabular($addresses);
        Yii::app()->end();
    }
}

When I run this code the Ajax validation does not work. The onclick validation does work but for the tabular data the messages are not shown in the error summary but the fields are highlighted in red.

I any thing else is required then please let me know. Thanks for your time. Cheers!!!!!

Update View File:

<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'user-account-detail-form',
'enableAjaxValidation'=>true,
 )); ?>

<?php echo $form->errorSummary($model,$address); ?>

<h2> Account Details </h2>

<div class="row">
    <?php echo $form->labelEx($model,'Title'); ?>
    <?php echo $form->dropDownList($model,'Title', $model->getAllTitles()); ?>
    <?php echo $form->error($model,'Title'); ?>
</div>



<div class="row">
    <?php echo $form->labelEx($model,'firstName'); ?>
    <?php echo $form->textField($model,'firstName',array('size'=>50,'maxlength'=>100)); ?>
    <?php echo $form->error($model,'firstName'); ?>
</div>

<div class="row">
    <?php echo $form->labelEx($model,'middleName'); ?>
    <?php echo $form->textField($model,'middleName',array('size'=>50,'maxlength'=>100)); ?>
    <?php echo $form->error($model,'middleName'); ?>
</div>

<div class="row">
    <?php echo $form->labelEx($model,'lastName'); ?>
    <?php echo $form->textField($model,'lastName',array('size'=>50,'maxlength'=>100)); ?>
    <?php echo $form->error($model,'lastName'); ?>
</div>

<div class="row">
    <?php echo $form->labelEx($model,'displayName'); ?>
    <?php echo $form->textField($model,'displayName',array('size'=>50,'maxlength'=>200)); ?>
    <?php echo $form->error($model,'displayName'); ?>
</div>

<div class="row">
    <?php echo $form->labelEx($model,'birthDate'); ?>
    <?php echo $form->textField($model,'birthDate',array('size'=>50,'maxlength'=>15)); ?>
    <?php echo $form->error($model,'birthDate'); ?>
</div>

<div class="row">
    <?php echo $form->labelEx($model,'lenderType'); ?>
    <?php echo $form->textField($model,'lenderType',array('size'=>50,'maxlength'=>15)); ?>
    <?php echo $form->error($model,'lenderType'); ?>
</div>

<div class="row">
    <?php echo $form->labelEx($model,'businessName'); ?>
    <?php echo $form->textField($model,'businessName',array('size'=>60,'maxlength'=>200)); ?>
    <?php echo $form->error($model,'businessName'); ?>
</div>

<div class="row">
    <?php echo $form->labelEx($model,'hearAboutUs'); ?>     
  <?php echo $form->dropDownList($model,'hearAboutUs', $model->getAllHearAbout()); ?>
    <?php echo $form->error($model,'hearAboutUs'); ?>
</div>

<div class="row">
    <?php echo $form->labelEx($model,'promotionalCode'); ?>
    <?php echo $form->textField($model,'promotionalCode',array('size'=>60,'maxlength'=>100)); ?>
    <?php echo $form->error($model,'promotionalCode'); ?>
</div>

<div class="row">
    <?php echo $form->labelEx($model,'mobileNumber'); ?>
    <?php echo $form->textField($model,'mobileNumber',array('size'=>50,'maxlength'=>15)); ?>
    <?php echo $form->error($model,'mobileNumber'); ?>
</div>

<div class="row">
    <?php echo $form->labelEx($model,'workLandline'); ?>
    <?php echo $form->textField($model,'workLandline',array('size'=>50,'maxlength'=>15)); ?>
    <?php echo $form->error($model,'workLandline'); ?>
</div>
    <?php echo $form->textField($model,'thirdAnswer',array('size'=>60,'maxlength'=>100)); ?>
    <?php echo $form->error($model,'thirdAnswer'); ?>
</div>
<h2>Address </h2>
<?php foreach ($addresses as $i=>$address) { ?>
    <div class="row">
        <?php echo $form->labelEx($address,"[$i]Flat"); ?>
        <?php echo $form->textField($address,"[$i]Flat",array('size'=>60,'maxlength'=>100)); ?>
        <?php echo $form->error($address,"[$i]Flat"); ?>
    </div>

    <div class="row">
        <?php echo $form->labelEx($address,"[$i]buildingName"); ?>
        <?php echo $form->textField($address,"[$i]buildingName",array('size'=>60,'maxlength'=>100)); ?>
        <?php echo $form->error($address,"[$i]buildingName"); ?>
    </div>

    <div class="row">
        <?php echo $form->labelEx($address,"[$i]buildingNumber"); ?>
        <?php echo $form->textField($address,"[$i]buildingNumber",array('size'=>60,'maxlength'=>100)); ?>
        <?php echo $form->error($address,"[$i]buildingNumber"); ?>
    </div>

    <div class="row">
        <?php echo $form->labelEx($address,"[$i]street"); ?>
        <?php echo $form->textField($address,"[$i]street",array('size'=>60,'maxlength'=>100)); ?>
        <?php echo $form->error($address,"[$i]street"); ?>
    </div>

    <div class="row">
        <?php echo $form->labelEx($address,"[$i]district"); ?>
        <?php echo $form->textField($address,"[$i]district",array('size'=>60,'maxlength'=>100)); ?>
        <?php echo $form->error($address,"[$i]district"); ?>
    </div>

    <div class="row">
        <?php echo $form->labelEx($address,"[$i]town"); ?>
        <?php echo $form->textField($address,"[$i]town",array('size'=>60,'maxlength'=>100)); ?>
        <?php echo $form->error($address,"[$i]town"); ?>
    </div>

    <div class="row">
        <?php echo $form->labelEx($address,"[$i]county"); ?>
        <?php echo $form->textField($address,"[$i]county",array('size'=>60,'maxlength'=>100)); ?>
        <?php echo $form->error($address,"[$i]county"); ?>
    </div>

    <div class="row">
        <?php echo $form->labelEx($address,"[$i]postCode"); ?>
        <?php echo $form->textField($address,"[$i]postCode",array('size'=>60,'maxlength'=>100)); ?>
        <?php echo $form->error($address,"[$i]postCode"); ?>
    </div>

    <div class="row">
        <?php echo $form->labelEx($address,"[$i]isCorresppondence"); ?>
        <?php echo $form->textField($address,"[$i]isCorresppondence",array('size'=>60,'maxlength'=>100)); ?>
        <?php echo $form->error($address,"[$i]isCorresppondence"); ?>
    </div>

<?php } ?>

<div class="row buttons">
    <?php echo CHtml::submitButton('Continue'); ?>
</div>

 <?php $this->endWidget(); ?>

Update : I have checked the response from the server and it is giving the correct response. Below is the screen shot:

Update :: I have managed to correct the on click validation issue by passing the array of models to the errorSummary() function like:

<?php 
$error = array();
array_push($error, $model);
foreach ($addresses as $address)
{
    array_push($error, $address);
}
echo $form->errorSummary($error); ?>

But the AJAX validation is still not working. Can any one help me with that.

回答1:

http://www.yiiframework.com/doc/api/1.1/CActiveForm

The AJAX-based validation has a few limitations. First, it does not work with file upload fields. Second, it should not be used to perform validations that may cause server-side state changes. Third, it is not designed to work with tabular data input for the moment.

So, you need to write custom error handler for tabular data

//view
$form = $this->beginWidget('CActiveForm', array(   
    'enableClientValidation' => true,
    'clientOptions' => array(
        'validateOnChange' => false,
        'validateOnType' => false,
        'validateOnSubmit' => true,
        'beforeValidate' => 'js:formBeforeValidate',
        'afterValidate' => 'js:formAfterValidate'
    ),
));
//some js
function formBeforeValidate (form) {    
    //clean errors
    return true;
}

function formAfterValidate(form, data, hasError) {    
    if (hasError === true) {
        //append errors to input
    }
    return !hasError;
}


回答2:

There is no inbuilt mechanism in Yii to ajax validation for tabular data. I implemented custom validation using jquery for this purpose. Below is the code that I used to create a custom ajax validation for tabular data.

Controller: It assigns the value passed to the model attribute and returns any error for the attribute.

public function actionValidateData($value,$name)
{
    $model = new BusinessPartner;
    $model->setAttribute($name, $value);
    $model->validate();
    echo CHtml::error($model,$name);
    Yii::app()->end();
}

Jquery function to make ajax call and show the messages. I have added class 'businessPartner' to all the fields of the model.

$(document).on('blur','.businessPartner',function(e){
    e.preventDefault();
    var id= $(this).attr('id');
    var name= $(this).attr('rel');
    $.ajax({
        url:"<?php echo Yii::app()->createUrl('user/validatedata'); ?>",
        type: "GET",
        data: 'value='+$.trim($(this).val())+'&name='+ name,
        success :function(data){
            if($.trim(data))
            {   
                if(!$('#'+id).hasClass('error'))
                {
                    $('#'+id).addClass('error');
                    $('#'+id).prev().addClass('error');
                    $('#'+id).after(data);
                }
            }
            else
            {
                if(!$('#'+id).parent().hasClass('success'))
                {                       
                    $('#'+id).removeClass('error');
                    $('#'+id).prev().removeClass('error')
                    $('#'+id).next().remove()
                    $('#'+id).parent().addClass('success');
                }
            }

        },
        error:function(){
        },
    });
});


标签: php yii