How to make ajax update and ajax validation work together in Yii2?

294 views Asked by At

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.

1

There are 1 answers

0
daniil sidorov On

Thx to Michal Hynčica. I just needed to use the method renderAjax() instead of renderPartial() when I render the form.