Search code examples
phpvalidationyii2yii2-advanced-appyii2-basic-app

yii2 conditional validation on server side


I have one form that form have below fields

i)Book ii)Amount

Controller action:

public function actionBook()
{   
    $model = new Book();
    if ($model->load(Yii::$app->request->post()) && $model->validate()){ 
        print_r($model);exit;
        return $this->redirect('/Book');
    }
    $model->getBook();
    return $this->render('BookForm', ['model' => $model]);
}

Whenever this page will load i will call one model function by default, the function is getBook()

Model:

public book;
public amount;
public showAmountField;

public function rules()
{   
 return [
  [['book'], 'required'],
  ['amount', 'required', 'when' => function($model) {
        return $model->showAmountField == true;
    }],
 ];
}

public function getBook()
{
 if(some condition here){
  $this->showAmountField = true;
 }
}

so whenever the showAmountField is true at the time the amount field is required, otherwise it will not required, here all are working fine and the client side validation also working fine, but when i change amount field id using console(f12) at the time the server side validation not working and form is simply submit with the amount field is empty, so what is wrong here. Please explain anyone.

UPDATE

View

<?php
 use yii\helpers\Html;
 use yii\bootstrap\ActiveForm;
 $this->params['breadcrumb'] = $model->breadCrumbs;
?>

<?php $form = ActiveForm::begin([
  'id' => 'book-form',  
  'options' => ['class' => 'form-horizontal'],
  ]); 
 ?>
<?= $form->field($model, 'book')->textInput()->label("Book"); ?>
<?php if($model->showAmountField): ?>      
  <?= $form->field($model, 'amount')->textInput()->label("Amount"); ?>
<?php endif; ?>  
<?= $form->errorSummary($model, ['header' => '']); ?>
<?php ActiveForm::end(); ?>

Solution

  • $model = new Book();
    if ($model->load(Yii::$app->request->post()) && $model->validate()){ 
        print_r($model);exit;
        return $this->redirect('/Book');
    }
    $model->getBook();
    

    here you are initialising the $model->getBook(); after the if block so the model gets overridden in post request with new instance and hence server side validations fails for when condition.

        $model = new Book();
        $model->getBook();
        if ($model->load(Yii::$app->request->post()) && $model->validate()){ 
            print_r($model);exit;
            return $this->redirect('/Book');
        }
    

    it should be before post load