wysharpDefaultModalContainerSelector = "#wysharp-default-modal-container";
wysharpDefaultLoadingContainerSelector = "#wysharp-default-loading-container";
wysharpDefaultGlobalTipSelector = "#wysharp-default-global-tip";
wysharpDefaultGlobalTipMsgSelector = "#wysharp-default-global-tip-msg";
wysharpDefaultJqueryLoadingOverlayOptions = {
    image:"",
    fontawesome : "fa fa-cog fa-spin",
    size: 12
};

var wySharpJqValidateDefaultOptions = {
    ignore: [],
    /*errorPlacement: function(error, element) {
        $.showFormFieldValidationResult({field: element, msg: error.text()});
    },*/
    showErrors : function(errorMap, errorList) {
        if (!errorList || errorList.length == 0){
            return;
        }
        var jqForm = $.getJqObj($.getJqObj(errorList[0].element).closest("form"));
        jqForm.find(".form-group").removeClass("has-error").removeClass("has-success").addClass("has-success");
        jqForm.find(".help-block").text("");
        for (var i = 0; i < errorList.length; i++){
            var error = errorList[i];
            $.showFormFieldValidationResult({field: error.element, msg: error.message});
        }
    },
    onfocusin: false,
    onfocusout: false,
    onkeyup: false,
    onclick: false,
    /*success:function(label, element) {
        ///<summary>验证成功后调用的方法</summary>
        $.getJqObj(element).closest(".form-group").removeClass("has-error");
    },*/
    /*highlight: function (element) {
        /!*$(element).closest('.form-group').addClass('has-error');*!/
    },*/
    /*unhighlight: function (element, errorClass) {
        /!*$(element.closest('.form-group')).removeClass('has-error').addClass("has-success");*!/
    }*/
};
$.validator.setDefaults(wySharpJqValidateDefaultOptions);

$.extend({
    renderPartial: function (args) {
        ///<summary>渲染部分视图</summary>
        ///<param name="args" type="Object"></param>
        ///<param name="args.url" type="string">请求URL</param>
        ///<param name="args.data" type="Object">请求数据</param>
        ///<param name="args.container" type="string/HTMLElement/Object">容器</param>
        ///<param name="args.onFinished" type="function">结束事件</param>
        ///<param name="args.loadingOptions" type="object">Loading选项</param>
        ///<param name="args.tipOptions" type="object">提示框选项</param>
        ///<param name="args.ajaxOptions" type="object">jquery ajax选项</param>
        if ($.isEmptyObject(args)) {
            console.error("参数为空");
            return;
        }
        if (!args.url) {
            console.error("请求URL为空");
            return;
        }
        var jqContainer = $.getJqObj(args.container);
        if ($.isEmptyObject(jqContainer)) {
            console.error("未找到目标容器");
            return;
        }
        /*var onFinished = function (response, status, xhr) {
            $.hideLoading(args.loadingOptions);
            if (args.onFinished && typeof (args.onFinished) == "function") {
                args.onFinished();
            }
            if (status != "success") {
                console.error(xhr.status + " " + xhr.statusText);
            }
        };
        var data = args.data ? args.data : null;
        if (args.data) {
            jqContainer.load(args.url, data, onFinished);
        } else {
            jqContainer.load(args.url, onFinished);
        }*/
        var method = args.data ? "POST" : "GET";
        var defaultAjaxOptions = {
            url: args.url,
            type: method,
            success: function (result, status, xhr) {
                $.hideLoading(args.loadingOptions);
                try {
                    if (typeof (result) == "object") {
                        $.showAlert({message: result.msg});
                    } else if (typeof (result) == "string") {
                        jqContainer.html(result);
                    }
                    if (args.onFinished && typeof (args.onFinished) == "function") {
                        args.onFinished();
                    }
                } catch (e) {
                    if (console && typeof (console.error) == "function") {
                        console.error(e.message);
                    }
                }
            },
            error: function (XMLHttpRequest, textStatus, errorThrown) {
                $.hideLoading(args.loadingOptions);
                if (console && typeof (console.error) == "function") {
                    console.error(e.message);
                }
            }
        };
        var finalAjaxOptions = $.extend(true, defaultAjaxOptions, args.ajaxOptions);
        if (args.data) {
            finalAjaxOptions.data = args.data;
        }
        $.showLoading(args.loadingOptions);
        $.ajax(finalAjaxOptions);
    },
    
    popBsModal: function (args) {
        ///<summary>弹出Bootstrap模态框</summary>
        ///<param name="args" type="Object"></param>
        ///<param name="args.container" type="string/HTMLElement/Object">容器</param>
        ///<param name="args.size" type="string/Object">尺寸。参数类型为string时，传递WySharpSize枚举；参数类型为Object时，传递{width: [value], height: [value]}</param>
        var defaultArgs = {
            container: wysharpDefaultModalContainerSelector,
            size: { width: "500px" }
        };
        var finalArgs = $.extend(true, defaultArgs, args);
        var jqContainer = $.getJqObj(finalArgs.container);
        if (!jqContainer || jqContainer.length <= 0) {
            return;
        }
        if (finalArgs.size) {
            var jqDialog = jqContainer.children(".modal-dialog");
            if (typeof(finalArgs.size) == "string") {
                switch (finalArgs.size) {
                    case WySharpSize.Large:
                        jqDialog.addClass("modal-lg");
                        break;
                    case WySharpSize.Middle:
                        jqDialog.addClass("modal-md");
                        break;
                    case WySharpSize.Small:
                        jqDialog.addClass("modal-sm");
                        break;
                    default:
                        console.error("参数size枚举错误");
                        break;
                }
            } else if (typeof (finalArgs.size) == "object") {
                if (finalArgs.size.width) {
                    jqDialog.css("width", finalArgs.size.width);
                }
                if (finalArgs.size.height) {
                    jqDialog.css("height", finalArgs.size.height);
                }
            } else {
                console.error("参数size类型错误");
            }
        }
        jqContainer.modal('show');
    },

    popBsPartial: function (args) {
        ///<summary>弹出部分视图</summary>
        ///<param name="args.url" type="string">请求URL</param>
        ///<param name="args.data" type="Object">请求数据</param>
        ///<param name="args.container" type="string/HTMLElement/Object">容器</param>
        ///<param name="args.onFinished" type="function">结束事件</param>
        ///<param name="args.size" type="string/Object">尺寸。参数类型为string时，传递WySharpSize枚举；参数类型为Object时，传递{width: [value], height: [value]}</param>
        ///<param name="args.ajaxOptions" type="object">jquery ajax选项</param>
        var defaultArgs = {
            container: wysharpDefaultModalContainerSelector,
        };
        var finalArgs = $.extend(true, defaultArgs, args);
        finalArgs.onFinished = function() {
            $.popBsModal(finalArgs);
            if (args.onFinished && typeof(args.onFinished) == "function") {
                args.onFinished();
            }
        };
        var renderPartialArgs = $.extend(true, {}, finalArgs);
        renderPartialArgs.container = $.getJqObj(renderPartialArgs.container).find(".modal-content");
        $.renderPartial(renderPartialArgs);
    },

    /*showLoading: function (args) {
        ///<summary>显示Loading</summary>
        ///<param name="args.container" type="string/HTMLElement/Object">控件容器</param>
        var defaultArgs = {
            container: wysharpDefaultLoadingContainerSelector
        };
        var finalArgs = $.extend(true, defaultArgs, args);

        var jqLoading = $.getJqObj(finalArgs.container);
        if (jqLoading && jqLoading.length > 0) {
            jqLoading.modal('show');
        }
        return jqLoading;
    },*/

    showLoading: function (args) {
        ///<summary>显示Loading</summary>
        ///<param name="args.container" type="string/HTMLElement/Object">控件容器</param>
        var defaultArgs = wysharpDefaultJqueryLoadingOverlayOptions;
        var finalArgs = $.extend(true, defaultArgs, args);

        if (finalArgs.container){
            $(finalArgs.container).LoadingOverlay("show", finalArgs);
        }else {
            $.LoadingOverlay("show", finalArgs);
        }
    },

    resizeLoading: function (args) {
        ///<summary>改变Loading大小尺寸</summary>
        ///<param name="args.container" type="string/HTMLElement/Object">控件容器</param>
        var defaultArgs = wysharpDefaultJqueryLoadingOverlayOptions;
        var finalArgs = $.extend(true, defaultArgs, args);

        if (finalArgs.container){
            $(finalArgs.container).LoadingOverlay("resize");
        }else {
            $.LoadingOverlay("resize");
        }
    },

    /*hideLoading: function (args) {
        ///<summary>隐藏Loading</summary>
        ///<param name="args.container" type="string/HTMLElement/Object">控件容器</param>
        var defaultArgs = {
            container: wysharpDefaultLoadingContainerSelector
        };
        var finalArgs = $.extend(true, defaultArgs, args);

        var jqLoading = $.getJqObj(finalArgs.container);
        if (jqLoading && jqLoading.length > 0) {
            jqLoading.modal('hide');
        }
        return jqLoading;
    },*/

    hideLoading: function (args) {
        ///<summary>隐藏Loading</summary>
        ///<param name="args.container" type="string/HTMLElement/Object">控件容器</param>
        var defaultArgs = {
            hide: true
        };
        var finalArgs = $.extend(true, defaultArgs, args);

        if (finalArgs.container){
            $(finalArgs.container).LoadingOverlay("hide", finalArgs.hide);
        }else {
            $.LoadingOverlay("hide", finalArgs.hide);
        }
    },
    
    showTip: function (args) {
        ///<summary>弹出提示框</summary>
        ///<param name="args.container" type="string/HTMLElement/Object">控件容器</param>
        ///<param name="args.msgContainer" type="string/HTMLElement/Object">消息容器</param>
        ///<param name="args.msg" type="string">提示信息</param>
        ///<param name="args.containerAddCss" type="string">控件容器追加CSS</param>
        ///<param name="args.msgContainerAddCss" type="string">消息容器追加CSS</param>
        ///<param name="args.containerCss" type="string">控件容器CSS</param>
        ///<param name="args.msgContainerCss" type="string">消息容器CSS</param>
        var defaultArgs = {
            container: wysharpDefaultGlobalTipSelector,
            msgContainer: wysharpDefaultGlobalTipMsgSelector,
            containerAddCss: "alert-success"
        };
        var finalArgs = $.extend(true, defaultArgs, args);
        
        var jqTipMsg = $.getJqObj(finalArgs.msgContainer);
        if (finalArgs.msgContainerCss && typeof (finalArgs.msgContainerCss) == "string") {
            jqTipMsg.removeClass();
            jqTipMsg.addClass(finalArgs.msgContainerCss);
        }
        if (finalArgs.msgContainerAddCss && typeof (finalArgs.msgContainerAddCss) == "string") {
            jqTipMsg.addClass(finalArgs.msgContainerAddCss);
        }
        jqTipMsg.text(args.msg);
        
        var jqTip = $.getJqObj(finalArgs.container);
        if (finalArgs.containerCss && typeof (finalArgs.containerCss) == "string") {
            jqTip.removeClass();
            jqTip.addClass(finalArgs.containerCss);
        }
        if (finalArgs.containerAddCss && typeof (finalArgs.containerAddCss) == "string") {
            jqTip.addClass(finalArgs.containerAddCss);
        }

        jqTip.fadeIn();
        var timeoutHandler = setTimeout(function () {
            jqTip.fadeOut();
            jqTipMsg.text("");
        }, 2000);
        jqTip.click(function () {
            clearTimeout(timeoutHandler);
        });

        return jqTip;
    },
    
    ajaxGet: function (args) {
        ///<summary>封装ajax get请求</summary>
        ///<param name="args.ajaxGetOptions" type="object">ajaxt get选项</param>
        ///<param name="args.ajaxGetOptions.url" type="object">URL</param>
        ///<param name="args.ajaxGetOptions.success" type="function">提交成功回调方法</param>
        ///<param name="args.ajaxGetOptions.onSuccess" type="function">提交成功回调方法中执行方法</param>
        ///<param name="args.ajaxGetOptions.onSuccessFront" type="function">提交成功回调方法中最开始执行方法</param>
        ///<param name="args.ajaxGetOptions.onSuccessBack" type="function">提交成功回调方法中最后执行方法</param>
        ///<param name="args.loadingOptions" type="object">Loading选项</param>
        ///<param name="args.tipOptions" type="object">提示框选项</param>
        var defaultArgs = {
        };
        var finalArgs = $.extend(true, defaultArgs, args);
        var defaultAjaxGetOptions = {
            success: function (resultState, statusText, xhr) {
                $.hideLoading(finalArgs.loadingOptions);
                if (resultState && resultState.stateCode == 200) {
                    if (finalArgs.ajaxGetOptions.onSuccessFront && typeof (finalArgs.ajaxGetOptions.onSuccessFront) == "function") {
                        finalArgs.ajaxGetOptions.onSuccessFront(resultState, statusText, xhr);
                    }
                    if (finalArgs.ajaxGetOptions.onSuccess && typeof (finalArgs.ajaxGetOptions.onSuccess) == "function") {
                        finalArgs.ajaxGetOptions.onSuccess(resultState, statusText, xhr);
                    }
                    var defaultTipOptions = { msg: resultState.msg };
                    var finalTipOptions = $.extend(true, defaultTipOptions, finalArgs.tipOptions);
                    $.showTip(finalTipOptions);
                    if (finalArgs.ajaxGetOptions.onSuccessBack && typeof (finalArgs.ajaxGetOptions.onSuccessBack) == "function") {
                        finalArgs.ajaxGetOptions.onSuccessBack(resultState, statusText, xhr);
                    }
                } else {
                    $.showAlert({message: resultState.msg});
                }
            }
        };
        finalArgs.ajaxGetOptions = $.extend(true, defaultAjaxGetOptions, finalArgs.ajaxGetOptions);
        $.get(finalArgs.ajaxGetOptions.url, finalArgs.ajaxGetOptions.success);
        $.showLoading(finalArgs.loadingOptions);
    },

    ajaxGetRefresh: function (args) {
        ///<summary>封装ajax get请求，并刷新</summary>
        ///<param name="args.url" type="string">URL</param>
        ///<param name="args.ajaxGetOptions" type="object">ajaxt get选项</param>
        ///<param name="args.ajaxGetOptions.url" type="object">URL</param>
        ///<param name="args.ajaxGetOptions.success" type="function">提交成功回调方法</param>
        ///<param name="args.ajaxGetOptions.onSuccess" type="function">提交成功回调方法中执行方法</param>
        ///<param name="args.ajaxGetOptions.onSuccessFront" type="function">提交成功回调方法中最开始执行方法</param>
        ///<param name="args.ajaxGetOptions.onSuccessBack" type="function">提交成功回调方法中最后执行方法</param>
        ///<param name="args.refreshOptions" type="object">刷新选项</param>
        ///<param name="args.refreshOptions.refresh" type="function">刷新方法</param>
        ///<param name="args.refreshOptions.beforeRefresh" type="function">刷新前回调</param>
        ///<param name="args.refreshOptions.afterRefresh" type="function">刷新后回调</param>
        var defaultRefreshOptions = {
            refresh: function () {
                var btnSearch = $.getJqObj("#btnSearch");
                if (btnSearch && btnSearch.length > 0) {
                    btnSearch.click();
                } else if (typeof (search) == "function") {
                    search();
                }
            }
        };
        args.refreshOptions = $.extend(true, defaultRefreshOptions, args.refreshOptions);
        var defaultArgs = {
            ajaxGetOptions: {
                onSuccess: function () {
                    if (args.refreshOptions && args.refreshOptions.beforeRefresh && typeof (args.refreshOptions.beforeRefresh) == "function") {
                        args.refreshOptions.beforeRefresh();
                    }
                    args.refreshOptions.refresh();
                    if (args.refreshOptions && args.refreshOptions.afterRefresh && typeof (args.refreshOptions.afterRefresh) == "function") {
                        args.refreshOptions.afterRefresh();
                    }
                }
            }
        };
        var finalArgs = $.extend(true, defaultArgs, args);
        $.ajaxGet(finalArgs);
    },

    ajaxValSubmit: function (args) {
        ///<summary>带有Bootstrap样式jquery.validate验证的ajaxSubmit</summary>
        ///<param name="args.form" type="string/HTMLElement/Object">表单</param>
        ///<param name="args.ajaxSubmitOptions" type="object">ajaxt提交表单选项，由jquery.form的ajaxSubmit选项扩展，可接受全部jquery.form的ajaxSubmit选项</param>
        ///<param name="args.ajaxSubmitOptions.success" type="function">提交成功回调方法</param>
        ///<param name="args.ajaxSubmitOptions.onSuccess" type="function">提交成功回调方法中执行方法</param>
        ///<param name="args.ajaxSubmitOptions.onSuccessFront" type="function">提交成功回调方法中最开始执行方法</param>
        ///<param name="args.ajaxSubmitOptions.onSuccessBack" type="function">提交成功回调方法中最后执行方法</param>
        ///<param name="args.ajaxSubmitOptions.notShowFormValidationResult" type="boolean">不显示表单验证结果</param>
        ///<param name="args.loadingOptions" type="object">Loading选项</param>
        ///<param name="args.tipOptions" type="object">提示框选项</param>
        var defaultArgs = {
            ajaxSubmitOptions: {
                success: function (resultState, statusText, xhr) {
                    $.hideLoading(this.loadingOptions);
                    if (resultState) {
                        if (resultState.stateCode == 200) {
                            if (this.onSuccessFront && typeof (this.onSuccessFront) == "function") {
                                this.onSuccessFront(resultState, statusText, xhr);
                            }
                            if (this.onSuccess && typeof (this.onSuccess) == "function") {
                                this.onSuccess(resultState, statusText, xhr);
                            }
                            var defaultTipOptions = { msg: resultState.msg };
                            var finalTipOptions = $.extend(true, defaultTipOptions, args.tipOptions);
                            $.showTip(finalTipOptions);
                            if (this.onSuccessBack && typeof (this.onSuccessBack) == "function") {
                                this.onSuccessBack(resultState, statusText, xhr);
                            }
                        } else if (resultState.stateCode == 500) {
                            $.showAlert({message: "系统错误"});
                        } else {
                            // 显示表单验证结果
                            if (!(args && args.ajaxSubmitOptions && args.ajaxSubmitOptions.notShowFormValidationResult)){
                                $.showFormValidationResult({form: args.form, resultState: resultState});
                            }
                            // 显示错误信息
                            if (resultState.msg && resultState.msg != ""){
                                $.showAlert({message: resultState.msg});
                            }
                        }
                    } else {
                        $.showAlert({message: "系统错误"});
                    }
                },
                error: function (XMLHttpRequest, textStatus, errorThrown) {
                    $.hideLoading(this.loadingOptions);
                }
            },
        };
        var finalArgs = $.extend(true, defaultArgs, args);
        var defaultAjaxSubmitOptions = {
            beforeSubmit: function () {
                var isValid = $.getJqObj(finalArgs.form).valid();
                if (isValid) {
                    $.showLoading(finalArgs.loadingOptions);
                }
                return isValid;
            }
        };
        finalArgs.ajaxSubmitOptions = $.extend(true, defaultAjaxSubmitOptions, finalArgs.ajaxSubmitOptions);
        var jqForm = $.getJqObj(finalArgs.form);
        jqForm.ajaxSubmit(finalArgs.ajaxSubmitOptions);
    },

    ajaxSubmitClose: function (args) {
        ///<summary>Ajax提交并关闭</summary>
        ///<param name="args.form" type="string/HTMLElement/Object">表单</param>
        ///<param name="args.ajaxSubmitOptions" type="object">ajaxt提交表单选项，由jquery.form的ajaxSubmit选项扩展，可接受全部jquery.form的ajaxSubmit选项</param>
        ///<param name="args.ajaxSubmitOptions.success" type="function">提交成功回调方法</param>
        ///<param name="args.ajaxSubmitOptions.onSuccess" type="function">提交成功回调方法中执行方法</param>
        ///<param name="args.ajaxSubmitOptions.onSuccessFront" type="function">提交成功回调方法中最开始执行方法</param>
        ///<param name="args.ajaxSubmitOptions.onSuccessBack" type="function">提交成功回调方法中最后执行方法</param>
        ///<param name="args.closeOptions" type="object">关闭选项</param>
        ///<param name="args.closeOptions.container" type="function">关闭容器</param>
        ///<param name="args.closeOptions.beforeClose" type="function">关闭前回调</param>
        ///<param name="args.closeOptions.afterClose" type="function">关闭后回调</param>
        var defaultCloseOptions = {
            container: wysharpDefaultModalContainerSelector
        };
        args.closeOptions = $.extend(true, defaultCloseOptions, args.closeOptions);
        var defaultArgs = {
            ajaxSubmitOptions: {
                onSuccess: function () {
                    if (args.closeOptions && args.closeOptions.beforeClose && typeof (args.closeOptions.beforeClose) == "function") {
                        args.closeOptions.beforeClose();
                    }
                    var jqContainer = $.getJqObj(args.closeOptions.container);
                    jqContainer.modal('hide');
                    if (args.closeOptions && args.closeOptions.afterClose && typeof (args.closeOptions.afterClose) == "function") {
                        args.closeOptions.afterClose();
                    }
                }
            }
        };
        var finalArgs = $.extend(true, defaultArgs, args);
        $.ajaxValSubmit(finalArgs);
    },

    ajaxSubmitRefresh: function (args) {
        ///<summary>Ajax提交并刷新</summary>
        ///<param name="args.form" type="string/HTMLElement/Object">表单</param>
        ///<param name="args.ajaxSubmitOptions" type="object">ajaxt提交表单选项，由jquery.form的ajaxSubmit选项扩展，可接受全部jquery.form的ajaxSubmit选项</param>
        ///<param name="args.ajaxSubmitOptions.success" type="function">提交成功回调方法</param>
        ///<param name="args.ajaxSubmitOptions.onSuccess" type="function">提交成功回调方法中执行方法</param>
        ///<param name="args.ajaxSubmitOptions.onSuccessFront" type="function">提交成功回调方法中最开始执行方法</param>
        ///<param name="args.ajaxSubmitOptions.onSuccessBack" type="function">提交成功回调方法中最后执行方法</param>
        ///<param name="args.refreshOptions" type="object">刷新选项</param>
        ///<param name="args.refreshOptions.refresh" type="function">刷新方法</param>
        ///<param name="args.refreshOptions.beforeRefresh" type="function">刷新前回调</param>
        ///<param name="args.refreshOptions.afterRefresh" type="function">刷新后回调</param>
        var defaultRefreshOptions = {
            refresh: function () {
                if (search && typeof (search) == "function") {
                    search();
                }
            }
        };
        args.refreshOptions = $.extend(true, defaultRefreshOptions, args.refreshOptions);
        var defaultArgs = {
            ajaxSubmitOptions: {
                onSuccess: function () {
                    if (args.refreshOptions && args.refreshOptions.beforeRefresh && typeof (args.refreshOptions.beforeRefresh) == "function") {
                        args.refreshOptions.beforeRefresh();
                    }
                    args.refreshOptions.refresh();
                    if (args.refreshOptions && args.refreshOptions.afterRefresh && typeof (args.refreshOptions.afterRefresh) == "function") {
                        args.refreshOptions.afterRefresh();
                    }
                }
            }
        };
        var finalArgs = $.extend(true, defaultArgs, args);
        $.ajaxValSubmit(finalArgs);
    },

    ajaxSubmitCloseRefresh: function (args) {
        ///<summary>Ajax提交、关闭、刷新</summary>
        ///<param name="args.form" type="string/HTMLElement/Object">表单</param>
        ///<param name="args.ajaxSubmitOptions" type="object">ajaxt提交表单选项，由jquery.form的ajaxSubmit选项扩展，可接受全部jquery.form的ajaxSubmit选项</param>
        ///<param name="args.ajaxSubmitOptions.success" type="function">提交成功回调方法</param>
        ///<param name="args.ajaxSubmitOptions.onSuccess" type="function">提交成功回调方法中执行方法</param>
        ///<param name="args.ajaxSubmitOptions.onSuccessFront" type="function">提交成功回调方法中最开始执行方法</param>
        ///<param name="args.ajaxSubmitOptions.onSuccessBack" type="function">提交成功回调方法中最后执行方法</param>
        ///<param name="args.closeOptions" type="object">关闭选项</param>
        ///<param name="args.closeOptions.container" type="function">关闭容器</param>
        ///<param name="args.refreshOptions" type="object">刷新选项</param>
        ///<param name="args.refreshOptions.refresh" type="function">刷新方法</param>
        ///<param name="args.closeRefreshOptions.beforeAction" type="function">前置方法</param>
        ///<param name="args.closeRefreshOptions.afterAction" type="function">后置方法</param>
        var defaultCloseOptions = {
            container: wysharpDefaultModalContainerSelector
        };
        args.closeOptions = $.extend(true, defaultCloseOptions, args.closeOptions);
        
        var defaultRefreshOptions = {
            refresh: function () {
                var btnSearch = $.getJqObj("#btnSearch");
                if (btnSearch && btnSearch.length > 0) {
                    btnSearch.click();
                } else if (typeof (search) == "function") {
                    search();
                }
            }
        };
        args.refreshOptions = $.extend(true, defaultRefreshOptions, args.refreshOptions);
        
        var defaultArgs = {
            ajaxSubmitOptions: {
                onSuccess: function () {
                    if (args.closeRefreshOptions && args.closeRefreshOptions.beforeAction && typeof (args.closeRefreshOptions.beforeAction) == "function") {
                        args.closeRefreshOptions.beforeAction();
                    }
                    var jqContainer = $.getJqObj(args.closeOptions.container);
                    jqContainer.modal('hide');
                    args.refreshOptions.refresh();
                    if (args.closeRefreshOptions && args.closeRefreshOptions.afterAction && typeof (args.closeRefreshOptions.afterAction) == "function") {
                        args.closeRefreshOptions.afterAction();
                    }
                }
            }
        };
        var finalArgs = $.extend(true, defaultArgs, args);
        
        $.ajaxValSubmit(finalArgs);
    },
    
    functionWithConfirm: function (args) {
        ///<summary>带有确认取消的动作</summary>
        ///<param name="args" type="Object">参数对象</param>
        ///<param name="args.func" type="function">确认后执行的方法</param>
        ///<param name="args.funcArgs" type="function">确认后执行方法的参数</param>
        ///<param name="args.ctrlOptions" type="Object">控件参数对象,开源控件（Bootbox）的参数</param>
        var defaultArgs = {
            ctrlOptions: {
                title: "提示信息",
                message: "确认吗？",
                size: "small",
                buttons: {
                    confirm: {
                        label: '是',
                        className: 'btn-success'
                    },
                    cancel: {
                        label: '否',
                        className: 'btn-default'
                    }
                },
                callback: function (result) {
                    if (result){
                        if (typeof (args.func) == "function") {
                            args.func(args.funcArgs);
                        }
                    }
                }
            }
        };
        var finalArgs = $.extend(true, defaultArgs, args);
        bootbox.confirm(finalArgs.ctrlOptions);
    },

    delWithConfirm: function (args) {
        ///<summary>带有确认取消的删除</summary>
        ///<param name="args" type="Object">参数对象</param>
        ///<param name="args.sender" type="string/HTMLElement/Object">触发控件</param>
        ///<param name="args.func" type="function">确认后执行的方法</param>
        ///<param name="args.funcArgs" type="function">确认后执行方法的参数</param>
        ///<param name="args.ctrlOptions" type="Object">控件参数对象,开源控件（Bootbox）的参数</param>
        var defaultArgs = {
            ctrlOptions: {
                message: "确认删除吗？",
            }
        };
        var finalArgs = $.extend(true, defaultArgs, args);
        $.functionWithConfirm(finalArgs);
    },

    showAlert: function (args) {
        ///<summary>提示框</summary>
        ///<param name="args" type="Object">参数对象</param>
        ///<param name="args.message" type="string">提示信息</param>
        ///<param name="args.func" type="function">确认后执行的方法</param>
        ///<param name="args.funcArgs" type="function">确认后执行方法的参数</param>
        ///<param name="args.ctrlOptions" type="Object">控件参数对象,开源控件（Bootbox）的参数</param>
        var defaultArgs = {
            ctrlOptions: {
                title: "提示信息",
                size: "small",
                message: args.message,
                callback: function () {
                    if (typeof (args.func) == "function") {
                        args.func(args.funcArgs);
                    }
                }
            }
        };
        var finalArgs = $.extend(true, defaultArgs, args);
        bootbox.alert(finalArgs.ctrlOptions);
    },

    selectTree: function (args) {
        ///<summary>下拉树</summary>
        ///<param name="args" type="Object">参数对象</param>
        ///<param name="args.container" type="string/HTMLElement/Object">树形控件容器</param>
        ///<param name="args.sender" type="string/HTMLElement/Object">触发元素</param>
        ///<param name="args.pinTo" type="string/HTMLElement/Object">下拉框固定参照元素</param>
        ///<param name="args.valueCtrl" type="string/HTMLElement/Object">值控件，默认会将选中的ID存入该值控件中</param>
        ///<param name="args.url" type="string/HTMLElement/Object">请求数据URL，如果args.data有值，则该值无效</param>
        ///<param name="args.bootstrapTreeViewOptions" type="string/HTMLElement/Object">Bootstrap TreeView参数</param>
        ///<param name="args.emptyOption" type="Object">空选项</param>
        ///<param name="args.emptyOption.id" type="string">空选项ID值</param>
        ///<param name="args.emptyOption.text" type="string">空选项文本</param>
        var defaultArgs = {
            sender: $.getJqObj(args.container).parent().children('button').first(),
            pinTo: $.getJqObj(args.container).parent().children('button').first(),
            valueCtrl: $.getJqObj(args.container).parent().children('input[type="hidden"]').first(),
            emptyOption: { id: '', text: '' }
        };
        var finalArgs = $.extend(true, defaultArgs, args);

        var container = $.getJqObj(finalArgs.container);

        var funcOnNodeSelected = function(event, node) {
            $.getJqObj(finalArgs.pinTo).val(node.text);
            var pinTo = $.getJqObj(finalArgs.pinTo);
            var reg = /<("[^"]*"|'[^']*'|[^'">])*>[\s\S]*<\/[\s\S]*>/;
            var text = pinTo.html().replace(reg, '').trim();
            var innerHtml = pinTo.html().replace(text, '').trim();
            $.getJqObj(finalArgs.pinTo).html(node.text + innerHtml);
            $.getJqObj(finalArgs.valueCtrl).val(node.id);
            container.hide();
        };

        var defaultBootstrapTreeViewOptions = {
            showTags: true,
            onNodeSelected: funcOnNodeSelected
        }
        var finalBootstrapTreeViewOptions = finalBootstrapTreeViewOptions = $.extend(true, defaultBootstrapTreeViewOptions, finalArgs.bootstrapTreeViewOptions);

        if (finalArgs.bootstrapTreeViewOptions && finalArgs.bootstrapTreeViewOptions.data){
            container.treeview(finalBootstrapTreeViewOptions);
            if (finalArgs.emptyOption && finalBootstrapTreeViewOptions && finalBootstrapTreeViewOptions.data){
                finalBootstrapTreeViewOptions.data.unshift(finalArgs.emptyOption);
            }
        } else if (finalArgs.url){
            $.ajax({
                type : "get",
                url : finalArgs.url,
                success : function(returnData) {
                    if (returnData && !returnData.stateCode){
                        returnData.unshift(finalArgs.emptyOption);
                    }
                    finalBootstrapTreeViewOptions.data = returnData;
                    container.treeview(finalBootstrapTreeViewOptions);
                    var selectedNodes = container.treeview('getSelected');
                    if (selectedNodes && selectedNodes.length > 0){
                        funcOnNodeSelected(null, selectedNodes[0]);
                        function expandRecursively(currentNode){
                            var parentNode = container.treeview('getParent', currentNode);
                            if (!parentNode || parentNode instanceof jQuery){
                                return;
                            }
                            container.treeview('expandNode', parentNode);
                            expandRecursively(parentNode);
                        }
                        expandRecursively(selectedNodes[0]);
                    }
                },
                error : function() {
                    $.showTip({ msg: "TreeView数据请求出错" });
                }
            });
        }

        if (!container.hasClass("wysharp-select-tree")){
            container.addClass("wysharp-select-tree");
        }
        container.pinBottom({target: finalArgs.pinTo, setInterval: true});
        container.hover(function(){
        }, function(){
            container.hide();
        });

        var sender = $.getJqObj(finalArgs.sender);
        sender.click(function() {
            container.toggle();
        });
        sender.blur(function () {
            if(!container.is(':hover')){
                container.hide();
            }
        });
    },

    showFormValidationResult: function (args) {
        ///<summary>显示表单验证结果（根据后台返回的ResultState对象）</summary>
        ///<param name="args" type="Object">参数对象</param>
        ///<param name="args.form" type="string/HTMLElement/Object">表单form</param>
        ///<param name="args.resultState" type="function">结果状态，后台返回</param>
        var jqForm = $.getJqObj(args.form);
        jqForm.find(".form-group").removeClass("has-error").removeClass("has-success").addClass("has-success");
        jqForm.find(".help-block").text("");
        if (args.resultState.data){
            for(var key in args.resultState.data)
            {
                /*var formCtrl = jqForm.find('*[name="' + key + '"]');
                if (!formCtrl || formCtrl.length == 0){
                    continue;
                }
                var formGroup = formCtrl.closest(".form-group");
                if (formGroup && formGroup.length > 0){
                    formGroup.removeClass("has-success").removeClass("has-error").addClass("has-error");
                    var helpBlock = formGroup.find(".help-block");
                    if (helpBlock && helpBlock.length > 0){
                        helpBlock.text(args.resultState.data[key]);
                    }
                }*/
                $.showFormFieldValidationResult({field: key, msg: args.resultState.data[key], form: jqForm});
            }
        }
    },

    showFormFieldValidationResult: function (args) {
        ///<summary>显示表单看控件验证结果</summary>
        ///<param name="args" type="Object">参数对象</param>
        ///<param name="args.field" type="string/HTMLElement/Object">表单控件</param>
        ///<param name="args.msg" type="string">验证消息</param>
        ///<param name="args.form" type="string/HTMLElement/Object">表单form，仅当args.field是string时需要</param>

        var formCtrl;
        if (typeof (args.field) == "string"){
            var jqForm = $.getJqObj(args.form);
            formCtrl = jqForm.find('*[name="' + args.field + '"]');
        }else {
            formCtrl = $.getJqObj(args.field);
        }
        if (!formCtrl || formCtrl.length == 0){
            return;
        }
        var formGroup = formCtrl.closest(".form-group");
        if (formGroup && formGroup.length > 0){
            formGroup.removeClass("has-success").removeClass("has-error").addClass("has-error");
            var helpBlock = formGroup.find(".help-block");
            if (helpBlock && helpBlock.length > 0){
                helpBlock.text(args.msg);
            }
        }
    },

    removeFormValidationStyle: function (args) {
        ///<summary>移除表单验证样式</summary>
        ///<param name="args" type="Object">参数对象</param>
        ///<param name="args.form" type="string/HTMLElement/Object">表单form</param>

        var jqForm = $.getJqObj(args.form);
        jqForm.find(".form-group").removeClass("has-error").removeClass("has-success");
        jqForm.find(".help-block").text("");
    }
});

$.fn.extend({
    renderPartial: function (args) {
        ///<summary>渲染部分视图</summary>
        ///<param name="args" type="Object"></param>
        ///<param name="args.url" type="string">请求URL</param>
        ///<param name="args.data" type="Object">请求数据</param>
        ///<param name="args.onFinished" type="function">结束事件</param>
        ///<param name="args.loadingOptions" type="object">Loading选项</param>
        ///<param name="args.tipOptions" type="object">提示框选项</param>
        ///<param name="args.ajaxOptions" type="object">jquery ajax选项</param>
        args.container = this;
        $.renderPartial(args);
    },
    
    popPartial: function (args) {
        ///<summary>弹出部分视图</summary>
        ///<param name="args.url" type="string">请求URL</param>
        ///<param name="args.data" type="Object">请求数据</param>
        ///<param name="args.onFinished" type="function">结束事件</param>
        ///<param name="args.size" type="string/Object">尺寸。参数类型为string时，传递WySharpSize枚举；参数类型为Object时，传递{width: [value], height: [value]}</param>
        args.container = this;
        $.popPartial(args);
    },

    showTip: function (args) {
        ///<summary>弹出提示框</summary>
        ///<param name="args.msg" type="string">提示信息</param>
        var sender = this;
        var finalArgs = $.extend(true, args, { container: sender });
        $.showTip(finalArgs);
    },

    ajaxValSubmit: function (args) {
        ///<summary>带有Bootstrap样式jquery.validate验证的ajaxSubmit</summary>
        ///<param name="args.form" type="string/HTMLElement/Object">表单</param>
        ///<param name="args.ajaxSubmitOptions" type="object">jquery.form的ajaxSubmit选项</param>
        ///<param name="args.ajaxSubmitOptions.success" type="function">提交成功回调方法</param>
        ///<param name="args.ajaxSubmitOptions.onSuccess" type="function">提交成功回调方法中执行方法</param>
        var sender = this;
        var finalArgs = $.extend(true, args, { form: sender });
        $.ajaxValSubmit(finalArgs);
    },

    ajaxSubmitClose: function (args) {
        ///<summary>Ajax提交并关闭</summary>
        ///<param name="args.form" type="string/HTMLElement/Object">表单</param>
        ///<param name="args.ajaxSubmitOptions" type="object">ajaxt提交表单选项，由jquery.form的ajaxSubmit选项扩展，可接受全部jquery.form的ajaxSubmit选项</param>
        ///<param name="args.ajaxSubmitOptions.success" type="function">提交成功回调方法</param>
        ///<param name="args.ajaxSubmitOptions.onSuccess" type="function">提交成功回调方法中执行方法</param>
        ///<param name="args.ajaxSubmitOptions.onSuccessFront" type="function">提交成功回调方法中最开始执行方法</param>
        ///<param name="args.ajaxSubmitOptions.onSuccessBack" type="function">提交成功回调方法中最后执行方法</param>
        ///<param name="args.closeOptions" type="object">关闭选项</param>
        ///<param name="args.closeOptions.container" type="function">关闭容器</param>
        ///<param name="args.closeOptions.beforeClose" type="function">关闭前回调</param>
        ///<param name="args.closeOptions.afterClose" type="function">关闭后回调</param>
        var sender = this;
        var finalArgs = $.extend(true, args, { form: sender });
        $.ajaxSubmitClose(finalArgs);
    },

    ajaxSubmitRefresh: function (args) {
        ///<summary>Ajax提交并刷新</summary>
        ///<param name="args.form" type="string/HTMLElement/Object">表单</param>
        ///<param name="args.ajaxSubmitOptions" type="object">ajaxt提交表单选项，由jquery.form的ajaxSubmit选项扩展，可接受全部jquery.form的ajaxSubmit选项</param>
        ///<param name="args.ajaxSubmitOptions.success" type="function">提交成功回调方法</param>
        ///<param name="args.ajaxSubmitOptions.onSuccess" type="function">提交成功回调方法中执行方法</param>
        ///<param name="args.ajaxSubmitOptions.onSuccessFront" type="function">提交成功回调方法中最开始执行方法</param>
        ///<param name="args.ajaxSubmitOptions.onSuccessBack" type="function">提交成功回调方法中最后执行方法</param>
        ///<param name="args.refreshOptions" type="object">刷新选项</param>
        ///<param name="args.refreshOptions.refresh" type="function">刷新方法</param>
        ///<param name="args.refreshOptions.beforeRefresh" type="function">刷新前回调</param>
        ///<param name="args.refreshOptions.afterRefresh" type="function">刷新后回调</param>
        var sender = this;
        var finalArgs = $.extend(true, args, { form: sender });
        $.ajaxSubmitRefresh(finalArgs);
    },

    ajaxSubmitCloseRefresh: function (args) {
        ///<summary>Ajax提交、关闭、刷新</summary>
        ///<param name="args.form" type="string/HTMLElement/Object">表单</param>
        ///<param name="args.ajaxSubmitOptions" type="object">ajaxt提交表单选项，由jquery.form的ajaxSubmit选项扩展，可接受全部jquery.form的ajaxSubmit选项</param>
        ///<param name="args.ajaxSubmitOptions.success" type="function">提交成功回调方法</param>
        ///<param name="args.ajaxSubmitOptions.onSuccess" type="function">提交成功回调方法中执行方法</param>
        ///<param name="args.ajaxSubmitOptions.onSuccessFront" type="function">提交成功回调方法中最开始执行方法</param>
        ///<param name="args.ajaxSubmitOptions.onSuccessBack" type="function">提交成功回调方法中最后执行方法</param>
        ///<param name="args.closeOptions" type="object">关闭选项</param>
        ///<param name="args.closeOptions.container" type="function">关闭容器</param>
        ///<param name="args.refreshOptions" type="object">刷新选项</param>
        ///<param name="args.refreshOptions.refresh" type="function">刷新方法</param>
        ///<param name="args.closeRefreshOptions.beforeAction" type="function">前置方法</param>
        ///<param name="args.closeRefreshOptions.afterAction" type="function">后置方法</param>
        var sender = this;
        var finalArgs = $.extend(true, args, { form: sender });
        $.ajaxSubmitCloseRefresh(finalArgs);
    },

    functionWithConfirm: function (args) {
        ///<summary>带有确认取消的动作</summary>
        ///<param name="args" type="Object">参数对象</param>
        ///<param name="args.confirmFunc" type="function">确认后执行的方法</param>
        ///<param name="args.confirmFuncArgs" type="function">确认后执行方法的参数</param>
        ///<param name="args.bsConfirmationOptions" type="Object">参数对象,bs-confirmation.js的参数</param>
        var sender = this;
        var finalArgs = $.extend(true, args, { sender: sender });
        $.functionWithConfirm(finalArgs);
    },
    
    delWithConfirm: function (args) {
        ///<summary>带有确认取消的删除</summary>
        ///<param name="args" type="Object">参数对象</param>
        ///<param name="args.confirmFunc" type="function">确认后执行的方法</param>
        ///<param name="args.confirmFuncArgs" type="function">确认后执行方法的参数</param>
        ///<param name="args.bsConfirmationOptions" type="Object">参数对象,bs-confirmation.js的参数</param>
        var sender = this;
        var finalArgs = $.extend(true, args, { sender: sender });
        $.delWithConfirm(finalArgs);
    },

    selectTree: function (args) {
        ///<summary>带有确认取消的删除</summary>
        ///<param name="args" type="Object">参数对象</param>
        ///<param name="args.sender" type="string/HTMLElement/Object">触发元素</param>
        ///<param name="args.pinTo" type="string/HTMLElement/Object">下拉框固定参照元素</param>
        ///<param name="args.data" type="string/HTMLElement/Object">数据</param>
        ///<param name="args.url" type="string/HTMLElement/Object">请求数据URL，如果args.data有值，则该值无效</param>
        var container = this
        var finalArgs = $.extend(true, args, { container: container });
        $.selectTree(finalArgs);
    },

    showFormValidationResult: function (args) {
        ///<summary>显示表单验证结果（根据后台返回的ResultState对象）</summary>
        ///<param name="args" type="Object">参数对象</param>
        ///<param name="args.form" type="string/HTMLElement/Object">表单form</param>
        ///<param name="args.resultState" type="function">结果状态，后台返回</param>
        var form = this
        var finalArgs = $.extend(true, args, { form: form });
        $.showFormValidationResult(finalArgs);
    },

    removeFormValidationStyle: function (args) {
        ///<summary>移除表单验证样式</summary>
        ///<param name="args" type="Object">参数对象</param>
        ///<param name="args.form" type="string/HTMLElement/Object">表单form</param>

        var form = this
        var finalArgs = $.extend(true, args, { form: form });
        $.removeFormValidationStyle(finalArgs);
    }
});

