Yii2:如何使用自定义验证函数来激活表单



在我的表单模型中,我有一个以这种方式定义的字段的自定义验证函数

class SignupForm extends Model
{
    public function rules()
    {
        return [
            ['birth_date', 'checkDateFormat'],
            // other rules
        ];
    }
    public function checkDateFormat($attribute, $params)
    {
        // no real check at the moment to be sure that the error is triggered
        $this->addError($attribute, Yii::t('user', 'You entered an invalid date format.'));
    }
}

当我按下提交按钮时,错误消息不会显示在表单视图中的字段下,而其他规则(如所需的电子邮件和密码)会出现。

正在处理注册本机表单,因此为了确保它不是归档问题,我设置了规则

['username', 'checkDateFormat']

并删除了与用户名字段相关的所有其他规则,但该消息也没有显示。

我尝试过不将任何参数传递给checkDateFormat,我尝试将字段的名称显式传递给addError()

$this->addError('username', '....');

但什么也没出现。

设置自定义验证函数的正确方法是什么?

你读过文档吗?

根据上述验证步骤,属性将是 验证当且仅当它是在 中声明的活动属性 scenario() 并与一个或多个活动规则相关联 在规则()中声明。

因此,您的代码应如下所示:

class SignupForm extends Model
{
    public function rules()
    {
        return [
            ['birth_date', 'checkDateFormat'],
            // other rules
        ];
    }
    public function scenarios()
    {
        $scenarios = [
            'some_scenario' => ['birth_date'],
        ];
        return array_merge(parent::scenarios(), $scenarios);
    }
    public function checkDateFormat($attribute, $params)
    {
        // no real check at the moment to be sure that the error is triggered
        $this->addError($attribute, Yii::t('user', 'You entered an invalid date format.'));
    }
}

在控制器集场景中,示例:

$signupForm = new SignupForm(['scenario' => 'some_scenario']);

尝试对空字段强制验证

['birth_date', 'checkDateFormat', 'skipOnEmpty' => false, 'skipOnError' => false],

此外,请确保不要为视图中的birth_date字段分配 id。

如果您有 birth_date 的 id,则需要指定selectors

<?= $form->field($model, 'birth_date', ['selectors' => ['input' => '#myBirthDate']])->textInput(['id' => 'myBirthDate']) ?>

要在 yii 2 中进行自定义验证,您可以在模型中编写自定义函数并在规则中分配该函数。例如。我必须在password字段中应用密码条件,然后我将在模型中这样写。

public function rules()
{
    return [
        ['new_password','passwordCriteria'],
    ];
}
public function passwordCriteria()
{
    if(!empty($this->new_password)){
        if(strlen($this->new_password)<8){
            $this->addError('new_password','Password must contains eight letters one digit and one character.');
        }
        else{
            if(!preg_match('/[0-9]/',$this->new_password)){
                $this->addError('new_password','Password must contain one digit.');
            }
            if(!preg_match('/[a-zA-Z]/', $this->new_password)){
                $this->addError('new_password','Password must contain one character.');
            }
        }
    }
}

如果要从类模型扩展,则需要在某处触发$model->validate()

我在使用 CRUD 生成器时偶然发现了这个。生成的 actionCreate() 函数不包含模型验证调用,因此永远不会调用自定义验证器。此外,_form不包括和错误摘要。

因此,将错误摘要添加到_form。

<?= $form->errorSummary($model); ?>

。并将验证调用 - $model->validate() - 添加到控制器操作

public function actionCreate()
{
    $model = new YourModel();
    if ($model->load(Yii::$app->request->post()) && $model->validate()) {...

虽然这是一个旧帖子,但我认为我应该回答。

您应该创建一个自定义验证程序类,并且要创建一个支持客户端验证的验证程序,您应该实现 yiivalidatorsValidator::clientValidateAttribute() 方法,该方法返回一段在客户端执行验证的 JavaScript 代码。在 JavaScript 代码中。

您可以使用以下预定义变量:

attribute:要验证的属性的名称。

value:正在验证的值。

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

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

因此,这意味着您可以使用messages数组在此方法的 javascript 代码块中运行时将消息推送到客户端。

我将创建一个包含虚拟支票的类,这些检查可以按照您希望的方式替换。 并根据您的 yii2 advancedbasic更改namespace

Custom Client-side Validator

namespace commoncomponents;
use yiivalidatorsValidator;
class DateFormatValidator extends Validator{
public function init() {
        parent::init ();
        $this->message = 'You entered an invalid date format.';
    }
    public function validateAttribute( $model , $attribute ) {
        if ( /*SOME CONDITION TO CHECK*/) {
            $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 ($("#DATE-1").val()=="" || $("#DATE-2").val() =="") {
    messages.push($message);
}
JS;
    }
}

然后在模型中SigupForm添加rule

['birth_date', 'commoncomponentsDateFormatValidator'],

Deferred Validation

您甚至可以在 clientValidateAttribute 函数中添加 ajax 调用,并且基于该 ajax 调用的结果,您可以将消息推送到客户端,但您可以使用 yii 提供的 deferred 对象,它是一个延迟对象数组,您可以在该数组中推送调用或显式创建延迟对象并调用其 resolve() 方法。

Default Yii's deferred Object

public function clientValidateAttribute($model, $attribute, $view)
{
    return <<<JS
        deferred.push($.get("/check", {value: value}).done(function(data) {
            if ('' !== data) {
                messages.push(data);
            }
        }));
JS;
}

关于Deferred Validation

您需要从控制器渲染模型。无需初始化视图中的模型。在控制器中,您需要调用验证函数

你确定addError的第一个参数不应该是这样的吗

$this->addError(**'attribute'**, Yii::t('user', 'You entered an invalid date format.'));

我遇到了常见问题。

在验证函数中:

public function checkDateFormat($attribute, $params)
    {
        // no real check at the moment to be sure that the error is triggered
        $this->addError($attribute, Yii::t('user', 'You entered an invalid date format.'));
    }

$params根本没有任何价值。它实际上总是等于 Null。您必须在函数中检查属性值:

public function checkDateFormat($attribute, $params)
{
    if($this->birth_date == False)
    {
        $this->addError($attribute, Yii::t('user', 'You entered an invalid date format.'));
    }
}

这就是它对我的工作方式。

如果不对模型使用方案,则必须将致敬标记为"安全":

    ['birth_date','safe'],
    ['birth_date', 'checkDateFormat'],

另一方面,您可以使用它进行日期验证:

    ['birth_date','safe'],
    [['birth_date'],'date', 'format'=>'php:Y-m-d'],

您可以根据需要更改格式。

**我们应该为函数设置属性以使用输入值 **

public function rules()
{
    return [
        ['social_id','passwordCriteria'],
    ];
}
public function passwordCriteria($attribute, $params)
{
   
    if(!empty($this->$attribute)){
       $input_value = $this->$attribute;
       //all good 
    }else{
       //Error empty value
       $this->addError('social_id','Error - value is empty');
    }
 }

您是否有机会使用客户端验证?如果你这样做,那么你必须编写一个javascript函数来验证输入。你可以在这里看到他们是如何做到的:

http://www.yiiframework.com/doc-2.0/guide-input-validation.html#conditional-validation

另一种解决方案是禁用客户端验证,使用 ajax 验证,这也应该带回错误。

还要确保你没有覆盖输入的模板,这意味着如果你覆盖了它,请确保你仍然有{error}。

你对规则的语法应该是这样的人,

[['birth_date'], 'checkDateFormat']

不是这个

['birth_date', 'checkDateFormat']

所以在你的例子中,它应该看起来像下面

...
class SignupForm extends Model
{
    public function rules()
    {
        // Notice the different with your previous code here
        return [
            [['birth_date'], 'checkDateFormat'], 
            // other rules
        ];
    }
    public function checkDateFormat($attribute, $params)
    {
        // no real check at the moment to be sure that the error is triggered
        $this->addError($attribute, Yii::t('user', 'You entered an invalid date format.'));
    }
}

相关内容

  • 没有找到相关文章

最新更新