我想知道是否有任何Yii2专家可以帮助我了解如何最好地使用ajax表格并结合Yii ajax验证。我想我可以解释这个问题,而无需通过我的所有代码。
我正在使用促销代码表单,用户在表单中输入促销代码,表单通过ajax提交。然后,我们对促销代码详细信息执行数据库查找,验证代码,如果代码验证,我们希望显示隐藏在页面上的注册表单。
我有一个表单字段“code”的自定义验证函数,它是名为“register”的模型场景中的活动字段。
class UserCode extends ActiveRecord
{
...
public function scenarios()
{
return [
'register' => ['code'],
];
}
public function rules()
{
return [
[['code'], 'required'],
[['code'], 'validateUserCode', 'on' => ['register']],
];
}
public function validateUserCode($attribute, $params)
{
// perform all my custom logic to determine if the code is valid
if ($code_invalid) {
$this->addError($attribute, 'Sorry, this code is invalid.');
}
}
...
}
然后在控制器中,如Yii2指南所示,我使用以下代码捕获此ajax验证:
public function actionValidate() {
$model = new UserCode(['scenario' => 'register']);
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
// no logic can be run after the above code b/c the form is submit with ajax
// and therefore always trapped in the Yii::$app->request->isAjax conditional
}
上面的代码都运行正常,如果我从表单上的$form->field($model, 'code')
字段中删除焦点,Yii的ajax验证将启动并根据我的自定义验证逻辑显示我的自定义错误消息。
当我提交表格时,我的挑战就出现了。表单提交也是通过ajax处理的,因此控制器操作总是返回ActiveForm::validate($model);
的结果,因为if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post()))
将适用于ajax表单验证和表单提交。
通过上述方法,我被迫只返回ajax验证的结果,而不是我可能需要的任何json数据进行额外的客户端验证,例如在通过提交有效使用代码后显示注册表单ajax形式。
我意识到我可以在ActiveForm上设置'enableAjaxValidation' => false
,然后在if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post()))
条件内返回我自己的json数据。如果我这样做,我可以显示注册表单,因为我有自己的json数据可以使用。
有没有办法在使用ajax提交的表单上进行ajax验证?你怎么能单独从ajax表单提交中捕获ajax验证来以不同的方式处理这两个事件?
非常感谢任何建议或替代方法!
答案 0 :(得分:18)
与您提交表单的网址相比,您应该使用不同的网址设置validationUrl
。通过这种方式,您可以使用验证函数来验证并返回return ActiveForm::validate($model);
以及执行其他操作的正常提交表单。
您可以详细了解validationUrl
here:
答案 1 :(得分:0)
我找到了解决方法:
表格:
<?php
$form = ActiveForm::begin(['id' => 'form-add-contact', 'enableAjaxValidation' => true, 'validationUrl' => Yii::$app->urlManager->createUrl('contacts/contacts/contact-validate')]);
?>
通过Ajax提交:
<?php
$script = <<< JS
$(document).ready(function () {
$("#form-add-contact").on('beforeSubmit', function (event) {
event.preventDefault();
var form_data = new FormData($('#form-add-contact')[0]);
$.ajax({
url: $("#form-add-contact").attr('action'),
dataType: 'JSON',
cache: false,
contentType: false,
processData: false,
data: form_data, //$(this).serialize(),
type: 'post',
beforeSend: function() {
},
success: function(response){
toastr.success("",response.message);
},
complete: function() {
},
error: function (data) {
toastr.warning("","There may a error on uploading. Try again later");
}
});
return false;
});
});
JS;
$this->registerJs($script);
?>
控制器:
/*
* CREATE CONTACT FORM AJAX VALIDATION ACTION
*/
public function actionContactValidate() {
$model = new ContactsManagement();
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
$model->company_id = Yii::$app->user->identity->company_id;
$model->created_at = time();
\Yii::$app->response->format = Response::FORMAT_JSON;
return ActiveForm::validate($model);
}
}
/**
* Quick Add Contact Action
* @param type $id
* @return type
*/
public function actionAddContact() {
$model = new ContactsManagement();
if (Yii::$app->request->isAjax && $model->load(Yii::$app->request->post())) {
$transaction = \Yii::$app->db->beginTransaction();
try {
if ($model->validate()) {
$flag = $model->save(false);
if ($flag == true) {
$transaction->commit();
return Json::encode(array( 'status' => 'success', 'type' => 'success', 'message' => 'Contact created successfully.'));
} else {
$transaction->rollBack();
}
} else {
return Json::encode(array('status' => 'warning', 'type' => 'warning', 'message' => 'Contact can not created.'));
}
} catch (Exception $ex) {
$transaction->rollBack();
}
}
return $this->renderAjax('_add_form', [
'model' => $model,
]);
}