Reputation: 5448
Is it possible to enable ajax validation on form submit only, and have client / JS validation on change / blur? So for example:
Here is my ActiveForm config:
<?php $form = ActiveForm::begin([
'id' => 'login-form',
'enableAjaxValidation' => true,
'enableClientValidation' => true,
'validateOnBlur' => true,
'validateOnChange' => true,
'validateOnSubmit' => true,
]); ?>
Currently, when I focus out of a field, it will apply ajax validation as well - I do not want this.
Upvotes: 0
Views: 2733
Reputation: 23738
To do it the way you want it to work you need to submit the form via AJAX and it is required to attach a handler on afterValidate
event. The handler will replace default form submission and is responsible for sending data to the server and displaying error messages if server validation fails. Displaying validation messages requires support on the controller side.
You can update the form name/id
respectively in the script. and add the alerts in the error and incorrect server response. your form will be automatically saved via ajax call without reloading you can reset the form inside the success part.
Attach a handler to form:
$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
})');
Just make sure you have your action coded like below
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]);
}
And most important just initialize your form with the option enableClientValidation
as true
like below.
$form = ActiveForm::begin([
'id' => 'login-form',
'enableClientValidation' => true,
]);
Upvotes: 1