【问题标题】:Using custom validators with ActiveForm in Yii2在 Yii2 中使用带有 ActiveForm 的自定义验证器
【发布时间】:2018-07-15 15:15:18
【问题描述】:

我想制作自定义验证功能,如内置验证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 处理,就像在 @ 的情况下一样987654326@ 规则如果您尝试提交空字段。

【问题讨论】:

  • 为你添加了一个答案,看看是否有帮助
  • 嘿,答案对你有用吗?
  • 我还没有时间尝试
  • 一定要慢慢来,没问题

标签: php jquery validation yii2 yii-validation


【解决方案1】:

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

要创建支持客户端验证的验证器,您应该 实施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+ 我们将把该逻辑移到验证器中。

现在在components目录下创建一个文件AgeValidator.php,如果你使用basic-app,在项目的根目录下添加文件夹components如果它不存在创建一个新的,然后复制下面的代码。

但是

我假设了您在上面提供的模型的名称,因此如果它不是实际名称,您必须更新您在下面的验证器中看到的clientValidateAttribute 函数中的javascript 语句中的字段名称,因为ActiveForm 中的字段的id 属性以#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;
    }

}

【讨论】:

  • 我的项目中没有这个 common/components 目录。我应该创作吗?
  • 如果您使用的是高级应用程序,您是使用高级应用程序还是基本应用程序,然后在组件目录中添加一个新文件夹
  • 我使用基本应用程序
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多