0

我想制作自定义验证功能,如内置验证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 你尝试提交空的规则一样场地。

4

1 回答 1

1

尽管您也可以在您的场景中使用and ,但我建议使用更复杂的方法来定义自定义验证器,因为根据文档Conditional Validators whenwhenClient

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

attribute:正在验证的属性的名称。

value:正在验证的值。

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

deferred:可以将延迟对象推入的数组(在下一小节中解释)。

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

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

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语句中的字段名称,因为字段的属性是在一个格式如(所有小案例),因此根据上面给定的模型,它将相应地更新它,否则验证将不起作用。如果您打算将其保存在其他地方,请务必在下面的验证器和模型中更新命名空间。clientValidateAttributeidActiveForm#modelname-fieldname#testform-agerules()

<?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;
    }

}
于 2018-02-05T18:22:52.993 回答