Tuesday, September 9, 2014

Validate Yii2 forms before submitting with AJAX

I'm sure the code is much explanatory itself. Here is the solution. This would prevent the form being submitted the usual way while still the client validation is done.

<?php $form = ActiveForm::begin([
        'action' => ['create'],
        'enableAjaxValidation' = false,
        'enableClientValidation' = true,
        'beforeSubmit' => "function(form) {
        
                if($(form).find('.has-error').length) {
                        return false;
                }
                
                $.ajax({
                        url: form.attr('action'),
                        type: 'post',
                        data: form.serialize(),
                        success: function(data) {
                                // do something ...
                        }
                });
                
                return false;
        }",
]); ?>

This old method does not work anymore. Yii2 was updated lately to support more elegant way of handling JavaScript events. Please refer to:
https://github.com/yiisoft/yii2/pull/4955
https://github.com/yiisoft/yii2/issues/1350

Following code shows how you can use JS events to handle the same situation above.

Your php code remains same:
<?php $form = ActiveForm::begin([
        'id' => 'login-form',
        'action' => ['create'],
        'enableAjaxValidation' = false,
        'enableClientValidation' = true,
        
]); ?>

But the JavaScript part goes to a separate .js file:
$(document).ready(
        $('#login-form').on('beforeSubmit', function(event, jqXHR, settings) {
                var form = $(this);
                if(form.find('.has-error').length) {
                        return false;
                }
                
                $.ajax({
                        url: form.attr('action'),
                        type: 'post',
                        data: form.serialize(),
                        success: function(data) {
                                // do something ...
                        }
                });
                
                return false;
        }),
);