Handling Ajax Response Errors From Laravel Form Request Validation: lalavalidate.js

//A jquery plugin to handle error response from server and the server side
//use Laravel form validator to verify fields.
(function( $ ){
    var settings = {
        default_msg: '請檢查必填欄位', 
        show_default_msg: true,
        err_class_name: 'lala_error'
    }

    $.fn.lalavalidate = function(methodOrOptions) {
        //If methodOrOptions is a method name
        //console.log(methodOrOptions);
        if ( methods[methodOrOptions] ) {
            return methods[ methodOrOptions ].apply( this, Array.prototype.slice.call( arguments, 1 ));
        } else if ( typeof methodOrOptions === 'object' || ! methodOrOptions ) {
            // Default to "init"
            return methods.init.apply( this, arguments );
        } else {
            $.error( 'Method ' +  methodOrOptions + ' does not exist.' );
        }    
    };

    var methods = {
        init : function(options) {
            settings = $.extend(settings, options);
            var err_class_name = settings.err_class_name;
            //console.log(settings);return;

            return this.each( function() {
                var $form = $(this);
                
                $form.find('input, select, textarea').each(function(){
                    var $e = $(this);
                    var type = $e[0].type;

                    if(type == 'radio' || type == 'checkbox'){
                        //console.log(type);
                        var name = $e.attr('name');
                        var $last = $form.find('[name="' + name + '"]:last');

                        $e.on('focus', function(){
                            var $err = $last.parent().find('.' + err_class_name);
                            if($err.length > 0){
                                $err.remove();
                            }
                        });
                    }else{
                        $e.on('focus', function(){
                            var $parent = $e.parent();
                            var $err = $parent.find('.' + err_class_name);
                            if($err.length > 0){
                                $err.remove();
                            }
                        });
                    }
                });
            });
        },
        show_errors: function(response){
            //console.log(response);
            return this.each( function() {
                var $this = $(this);

                //Process responseJSON first
                if (typeof response.responseJSON != 'undefined') {
                    var json = response.responseJSON;
                    var errors = json.errors;
                    //console.log(errors);
                    if(settings.show_default_msg == true){
                        alert(settings.default_msg);
                    }

                    display_field_errors($this, errors);
                }else if(typeof response.responseText != 'undefined') {
                    alert(response.responseText);
                }else{
                    alert(response);
                }
            });
        }
    };

    function display_field_errors($form, errors){
        var err_class_name = settings.err_class_name;

        for(var key in errors){
            var err = errors[key];
            var $el = $form.find('[name="' + key + '"]');

            if($el.length != 0){
                var type = $el[0].type;

                if(type == 'radio' || type == 'checkbox'){
                    var $last = $el.last();
                    var $err = $last.parent().find('.' + err_class_name);
                    if($err.length > 0){
                        $err.remove();
                    }

                    var $error = $('<div class="' + err_class_name + '" style="display:block;color:#ff0000;">' + err[0] + '</div>');
                    $last.parent().append($error);
                }else{
                    var $err = $el.parent().find('.' + err_class_name);
                    if($err.length > 0){
                        $err.remove();
                    }

                    var $error = $('<div class="' + err_class_name + '" style="display:block;color:#ff0000;">' + err[0] + '</div>');
                    $el.parent().append($error);
                }
            }
        }
    }

})( jQuery );

Usage:

$(document).ready(function () {
    $('#iform').lalavalidate();
        
    $('#iform').ajaxForm({
        dataType: 'json',
        beforeSubmit: function (arr, $form, options) {
            if ($('#agree').prop('checked') == false) {
                alert('勾選同意使用條款及合約後才可送出表單');
                return false;
            }

            var pass1 = $('[name="password"]').val();
            var pass2 = $('[name="rpassword"]').val();
            if (pass1 != pass2) {
                alert('請輸入相同的密碼');
                return false;
            }
        },
        success: function (data, statusText, xhr, $form) {
            //console.log(data);
            if (typeof data.status == 'undefined') {
                alert(data);
            } else if (data.status == 'fail') {
                alert(data.message);
            } else {
                //console.log(data);
                alert('註冊成功,請至您的電子郵件信箱收取確認信');
                window.location.href = base_url;
            }
        },
        error: function (data) {
            //console.log(data);
            $('#iform').lalavalidate('show_errors', data);
        }
    });
});