Yii2: how to use custom validation function for activeform?

前端 未结 12 1148
独厮守ぢ
独厮守ぢ 2020-12-25 14:18

In my form\'s model, I have a custom validation function for a field defined in this way

class SignupForm extends Model
{
    public function rules()
    {
          


        
相关标签:
12条回答
  • 2020-12-25 14:42

    You need to trigger $model->validate() somewhere if you are extending from class Model.

    0 讨论(0)
  • 2020-12-25 14:43

    Your syntax on rules should be something like this man,

    [['birth_date'], 'checkDateFormat']
    

    not this

    ['birth_date', 'checkDateFormat']
    

    So in your case, it should look like below

    ...
    class SignupForm extends Model
    {
        public function rules()
        {
            // Notice the different with your previous code here
            return [
                [['birth_date'], 'checkDateFormat'], 
    
                // other rules
            ];
        }
    
        public function checkDateFormat($attribute, $params)
        {
            // no real check at the moment to be sure that the error is triggered
            $this->addError($attribute, Yii::t('user', 'You entered an invalid date format.'));
        }
    }
    
    0 讨论(0)
  • 2020-12-25 14:45

    I had common problem.

    In your validation function:

    public function checkDateFormat($attribute, $params)
        {
            // no real check at the moment to be sure that the error is triggered
            $this->addError($attribute, Yii::t('user', 'You entered an invalid date format.'));
        }
    

    $params doesn`t get any value at all. It actually always equals to Null. You have to check for your attribute value in function:

    public function checkDateFormat($attribute, $params)
    {
        if($this->birth_date == False)
        {
            $this->addError($attribute, Yii::t('user', 'You entered an invalid date format.'));
        }
    }
    

    that`s how it worked for me.

    0 讨论(0)
  • 2020-12-25 14:46

    You need to render the model from controller. Without initializing the model in view. And in the controller you need to call the validate function

    0 讨论(0)
  • 2020-12-25 14:48

    If you don't use scenarios for your model, you must mark your atribute as 'safe':

        ['birth_date','safe'],
        ['birth_date', 'checkDateFormat'],
    

    And, on the other hand, you can use this for date validation:

        ['birth_date','safe'],
        [['birth_date'],'date', 'format'=>'php:Y-m-d'],
    

    You can change format as you want.

    0 讨论(0)
  • 2020-12-25 14:52

    Although it's an old post i thought I should answer.

    You should create a Custom Validator Class and to create a validator that supports client-side validation, you should implement the yii\validators\Validator::clientValidateAttribute() method which returns a piece of JavaScript code that performs the validation on the client-side. Within the JavaScript code.

    You may use the following predefined variables:

    attribute: the name of the attribute being validated.

    value: the value being validated.

    messages: an array used to hold the validation error messages for the attribute.

    deferred: an array which deferred objects can be pushed into (explained in the next subsection).

    SO that means you can use messages array to push your messages to the client end on runtime within the javascript code block in this method.

    I will create a class that includes dummy checks that could be replaced the way you want them to. and change the namespace according to your yii2 advanced or basic.

    Custom Client-side Validator

    namespace common\components;
    use yii\validators\Validator;
    
    class DateFormatValidator extends Validator{
    public function init() {
            parent::init ();
            $this->message = 'You entered an invalid date format.';
        }
    
        public function validateAttribute( $model , $attribute ) {
    
            if ( /*SOME CONDITION TO CHECK*/) {
                $model->addError ( $attribute , $this->message );
            }
        }
    
        public function clientValidateAttribute( $model , $attribute , $view ) {
    
            $message = json_encode ( $this->message , JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
            return <<<JS
    if ($("#DATE-1").val()=="" || $("#DATE-2").val() =="") {
        messages.push($message);
    }
    JS;
        }
    }
    

    and then inside your model SigupForm add the rule

    ['birth_date', 'common\components\DateFormatValidator'],
    

    Deferred Validation

    You can even add ajax calls inside the clientValidateAttribute function and on the base of the result of that ajax call you can push message to the client end but you can use the deferred object provided by yii that is an array of Deferred objects and you push your calls inside that array or explicitly create the Deferred Object and call its resolve() method.

    Default Yii's deferred Object

    public function clientValidateAttribute($model, $attribute, $view)
    {
        return <<<JS
            deferred.push($.get("/check", {value: value}).done(function(data) {
                if ('' !== data) {
                    messages.push(data);
                }
            }));
    JS;
    }
    

    More about Deferred Validation

    0 讨论(0)
提交回复
热议问题