Yii2 - ajax 仅提交验证,客户端更改验证

Yii2 - ajax validation on submit only, client validation on change

是否可以仅在表单提交时启用 ajax 验证,并在更改/模糊时启用客户端/JS 验证?例如:

  1. 用户输入数据并按下 Tab 键:应应用客户端验证
  2. 用户然后提交表单:ajax验证应该适用
  3. 如果验证成功,继续正常的表单提交

这是我的 ActiveForm 配置:

<?php $form = ActiveForm::begin([
    'id' => 'login-form',
    'enableAjaxValidation' => true,
    'enableClientValidation' => true,
    'validateOnBlur' => true,
    'validateOnChange' => true,
    'validateOnSubmit' => true,
]); ?>

目前,当我关注某个字段时,它也会应用 ajax 验证 - 我不想要这个。

要按照您希望的方式进行操作,您需要通过 AJAX 提交表单,并且需要在 afterValidate 事件上附加一个处理程序。处理程序将替换默认的表单提交,并负责向服务器发送数据并在服务器验证失败时显示错误消息。显示验证消息需要控制器端支持。

您可以在脚本中分别更新表单name/id。并在错误和不正确的服务器响应中添加警报。您的表单将通过 ajax 调用自动保存而无需重新加载您可以在成功部分重置表单。

将处理程序附加到表单:

$this->registerJs('$(\'#my-form\').on(\'afterValidate\', function () {
    var $yiiform = $(this);
    $.ajax({
            type: $yiiform.attr(\'method\'),
            url: $yiiform.attr(\'action\'),
            data: $yiiform.serializeArray(),
        }
    )
        .done(function(data) {
            if(data.success) {
                $yiiform.submit();
                // data is saved
            } else if (data.validation) {
                // server validation failed
                $yiiform.yiiActiveForm(\'updateMessages\', data.validation, true); // renders validation messages at appropriate places
                console.log("error on form"+data.validation);
            } else {
                console.log("incorrect server response");
                // incorrect server response
            }
        })
        .fail(function () {
            console.log("request failed");
            // request failed
        })

    return false; // prevent default form submission
})');

只需确保您的操作编码如下

Controller action:

public function actionUpdate($id)
{
    if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {

        //call model validate to trigger validation messages
        $model->validate();

        $result = [];

        // The code below comes from ActiveForm::validate(). We do not need to validate the model
        // again, as it was already validated by save(). Just collect the messages.
        foreach ($model->getErrors() as $attribute => $errors) {
            $result[\yii\helpers\Html::getInputId($model, $attribute)] = $errors;
        }
        if (!empty($result)) {
            return $this->asJson(['validation' => $result]);
        }

        return $this->asJson(['success' => true]);

    } elseif ($model->load(Yii::$app->request->post()) && $model->save()) {
        Yii::$app->session->setFlash('success', 'Form saved successfully');
        return $this->redirect('index');
    }

    return $this->render('form', ['model' => $model]);
}

最重要的是,只需使用 enableClientValidation 选项初始化您的表单,如下所示 true

$form = ActiveForm::begin([
    'id' => 'login-form',
    'enableClientValidation' => true,
]);