Destroyer.0211
Destroyer.0211

Reputation: 113

Yii2 model custom validate method / function does not work

I want to validate my fine_amount against 2 input date. But it does not return any error. Without validating this method it saved data. I also looked into

Yii2: how to use custom validation function for activeform? but for me no solution.

Below is my code

Controller method

    $model = $this->findModel($id);

    $model->payment_date=date('d-M-Y',strtotime($model->payment_date));
    $model->payment_expected_date=date('d-M-Y',strtotime($model->payment_expected_date));

    if ($model->load(Yii::$app->request->post())) {
        $model->payment_date=date('Ymd',strtotime($model->payment_date));
        $model->payment_expected_date=date('Ymd',strtotime($model->payment_expected_date));

        if($model->validate()){
            $model->save();
            return $this->redirect(['view', 'id' => $model->id]);
        }
        else{
            $model->payment_date=date('d-M-Y',strtotime($model->payment_date));
            $model->payment_expected_date=date('d-M-Y',strtotime($model->payment_expected_date));

            return $this->render('update', [
                'model' => $model,
            ]);
        }
    }

    return $this->render('update', [
        'model' => $model,
    ]);

My Rule

['fine_amount' , 'fine_required'] ,

Validation function

public function fine_required() {
    $this->payment_date = date ( 'Ymd' , strtotime ( $this->payment_date ) );
    $this->payment_expected_date = date ( 'Ymd' , strtotime ( $this->payment_expected_date ) );

    if ( $this->payment_date > $this->payment_expected_date ) {
        if ( $this->fine_amount <= 0 ) {
            $this->addError ( 'fine_amount' , 'Fine Amount Must be add.' );
        }
        return false;
    }
    return true;
}

Upvotes: 1

Views: 288

Answers (1)

Muhammad Omer Aslam
Muhammad Omer Aslam

Reputation: 23778

You need to use conditional validation for your case, use when and whenClient respectively see below add to your rules section and remove any other validations. This will handle frontend and backend both validations

[ 'fine_amount' , 'required' , 'when' => function($model) {
        if ( $model->payment_date > $model->payment_expected_date ) {
            if ( $model->fine_amount <= 0 ) {
                return true;
            }
        }
        return false;
    } , 'whenClient' => 'function (attribute, value) {

    var d1 = new Date($("#' . Html::getInputId($this, 'payment_date') . '").val());
    var d2 = new Date($("#' . Html::getInputId($this, 'payment_expected_date'). '").val());
    if(d1>d2){
        if(value<=0){
            return true;
        }
    }
    return false;
}' , 'message' => 'Fine Amount Must be add.' ] ,

EDIT

Replaced strtolower ( \yii\helpers\StringHelper::basename ( get_class ( $this ) ) ) with Html::getInputId as it is more suitable for this case.

Upvotes: 1

Related Questions