[英]Using custom validators with ActiveForm in Yii2
I want to make custom validation function like built-in validation required
. 我想进行自定义的验证功能如内置的验证
required
。 I have example code here: 我在这里有示例代码:
Model: 模型:
use yii\base\Model;
class TestForm extends Model
{
public $age;
public function rules(){
return [
['age', 'my_validation']
];
}
public function my_validation(){
//some code here
}
}
View: 视图:
<?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>
Controller: 控制器:
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));
}
}
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. 在此示例中,我有一个年龄字段,该
my_validation
函数应检查年龄是否超过18岁,如果年龄小于18岁,则将提交提交并引发错误。如果您尝试执行required
规则,则应由ajax处理该验证提交空字段。
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 尽管您也可以在场景中的
when
和whenClient
使用whenClient
Conditional Validators
when
但我还是建议您使用更复杂的方法来定义自定义验证器,因为根据文档
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.要创建支持客户端验证的验证器,您应该实现
yii\\validators\\Validator::clientValidateAttribute()
方法,该方法返回一段JavaScript代码来在客户端执行验证。 Within the JavaScript code, you may use the following predefined variables:在JavaScript代码中,您可以使用以下预定义的变量:
attribute:
the name of the attribute being validated.attribute:
要验证的属性的名称。
value:
the value being validated.value:
正在验证的值。
messages:
an array used to hold the validation error messages for the attribute.messages:
一个数组,用于保存属性的验证错误消息。
deferred:
an array which deferred objects can be pushed into (explained in the next subsection).deferred:
可以将延迟对象推入的数组(在下一节中说明)。
So what you need to do is create a validator and add it to your rules against the field you want. 因此,您需要做的是创建一个验证器,并将其添加到您想要的字段的规则中。
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) First thing to do is to update the ActiveForm
widget to the following 1)首先要做的是将
ActiveForm
小部件更新为以下内容
$form = ActiveForm::begin([
'id' => 'my-form',
'enableClientValidation' => true,
'validateOnSubmit' => true,
]);
2) Change your model rules()
function to the following 2)将您的模型
rules()
函数更改为以下内容
public function rules()
{
return [
[['age'], 'required'],
[['age'], \app\components\AgeValidator::className(), 'skipOnEmpty' => false, 'skipOnError' => false],
];
}
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. 3)从您的模型中删除自定义验证函数
my_validation()
,希望您正在检查其中的年龄限制为18+
我们将把该逻辑移到验证器中。
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. 现在,在
components
目录中创建一个文件AgeValidator.php
,如果您使用的是basic-app
,请在项目的根目录中添加文件夹components
如果不存在),然后创建一个新文件夹,并在其中复制以下代码。
BUT 但
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. 我已经假设了您上面提供的Model的名称,所以如果不是实际名称,则必须更新在验证器下面看到的
clientValidateAttribute
函数中的javascript
语句内的字段名称,因为ActiveForm
中的字段的id
属性是以#modelname-fieldname
(所有大小写)之类的格式生成的,因此根据上述给定的模型,将#testform-age
进行相应的更新,否则验证将无法进行。 And do update the namespace in the validator below and in the model rules()
if you plan to save it somewhere else. 如果打算将其保存在其他位置,请在下面的验证器和模型
rules()
更新名称空间。
<?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;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.