在Yii2中将自定义验证器与ActiveForm一起使用 [英] Using custom validators with ActiveForm in Yii2
问题描述
我想创建自定义验证功能,例如内置验证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屋!