1

I have model form (SomeForm) and custom validation function in there:

use yii\base\Model; 
class SomeForm extends Model
{
      public $age;
      public function custom_validation($attribute, $params){
             if($this->age < 18){
                    $this->addError($attribute, 'Some error Text');
                    return true;
             }
             else{
                     return false;
             }
      }
      public function rules(){
             return [
                 ['age', 'custom_validation']
             ];
      }
}

I use this custom_validation in rules() function but form even submitting whatever value has age attribute.

Here is the form:

age.php

<?php $form = ActiveForm::begin(); ?>
    <?= $form->field($model, 'age')->label("Age") ?>
    <div class="form-group">
        <?= Html::submitButton('Submit', ['class' => 'btn btn-primary']) ?>
    </div>
    <?php ActiveForm::end(); ?>

and the controller:

use yii\web\Controller;

class SomeController extends Controller
{
     //this controller is just for rendering
     public function actionIndex(){
             return $this->render('age');
     }
     public function actionSubmit(){
             $model = new SomeForm();
             if($model->load(Yii::$app->request->post()){
                   //do something here
             }
     }
}
10
  • is this your complete model, please if you can add the view and controller/action code, and when you submit the form please can you add the dump of Yii::$app->request->post(); Commented Feb 4, 2018 at 13:50
  • added an answer for you see if that helps you out. Commented Feb 4, 2018 at 14:32
  • @MuhammadOmerAslam thank you for your attention! I added view and controller code in my question. Your answer have not helped me yet :/ Commented Feb 5, 2018 at 12:23
  • I'll try your edited code Commented Feb 5, 2018 at 12:25
  • the code you added does not follow what i said you are still not calling $model->validate() please read my answer again and compare the code with my controller/action code Commented Feb 5, 2018 at 12:25

1 Answer 1

4

You don't need to return anything just adding the error to the attribute is enough.

Since version 2.0.11 you can use yii\validators\InlineValidator::addError() for adding errors instead of using $this. That way the error message can be formatted using yii\i18n\I18N::format() right away.

Use {attribute} and {value} in the error message to refer to an attribute label (no need to get it manually) and attribute value accordingly:

What I suspect is the problem in your case is that you are missing the $formModel->validate() as in the model given above extends the yii\base\Model and not \yii\db\ActiveRecord and you must be saving some other ActiveRecord model and want to validate this FormModel before saving the ActiveRecord model, you have to call the $formModel->validate() to check if valid input is provided and trigger the model validation after loading the post array to the model.

And another thing to notice is by default, inline validators will not be applied if their associated attributes receive empty inputs or if they have already failed some validation rules. If you want to make sure a rule is always applied, you may configure the skipOnEmpty and/or skipOnError properties to be false in the rule declarations.

Your model should look like below you are missing the namespace in your model definition if that is not just intentional or due to sample code. just update you namespace according to the path where it is.

namespace frontend\models;

use yii\base\Model; 
class SomeForm extends Model
{
      public $age;
      const AGE_LIMIT=18;

      public function rules(){
             return [
                 ['age', 'custom_validation','skipOnEmpty' => false, 'skipOnError' => false]
             ];
      }

      public function custom_validation($attribute, $params,$validator){
          if($this->$attribute< self::AGE_LIMIT){
             $validator->addError($this, $attribute, 'The value "{value}" is not acceptable for {attribute}, should be greater than '.self::AGE_LIMIT.'.');
           }
      }
}

your controller/action should look like

public function actionTest()
    {
        //use appropriate namespace
        $formModel = new \frontend\models\SomeForm();
        $model= new \frontend\models\SomeActiveRecordModel();

        if ($formModel->load(Yii::$app->request->post()) && $model->load(Yii::$app->request->post())) {
            if ($formModel->validate()) {
             // your code after validation to save other ActiveRecord model
             if($model->save()){
              Yii::$app->session->setFlash('success','Record added succesfully.')
             }
            }
        }

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

The Input field age in the view file should use the $formMoedl object

echo $form->field($formModel, 'age')->textInput();
Sign up to request clarification or add additional context in comments.

6 Comments

I have one more question how can I validate with jquery? When I tried your solution it regularly submits data and page reloads. If you can answer shortly please write here and if not I'll add new question about jquery validation
that would be a separate topic i think you should add a post and leave a link here i will guide you through how to make it work with frontend ClientValidation of the form i hope you are talking about validating the input on the fly and showing the error message? like it does with any default yii2 form. @Godot
Yes I mean exactly this
no issue just add a question and leave a link here just make sure you provide all the code relevant to the topic like ActiveForm and Model and should be exact code rather than example code.
so will I ask new question about jquery validating?
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.