﻿//This is a private jQuery plugin developed by Ahmed Galal (someone_survive@hotmail.com)
//Used as a replacement for the normal $.ajax supported in jQuery
//This jquery plugin supports ajax file uploads and other options

(function ($) {
    jQuery.ajaxAction = function (options) {
        var settings = {
            url: null,
            before: null,
            updateElement: null,
            loaderElement: '#loader',
            loaderCss: 'loading',
            async: true,
            complete: null,
            type: 'POST',
            enctype: 'application/x-www-form-urlencoded',
            validate: null
        };

        if (options) {
            $.extend(settings, options);
        }

        if (!settings.validate) {
            settings.validate = function () {
                return true;
            }
        }

        processAjaxRequest(settings.url, null, settings);
    }
    jQuery.fn.ajaxAction = function (options) {
        var settings = {
            before: null,
            updateElement: null,
            loaderElement: '#loader',
            loaderCss: 'loading',
            async: true,
            complete: null,
            type: 'POST',
            enctype: 'application/x-www-form-urlencoded',
            validate: null
        };

        return this.each(function () {
            if (options) {
                $.extend(settings, options);
            }

            var element = $(this);
            var elementType = this.tagName.toLowerCase();

            if (elementType == "a") {
                settings.type = "GET";

                if (!settings.validate) {
                    settings.validate = function () {
                        return true;
                    }
                }

                element.bind("click", function (e) {
                    e.preventDefault();

                    var url = $(this).attr("href");
                    var data = "";

                    processAjaxRequest(url, data, settings);
                });
            }
            else if (elementType == "form") {
                if (typeof options != "boolean" && options != false) {
                    var fileExists = $("input[type='file']", element).length > 0;

                    element.bind("submit", function (e) {
                        e.preventDefault();

                        if (!settings.validate) {
                            settings.validate = function () {
                                if (element.validate) {
                                    return element.valid();
                                }
                                else {
                                    return true;
                                }
                            }
                        }

                        settings.enctype = element.attr("enctype");

                        var url = $(this).attr("action");
                        var data = $(this).serialize();

                        if (fileExists) {
                            processIFrameRequest(element, url, data, settings);
                        }
                        else {
                            processAjaxRequest(url, data, settings);
                        }
                    });
                }
                else if (options == false) {
                    element.unbind("submit");
                }
            }
            else {
                alert("unsupported html element");
            }
        });
    };
    function processIFrameRequest(form, url, data, settings) {
        if (settings.validate()) {
            if (settings.before) {
                settings.before();
            }

            if (settings.loaderElement) {
                $(settings.loaderElement).addClass(settings.loaderCss);
            }

            $(document.body).append("<iframe id='submitFrame' name='submitFrame' style='display:none;'></iframe>");

            var clonedForm = form.clone();

            settings.validate = function () {
                if (clonedForm.validate) {
                    return clonedForm.valid();
                }
                else {
                    return true;
                }
            }

            clonedForm.ajaxAction(settings);
            form.after(clonedForm);

            setTimeout(function () {
                $("iframe#submitFrame").contents().find("body").append(form);
                $(form).ajaxAction(false);
                $(form).submit();

                $("iframe#submitFrame").load(function () {
                    var html = $(this).contents().find("body").html();

                    if (settings.updateElement) {
                        $(settings.updateElement).html(html);
                    }
                    if (settings.loaderElement) {
                        $(settings.loaderElement).removeClass(settings.loaderCss);
                    }
                    if (settings.complete) {
                        settings.complete(html);
                    }

                    $(this).remove();
                });
            }, 10);
        }
    }
    function processAjaxRequest(url, data, settings) {

        if (settings.validate()) {
            if (settings.before) {
                settings.before();
            }
            if (settings.loaderElement) {
                $(settings.loaderElement).addClass(settings.loaderCss);
            }

            $.ajax({ url: url, data: data, cache: false, async: settings.async, type: settings.type, enctype: settings.enctype,
                success: function (html) {
                    if (settings.updateElement) {
                        $(settings.updateElement).html(html);
                    }
                    if (settings.loaderElement) {
                        $(settings.loaderElement).removeClass(settings.loaderCss);
                    }
                    if (settings.complete) {
                        settings.complete(html);
                    }
                }, error: function () {
                    alert("Error occurred while requesting");
                    if (settings.loaderElement) {
                        $(settings.loaderElement).removeClass(settings.loaderCss);
                    }
                    if (settings.complete) {
                        settings.complete(html);
                    }
                }, abort: function () {
                    alert("Request aborted");
                    if (settings.complete) {
                        settings.complete(html);
                    }
                }
            });
        }
    }
})(jQuery);
