问题
Currently to achieve ajax submit and validation at the same time. I'm using custom function like:
$('.edit_form').submit(function (e) {
e.preventDefault();
var form = $(this);
var formData = $(this).serialize();
if (form.find('.has-error').length) {
return false;
}
$.ajax({
url: form.attr("action"),
type: form.attr("method"),
data: formData,
success: function (data) {
...
},
error: function () {
alert("Something went wrong");
}
});
});
And here is php side, for validation my config looks like that:
$form = ActiveForm::begin([
'id' => "some_form",
'action' => ['user/edit'],
'options' => ['class' => 'edit_form'],
'enableAjaxValidation' => false,
'enableClientValidation' => true,
]); ?>
I'm sure that It's not the best way to achieve what I need. Especially this part that I use for preventing for submission in case of validation error:
if (form.find('.has-error').length) {
return false;
}
Any suggestions? How to achieve ajax submission and validation properly using Yii 2's inbuilt settings?
回答1:
Use beforeSubmit event instead of submit, the beforeSubmit will only be triggered once the form passes the validation.
$('form').on('beforeSubmit', function(e) {
var form = $(this);
var formData = form.serialize();
$.ajax({
url: form.attr("action"),
type: form.attr("method"),
data: formData,
success: function (data) {
...
},
error: function () {
alert("Something went wrong");
}
});
}).on('submit', function(e){
e.preventDefault();
});
回答2:
you can use AjaxSubmitButton.
Your form should b
$form = ActiveForm::begin([
'id' => "some_form",
'action' => 'javascript:void(0)',
'options' => ['class' => 'edit_form'],
]);
use AjaxSubmitButton here
AjaxSubmitButton::begin([
'label' => 'Submit',
'id' => 'some_form',
'ajaxOptions' => [
'type' => 'POST',
'url' => \yii\helpers\Url::to(['/user/edit']),
'success' => new \yii\web\JsExpression(
'function(data){
if(data=="success")
{
}else{
$.each(data, function(key, val) {
$("#"+key).after("<div class=\"help-block\">"+val+"</div>");
$("#"+key).closest(".form-group").addClass("has-error");
});
}
}'
),
],
'options' => ['class' => 'btn btn-success', 'type' => 'submit'],
]);
AjaxSubmitButton::end();
In your controller
public function actionEdit()
{
$model = new User;
if($model->save())
{
$result = 'success';
Yii::$app->response->format = trim(Response::FORMAT_JSON);
return $result;
}else{
$error = \yii\widgets\ActiveForm::validate($model);
Yii::$app->response->format = trim(Response::FORMAT_JSON);
return $error;
}
}
回答3:
Here I've find some interesting javascript-side validation tricks
So, a javascript submit button can be as:
$('body').on('click', '#submit', function(e) {
e.preventDefault();
var yiiform = $('#my-form');
$.ajax({
type: yiiform.attr('method'),
url: yiiform.attr('action'),
data: yiiform.serializeArray(),
success: function(data) {
if(data.success == 'true') {
window.location.href = 'http://my.success.page';
} else {
// here there is (maybe) the right way to trigger errors
$.each(data, function(key, val) {
yiiform.yiiActiveForm('updateAttribute', key, [val]);
});
}
}
});
}
triggered by:
<?= Button::widget([
'label' => Yii::t('app', 'Submit'),
'options' => [
'id'=>'submit',
'class' => 'btn btn-primary pull-right',
]]);?>
And the action controller will reply with:
...
if ($model->load(Yii::$app->request->post())) {
Yii::$app->response->format = Response::FORMAT_JSON;
if($model->save()) {
return ['success'=>'true'];
} else {
return ActiveForm::validate($model);
}
}
...
Details about ActiveForm::validate() can be found here
来源:https://stackoverflow.com/questions/31417868/yii2-activeform-ajax-submit-and-validation