我想制作自定义验证功能,如内置验证required
。我这里有示例代码:
型号:
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则抛出错误。这个验证应该由ajax处理,就像以防万一一样如果您尝试提交空字段,则为required
规则。
答案 0 :(得分:1)
虽然您可以在您的方案中使用Conditional Validators
when
和 whenClient
,但我建议您使用更复杂的方式这是为了定义自定义验证器,因为根据文档
要创建支持客户端验证的验证器,您应该这样做 实施
yii\validators\Validator::clientValidateAttribute()
返回一段执行该代码的JavaScript代码的方法 在客户端进行验证。在JavaScript代码中,您可以使用 以下预定义变量:
attribute:
要验证的属性的名称。
value:
正在验证的值。
messages:
用于保存属性验证错误消息的数组。
deferred:
可以推送延迟对象的数组(在下一小节中进行了解释)。
所以你需要做的就是创建一个验证器,并根据你想要的字段将它添加到你的规则中。
您需要小心复制以下代码 IF 您没有提供实际的型号名称并相应地更新字段名称。
1)首先要做的是将ActiveForm
小部件更新为以下内容
$form = ActiveForm::begin([
'id' => 'my-form',
'enableClientValidation' => true,
'validateOnSubmit' => true,
]);
2)将您的模型rules()
功能更改为以下
public function rules()
{
return [
[['age'], 'required'],
[['age'], \app\components\AgeValidator::className(), 'skipOnEmpty' => false, 'skipOnError' => false],
];
}
3)从模型中删除自定义验证函数my_validation()
我希望您检查其中的年龄限制18+
我们会将该逻辑移到验证器中
现在在AgeValidator.php
目录中创建一个文件components
,如果你使用basic-app
在项目的根目录中添加文件夹components
,如果它不存在创建一个新的,并在里面复制以下代码。
但是
我假设上面提供的模型名称,如果不是实际名称,则必须在javascript
函数中的clientValidateAttribute
语句中更新字段名称,如下所示验证器,因为id
中字段的ActiveForm
属性是以#modelname-fieldname
(所有小写)格式生成的,所以根据上面给出的模型,它将是#testform-age
相应地更新它,否则验证将无法正常工作。如果您计划将其保存在其他位置,请在下面的验证器和模型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;
}
}