I have a page with GridView and I want to make it possible to edit data without reloading the page. The GridView structure is basic. When I click on the button, I upload the form to the modal window and then track the form submission event. The data changes correctly, but ajax validation does not work.
ActiveForm
<?php $form = ActiveForm::begin([
'id' => 'update-form',
'action' => Url::to(['/product/ajax-update', 'wbId' => $model->wbId]),
'validationUrl' => Url::to(['/product/ajax-validate', 'wbId' => $model->wbId]),
'enableAjaxValidation' => true,
'validateOnChange' => true,
'method' => 'post',
]); ?>
<?= $form->field($model, 'wbId') ?>
<?= $form->field($model, 'supplierArticle') ?>
<?= $form->field($model, 'costPrice') ?>
<?= $form->field($model, 'accountName') ?>
<?php ActiveForm::end(); ?>
Validation rules
public function rules()
{
return [
[['wbId', 'supplierArticle', 'costPrice', 'createDate'], 'required'],
[['wbId'], 'integer'],
[['costPrice'], 'number'],
[['createDate', 'updateDate'], 'safe'],
[['supplierArticle'], 'string', 'max' => 100],
[['accountName'], 'string', 'max' => 50],
[['wbId'], 'unique'],
];
}
Load modal form function
public function actionLoadForm()
{
Yii::$app->response->format = Response::FORMAT_JSON;
if (Yii::$app->request->isAjax)
{
$wbId = Yii::$app->request->post('wbId');
if ($wbId)
{
$product = Product::find()->where(['wbId' => $wbId])->one();
if ($product)
{
return [
'success' => true,
'render' => $this->renderPartial('parts/form', [
'model' => $product
])
];
}
}
}
return false;
}
Ajax update function
public function actionAjaxUpdate($wbId)
{
Yii::$app->response->format = Response::FORMAT_JSON;
if (Yii::$app->request->isAjax)
{
/* @var $model Product */
$model = Product::find()->where(['wbId' => $wbId])->one();
if ($model)
{
if ($model->load(Yii::$app->request->post()) && $model->validate())
{
if ($model->save())
{
return [
'success' => true
];
}
}
}
}
return [
'success'=> false
];
}
Ajax validation
public function actionAjaxValidate($wbId)
{
Yii::$app->response->format = Response::FORMAT_JSON;
if (Yii::$app->request->isAjax)
{
/* @var $model Product */
$model = Product::find()->where(['wbId' => $wbId])->one();
if ($model->load(Yii::$app->request->post()))
{
return ActiveForm::validate($model);
}
}
return false;
}
Js - load form
$(document).on('click', updateItemButton, function (e)
{
let wbId = $(this).closest('tr').data('key');
$(updateModal).modal('show');
$.ajax({
type: "POST",
url: "/product/load-form",
dataType: "json",
cache: false,
data: {
"wbId": wbId
},
success: function (response)
{
if (response.success)
{
$(updateModal_content).html(response.render);
}
else
{
console.log(response);
}
},
error: function (response)
{
console.log(response);
}
});
e.preventDefault();
});
Js - submit-form
$(document).on('submit', updateModal_form, function (e)
{
e.preventDefault();
let formData = $(this).serializeArray();
$.ajax({
type: "POST",
url: $(this).attr('action'),
dataType: "json",
cache: false,
data: formData,
success: function (response)
{
console.log(response);
},
error: function (response)
{
console.log(response);
}
});
});
The validation event does not fire at all. Not when changing the data, nor when submitting the form. If incorrect data is entered, the request is sent to ajax-update and the server returns an empty response (because validation was not passed). How to make ajax data saving and ajax validation work together?
*I want to solve this problem without using pjax.
** Everything works correctly if you don't load the form via ajax. Apparently the problem is here.
Thx to Michal Hynčica. I just needed to use the method
renderAjax()instead ofrenderPartial()when I render the form.