在Yii2中将自定义验证器与ActiveForm一起使用 [英] Using custom validators with ActiveForm in Yii2

查看:325
本文介绍了在Yii2中将自定义验证器与ActiveForm一起使用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想创建自定义验证功能,例如内置验证required.我在这里有示例代码:

I want to make custom validation function like built-in validation required. I have example code here:

型号:

use yii\base\Model;

class TestForm extends Model
{
    public $age;
    public function rules(){
        return [
            ['age', 'my_validation']
        ];
    }
    public function my_validation(){
        //some code here
    }
}

查看:

<?php

use yii\helpers\Html;
use yii\widgets\ActiveForm;


$this->title = 'test';
?>
<div style="margin-top: 30px;">

    <?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(); ?>

</div>

控制器:

use app\models\form\TestForm;
use yii\web\Controller;

class TestController extends Controller
{
    public function actionIndex(){
        $model = new TestForm();

        if($model->load(\Yii::$app->request->post())){
            return $this->render('test', array(
                'model'=>$model,
                'message'=>'success'
            ));
        }
        return $this->render('test', array('model'=>$model));
    }
}

在此示例中,我有一个年龄字段,该my_validation函数应在年龄小于18岁之前检查年龄是否大于18岁,如果年龄小于18岁,则应提交错误并引发错误. c0>规则,如果您尝试提交空白字段.

in this example I have a field for age and this my_validation function should check if age is over 18 before submit and throw error if age is under 18. This validation should be processed by ajax like it is in case of required rule if you try to submit empty field.

推荐答案

尽管您可以使用在您的情况下也是 Conditional Validators when whenClient ,但我建议使用更复杂的方法来定义自定义验证器,因为根据文档

Although you can use Conditional Validators when and whenClient too in your scenario but I would recommend using a more sophisticated way which is to define a custom validator because according to the docs

要创建支持客户端验证的验证器,您应该 实施yii\validators\Validator::clientValidateAttribute() 方法,该方法返回一段JavaScript代码,该代码执行 在客户端进行验证.在JavaScript代码中,您可以使用 以下预定义变量:

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: 待验证属性的名称.

attribute: the name of the attribute being validated.

value: 待验证的值.

value: the value being validated.

messages: 一个用于保存属性验证错误消息的数组.

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

deferred: 可以将延迟对象推入的数组(在下一节中说明).

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

因此,您需要做的是创建一个验证器,并将其添加到您想要的字段的规则中.

So what you need to do is create a validator and add it to your rules against the field you want.

您需要小心复制以下代码 IF ,您没有提供实际的模型名称并相应地更新了字段名称.

You need to be careful copying the following code IF you haven't provided the actual model name and update the field names accordingly.

1)首先要做的是将ActiveForm小部件更新为以下内容

1) First thing to do is to update the ActiveForm widget to the following

$form = ActiveForm::begin([
    'id' => 'my-form',
    'enableClientValidation' => true,
    'validateOnSubmit' => true,
]);

2)将您的模型rules()功能更改为以下

2) Change your model rules() function to the following

public function rules()
    {
        return [
            [['age'], 'required'],
            [['age'], \app\components\AgeValidator::className(), 'skipOnEmpty' => false, 'skipOnError' => false],
        ];
    }

3)从模型中删除自定义验证功能my_validation(),我希望您正在检查其中的年龄限制为18+,我们将把该逻辑移到验证器中.

3) Remove the custom validation function my_validation() from your model i hope you are checking the age limit in it to be 18+ we will move that logic into the validator.

现在在components目录中创建文件AgeValidator.php,如果使用的是basic-app,则在项目的根目录中添加文件夹components,如果该目录不存在,则创建一个新文件,并复制该文件.里面的代码.

Now create a file AgeValidator.php inside components directory, if you are using the basic-app add the folder components inside the root directory of the project if it does not exist create a new one, and copy the following code inside.

但是

我已经假设了您上面提供的Model的名称,因此,如果不是实际名称,则必须更新验证器下面在clientValidateAttribute函数中的javascript语句内的字段名称,因为ActiveForm中字段的id属性以类似#modelname-fieldname的格式生成(全部为小写),因此根据上述给定模型,#testform-age会相应地对其进行更新,否则验证将无法进行.如果打算将其保存在其他位置,请在下面的验证器和模型rules()中更新名称空间.

I have assumed the name of the Model that is provided by you above so if it not the actual name you have to update the field name inside the javascript statements within clientValidateAttribute function you see below in the validator because the id attribute of the fields in ActiveForm is generated in a format like #modelname-fieldname (all small case) so according to above given model, it will be #testform-age do update it accordingly otherwise the validation wont work. And do update the namespace in the validator below and in the model rules() if you plan to save it somewhere else.

<?php

namespace app\components;

use yii\validators\Validator;

class AgeValidator extends Validator
{

    public function init()
    {
        parent::init();
        $this->message = 'You need to be above the required age 18+';
    }

    public function validateAttribute($model, $attribute)
    {

        if ($model->$attribute < 18) {
            $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 (parseInt($("#testform-age").val())<18) {
    messages.push($message);
}
JS;
    }

}

这篇关于在Yii2中将自定义验证器与ActiveForm一起使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆