var jQuery_formValidator_initConfig;
(function($) {

    $.formValidator =
{
    //各种校验方式支持的控件类型
    sustainType: function(id, setting) {
        var elem = $("#" + id).get(0);
        var srcTag = elem.tagName;
        var stype = elem.type;
        switch (setting.validatetype) {
            case "InitValidator":
                return true;
            case "InputValidator":
                if (srcTag == "INPUT" || srcTag == "TEXTAREA" || srcTag == "SELECT") {
                    return true;
                } else {
                    return false;
                }
            case "CompareValidator":
                if (srcTag == "INPUT" || srcTag == "TEXTAREA") {
                    if (stype == "checkbox" || stype == "radio") {
                        return false;
                    } else {
                        return true;
                    }
                }
                return false;
            case "AjaxValidator":
                if (stype == "text" || stype == "textarea" || stype == "file" || stype == "password" || stype == "select-one") {
                    return true;
                } else {
                    return false;
                }
            case "RegexValidator":
                if (srcTag == "INPUT" || srcTag == "TEXTAREA") {
                    if (stype == "checkbox" || stype == "radio") {
                        return false;
                    } else {
                        return true;
                    }
                }
                return false;
            case "FunctionValidator":
                return true;
        }
    },

    initConfig: function(controlOptions) {
        var settings =
		{
		    debug: false,
		    validatorgroup: "1",
		    alertmessage: false,
		    validobjectids: "",
		    forcevalid: false,
		    onsuccess: function() { return true; },
		    onerror: function() { },
		    submitonce: false,
		    formid: "",
		    autotip: false,
		    tidymode: false,
		    errorfocus: true,
		    wideword: true
		};
        controlOptions = controlOptions || {};
        $.extend(settings, controlOptions);
        //如果是精简模式，发生错误的时候，第一个错误的控件就不获得焦点
        if (settings.tidymode) { settings.errorfocus = false };
        if (settings.formid != "") { $("#" + settings.formid).submit(function() { return $.formValidator.pageIsValid("1"); }) };
        if (jQuery_formValidator_initConfig == null) { jQuery_formValidator_initConfig = new Array(); }
        jQuery_formValidator_initConfig.push(settings);
    },

    //如果validator对象对应的element对象的validator属性追加要进行的校验。
    appendValid: function(id, setting) {
        //如果是各种校验不支持的类型，就不追加到。返回-1表示没有追加成功
        if (!$.formValidator.sustainType(id, setting)) return -1;
        var srcjo = $("#" + id).get(0);
        //重新初始化
        if (setting.validatetype == "InitValidator" || srcjo.settings == undefined) { srcjo.settings = new Array(); }
        var len = srcjo.settings.push(setting);
        srcjo.settings[len - 1].index = len - 1;
        return len - 1;
    },

    //如果validator对象对应的element对象的validator属性追加要进行的校验。
    getInitConfig: function(validatorgroup) {
        if (jQuery_formValidator_initConfig != null) {
            for (i = 0; i < jQuery_formValidator_initConfig.length; i++) {
                if (validatorgroup == jQuery_formValidator_initConfig[i].validatorgroup) {
                    return jQuery_formValidator_initConfig[i];
                }
            }
        }
        return null;
    },

    //触发每个控件上的各种校验
    triggerValidate: function(returnObj) {
        switch (returnObj.setting.validatetype) {
            case "InputValidator":
                $.formValidator.inputValid(returnObj);
                break;
            case "CompareValidator":
                $.formValidator.compareValid(returnObj);
                break;
            case "AjaxValidator":
                $.formValidator.ajaxValid(returnObj);
                break;
            case "RegexValidator":
                $.formValidator.regexValid(returnObj);
                break;
            case "FunctionValidator":
                $.formValidator.functionValid(returnObj);
                break;
        }
    },

    //设置显示信息
    setTipState: function(elem, showclass, showmsg) {
        var setting0 = elem.settings[0];
        var initConfig = $.formValidator.getInitConfig(setting0.validatorgroup);
        var tip = $("#" + setting0.tipid);
        if (showmsg == null || showmsg == "") {
            tip.hide();
        }
        else {
            if (initConfig.tidymode) {
                //显示和保存提示信息
                $("#fv_content").html(showmsg);
                elem.Tooltip = showmsg;
                if (showclass != "onError") { tip.hide(); }
            }
            tip.removeClass();
            tip.addClass(showclass);
            tip.html(showmsg);
        }
    },

    resetTipState: function(validatorgroup) {
        var initConfig = $.formValidator.getInitConfig(validatorgroup);
        $(initConfig.validobjectids).each(function() {
            $.formValidator.setTipState(this, "onShow", this.settings[0].onshow);
        });
    },

    //设置错误的显示信息
    setFailState: function(tipid, showmsg) {
        var tip = $("#" + tipid);
        tip.removeClass();
        tip.addClass("onError");
        tip.html(showmsg);
    },

    //根据单个对象,正确:正确提示,错误:错误提示
    showMessage: function(returnObj) {
        var id = returnObj.id;
        var elem = $("#" + id).get(0);
        var isvalid = returnObj.isvalid;
        var setting = returnObj.setting; //正确:setting[0],错误:对应的setting[i]
        var showmsg = "", showclass = "";
        var settings = $("#" + id).get(0).settings;
        var intiConfig = $.formValidator.getInitConfig(settings[0].validatorgroup);
        if (!isvalid) {
            showclass = "onError";
            if (setting.validatetype == "AjaxValidator") {
                if (setting.lastValid == "") {
                    showclass = "onLoad";
                    showmsg = setting.onwait;
                }
                else {
                    showmsg = setting.onerror;
                }
            }
            else {
                showmsg = (returnObj.errormsg == "" ? setting.onerror : returnObj.errormsg);

            }
            if (intiConfig.alertmessage) {
                var elem = $("#" + id).get(0);
                if (elem.validoldvalue != $(elem).val()) { alert(showmsg); }
            }
            else {
                $.formValidator.setTipState(elem, showclass, showmsg);
            }
        }
        else {
            //验证成功后,如果没有设置成功提示信息,则给出默认提示,否则给出自定义提示;允许为空,值为空的提示
            showmsg = $.formValidator.isEmpty(id) ? setting.onempty : setting.oncorrect;
            $.formValidator.setTipState(elem, "onCorrect", showmsg);
        }
        return showmsg;
    },

    showAjaxMessage: function(returnObj) {
        var setting = returnObj.setting;
        var elem = $("#" + returnObj.id).get(0);
        if (elem.validoldvalue != $(elem).val()) {
            $.formValidator.ajaxValid(returnObj);
        }
        else {
            if (setting.isvalid != undefined && !setting.isvalid) {
                elem.lastshowclass = "onError";
                elem.lastshowmsg = setting.onerror;
            }
            $.formValidator.setTipState(elem, elem.lastshowclass, elem.lastshowmsg);
        }
    },

    //获取指定字符串的长度
    getLength: function(id) {
        var srcjo = $("#" + id);
        var elem = srcjo.get(0);
        sType = elem.type;
        var len = 0;
        switch (sType) {
            case "text":
            case "hidden":
            case "password":
            case "textarea":
            case "file":
                var val = srcjo.val();
                var initConfig = $.formValidator.getInitConfig(elem.settings[0].validatorgroup);
                if (initConfig.wideword) {
                    for (var i = 0; i < val.length; i++) {
                        if (val.charCodeAt(i) >= 0x4e00 && val.charCodeAt(i) <= 0x9fa5) {
                            len += 2;
                        } else {
                            len++;
                        }
                    }
                }
                else {
                    len = val.length;
                }
                break;
            case "checkbox":
            case "radio":
                len = $("input[@type='" + sType + "'][@name='" + srcjo.attr("name") + "'][@checked]").length;
                break;
            case "select-one":
                len = elem.options ? elem.options.selectedIndex : -1;
                break;
            case "select-multiple":
                len = $("select[@name=" + elem.name + "] option[@selected]").length;
                break;
        }
        return len;
    },

    //结合empty这个属性，判断仅仅是否为空的校验情况。
    isEmpty: function(id) {
        if ($("#" + id).get(0).settings[0].empty && $.formValidator.getLength(id) == 0) {
            return true;
        } else {
            return false;
        }
    },

    //对外调用：判断单个表单元素是否验证通过，不带回调函数
    isOneValid: function(id) {
        return $.formValidator.oneIsValid(id, 1).isvalid;
    },

    //验证单个是否验证通过,正确返回settings[0],错误返回对应的settings[i]
    oneIsValid: function(id, index) {
        var returnObj = new Object();
        returnObj.id = id;
        returnObj.ajax = -1;
        returnObj.errormsg = "";       //自定义错误信息
        var elem = $("#" + id).get(0);
        var settings = elem.settings;
        var settingslen = settings.length;
        //只有一个formValidator的时候不检验
        if (settingslen == 1) { settings[0].bind = false; }
        if (!settings[0].bind) { return null; }
        for (var i = 0; i < settingslen; i++) {
            if (i == 0) {
                if ($.formValidator.isEmpty(id)) {
                    returnObj.isvalid = true;
                    returnObj.setting = settings[0];
                    break;
                }
                continue;
            }
            returnObj.setting = settings[i];
            if (settings[i].validatetype != "AjaxValidator") {
                $.formValidator.triggerValidate(returnObj);
            } else {
                returnObj.ajax = i;
            }
            if (!settings[i].isvalid) {
                returnObj.isvalid = false;
                returnObj.setting = settings[i];
                break;
            } else {
                returnObj.isvalid = true;
                returnObj.setting = settings[0];
                if (settings[i].validatetype == "AjaxValidator") break;
            }
        }
        return returnObj;
    },

    //验证所有需要验证的对象，并返回是否验证成功。
    pageIsValid: function(validatorgroup) {
        if (validatorgroup == null || validatorgroup == undefined) { validatorgroup = "1" };
        var isvalid = true;
        var thefirstid = "", thefirsterrmsg;
        var returnObj, setting;
        var error_tip = "^";

        var initConfig = $.formValidator.getInitConfig(validatorgroup);
        var jqObjs = $(initConfig.validobjectids);
        jqObjs.each(function(i, elem) {
            if (elem.settings[0].bind) {
                returnObj = $.formValidator.oneIsValid(elem.id, 1);
                if (returnObj) {
                    var tipid = elem.settings[0].tipid;
                    //校验失败,获取第一个发生错误的信息和ID
                    if (!returnObj.isvalid) {
                        isvalid = false;
                        if (thefirstid == "") {
                            thefirstid = returnObj.id;
                            thefirsterrmsg = (returnObj.errormsg == "" ? returnObj.setting.onerror : returnObj.errormsg)
                        }
                    }
                    //为了解决使用同个TIP提示问题:后面的成功或失败都不覆盖前面的失败
                    if (!initConfig.alertmessage) {
                        if (error_tip.indexOf("^" + tipid + "^") == -1) {
                            if (!returnObj.isvalid) {
                                error_tip = error_tip + tipid + "^";
                            }
                            $.formValidator.showMessage(returnObj);
                        }
                    }
                }
            }
        });
        //成功或失败后，进行回调函数的处理，以及成功后的灰掉提交按钮的功能
        if (isvalid) {
            isvalid = initConfig.onsuccess();
            if (initConfig.submitonce) { $("input[@type='submit']").attr("disabled", true); }
        }
        else {
            var obj = $("#" + thefirstid).get(0);
            initConfig.onerror(thefirsterrmsg, obj);
            if (thefirstid != "" && initConfig.errorfocus) { $("#" + thefirstid).focus(); }
        }
        return !initConfig.debug && isvalid;
    },

    //ajax校验
    ajaxValid: function(returnObj) {
        var id = returnObj.id;
        var srcjo = $("#" + id);
        var elem = srcjo.get(0);
        var settings = elem.settings;
        var setting = settings[returnObj.ajax];
        var ls_url = setting.url;
        if (srcjo.size() == 0 && settings[0].empty) {
            returnObj.setting = settings[0];
            returnObj.isvalid = true;
            $.formValidator.showMessage(returnObj);
            setting.isvalid = true;
            return;
        }
        if (setting.addidvalue) {
            var parm = "clientid=" + id + "&" + id + "=" + encodeURIComponent(srcjo.val());
            ls_url = ls_url + (ls_url.indexOf("?") > 0 ? ("&" + parm) : ("?" + parm));
        }
        $.ajax(
		{
		    mode: "abort",
		    type: setting.type,
		    url: ls_url,
		    cache: setting.cache,
		    data: setting.data,
		    async: setting.async,
		    dataType: setting.datatype,
		    success: function(data) {
		        if (setting.success(data)) {
		            $.formValidator.setTipState(elem, "onCorrect", settings[0].oncorrect);
		            setting.isvalid = true;
		        }
		        else {
		            $.formValidator.setTipState(elem, "onError", setting.onerror);
		            setting.isvalid = false;
		        }
		    },
		    complete: function() {
		        if (setting.buttons && setting.buttons.length > 0) { setting.buttons.attr({ "disabled": false }) };
		        setting.complete;
		    },
		    beforeSend: function(xhr) {
		        //再服务器没有返回数据之前，先回调提交按钮
		        if (setting.buttons && setting.buttons.length > 0) { setting.buttons.attr({ "disabled": true }) };
		        var isvalid = setting.beforesend(xhr);
		        if (isvalid) {
		            setting.isvalid = false; 	//如果前面ajax请求成功了，再次请求之前先当作错误处理
		            $.formValidator.setTipState(elem, "onLoad", settings[returnObj.ajax].onwait);
		        }
		        setting.lastValid = "-1";
		        return isvalid;
		    },
		    error: function() {
		        $.formValidator.setTipState(elem, "onError", setting.onerror);
		        setting.isvalid = false;
		        setting.error();
		    },
		    processData: setting.processdata
		});
    },

    //对正则表达式进行校验（目前只针对input和textarea）
    regexValid: function(returnObj) {
        var id = returnObj.id;
        var setting = returnObj.setting;
        var srcTag = $("#" + id).get(0).tagName;
        var elem = $("#" + id).get(0);
        //如果有输入正则表达式，就进行表达式校验
        if (elem.settings[0].empty && elem.value == "") {
            setting.isvalid = true;
        }
        else {
            var regexpress = setting.regexp;
            if (setting.datatype == "enum") { regexpress = eval("regexEnum." + regexpress); }
            if (regexpress == undefined || regexpress == "") {
                setting.isvalid = false;
                return;
            }
            setting.isvalid = (new RegExp(regexpress, setting.param)).test($("#" + id).val());
        }
    },

    //函数校验。返回true/false表示校验是否成功;返回字符串表示错误信息，校验失败;如果没有返回值表示处理函数，校验成功
    functionValid: function(returnObj) {
        var id = returnObj.id;
        var setting = returnObj.setting;
        var srcjo = $("#" + id);
        var lb_ret = setting.fun(srcjo.val(), srcjo.get(0));
        if (lb_ret != undefined) {
            if (typeof lb_ret == "string") {
                setting.isvalid = false;
                returnObj.errormsg = lb_ret;
            } else {
                setting.isvalid = lb_ret;
            }
        }
    },

    //对input和select类型控件进行校验
    inputValid: function(returnObj) {
        var id = returnObj.id;
        var setting = returnObj.setting;
        var srcjo = $("#" + id);
        var elem = srcjo.get(0);
        var val = srcjo.val();
        var sType = elem.type;
        var len = $.formValidator.getLength(id);
        var empty = setting.empty, emptyerror = false;
        switch (sType) {
            case "text":
            case "hidden":
            case "password":
            case "textarea":
            case "file":
                if (setting.type == "size") {
                    empty = setting.empty;
                    if (!empty.leftempty) {
                        emptyerror = (val.replace(/^[ \s]+/, '').length != val.length);
                    }
                    if (!emptyerror && !empty.rightempty) {
                        emptyerror = (val.replace(/[ \s]+$/, '').length != val.length);
                    }
                    if (emptyerror && empty.emptyerror) { returnObj.errormsg = empty.emptyerror }
                }
            case "checkbox":
            case "select-one":
            case "select-multiple":
            case "radio":
                var lb_go_on = false;
                if (sType == "select-one" || sType == "select-multiple") { setting.type = "size"; }
                var type = setting.type;
                if (type == "size") {		//获得输入的字符长度，并进行校验
                    if (!emptyerror) { lb_go_on = true }
                    if (lb_go_on) { val = len }
                }
                else if (type == "date" || type == "datetime") {
                    var isok = false;
                    if (type == "date") { lb_go_on = isDate(val) };
                    if (type == "datetime") { lb_go_on = isDate(val) };
                    if (lb_go_on) { val = new Date(val); setting.min = new Date(setting.min); setting.max = new Date(setting.max); };
                } else {
                    stype = (typeof setting.min);
                    if (stype == "number") {
                        val = (new Number(val)).valueOf();
                        if (!isNaN(val)) { lb_go_on = true; }
                    }
                    if (stype == "string") { lb_go_on = true; }
                }
                setting.isvalid = false;
                if (lb_go_on) {
                    if (val < setting.min || val > setting.max) {
                        if (val < setting.min && setting.onerrormin) {
                            returnObj.errormsg = setting.onerrormin;
                        }
                        if (val > setting.min && setting.onerrormax) {
                            returnObj.errormsg = setting.onerrormax;
                        }
                    }
                    else {
                        setting.isvalid = true;
                    }
                }
                break;
        }
    },

    compareValid: function(returnObj) {
        var id = returnObj.id;
        var setting = returnObj.setting;
        var srcjo = $("#" + id);
        var desjo = $("#" + setting.desid);
        var ls_datatype = setting.datatype;
        setting.isvalid = false;
        curvalue = srcjo.val();
        ls_data = desjo.val();
        if (ls_datatype == "number") {
            if (!isNaN(curvalue) && !isNaN(ls_data)) {
                curvalue = parseFloat(curvalue);
                ls_data = parseFloat(ls_data);
            }
            else {
                return;
            }
        }
        if (ls_datatype == "date" || ls_datatype == "datetime") {
            var isok = false;
            if (ls_datatype == "date") { isok = (isDate(curvalue) && isDate(ls_data)) };
            if (ls_datatype == "datetime") { isok = (isDateTime(curvalue) && isDateTime(ls_data)) };
            if (isok) {
                curvalue = new Date(curvalue);
                ls_data = new Date(ls_data)
            }
            else {
                return;
            }
        }

        switch (setting.operateor) {
            case "=":
                if (curvalue == ls_data) { setting.isvalid = true; }
                break;
            case "!=":
                if (curvalue != ls_data) { setting.isvalid = true; }
                break;
            case ">":
                if (curvalue > ls_data) { setting.isvalid = true; }
                break;
            case ">=":
                if (curvalue >= ls_data) { setting.isvalid = true; }
                break;
            case "<":
                if (curvalue < ls_data) { setting.isvalid = true; }
                break;
            case "<=":
                if (curvalue <= ls_data) { setting.isvalid = true; }
                break;
        }
    },

    localTooltip: function(e) {
        e = e || window.event;
        var mouseX = e.pageX || (e.clientX ? e.clientX + document.body.scrollLeft : 0);
        var mouseY = e.pageY || (e.clientY ? e.clientY + document.body.scrollTop : 0);
        $("#fvtt").css({ "top": (mouseY + 2) + "px", "left": (mouseX - 40) + "px" });
    }
};

    //每个校验控件必须初始化的
    $.fn.formValidator = function(cs) {
        var setting =
	{
	    validatorgroup: "1",
	    empty: false,
	    submitonce: false,
	    automodify: false,
	    onshow: "请输入内容",
	    onfocus: "请输入内容",
	    oncorrect: "输入正确",
	    onempty: "输入内容为空",
	    defaultvalue: null,
	    bind: true,
	    validatetype: "InitValidator",
	    tipcss:
		{
		    "left": "10px",
		    "top": "1px",
		    "height": "20px",
		    "width": "250px"
		},
	    triggerevent: "blur",
	    forcevalid: false
	};

        //获取该校验组的全局配置信息
        cs = cs || {};
        if (cs.validatorgroup == undefined) { cs.validatorgroup = "1" };
        var initConfig = $.formValidator.getInitConfig(cs.validatorgroup);

        //如果为精简模式，tipcss要重新设置初始值
        if (initConfig.tidymode) { setting.tipcss = { "left": "2px", "width": "22px", "height": "22px", "display": "none"} };

        //先合并整个配置(深度拷贝)
        $.extend(true, setting, cs);

        return this.each(function(e) {
            var jqobj = $(this);
            var setting_temp = {};
            $.extend(true, setting_temp, setting);
            var tip = setting_temp.tipid ? setting_temp.tipid : this.id + "Tip";
            //自动形成TIP
            if (initConfig.autotip) {
                //获取层的ID、相对定位控件的ID和坐标
                if ($("body [id=" + tip + "]").length == 0) {
                    aftertip = setting_temp.relativeid ? setting_temp.relativeid : this.id;
                    var obj = getTopLeft(aftertip);
                    var y = obj.top;
                    var x = getElementWidth(aftertip) + obj.left;
                    $("<div class='formValidateTip'></div>").appendTo($("body")).css({ left: x + "px", top: y + "px" }).prepend($('<div id="' + tip + '"></div>').css(setting_temp.tipcss));
                }
                if (initConfig.tidymode) { jqobj.showTooltips() };
            }

            //每个控件都要保存这个配置信息
            setting.tipid = tip;
            $.formValidator.appendValid(this.id, setting);

            //保存控件ID
            var validobjectids = initConfig.validobjectids;
            if (validobjectids.indexOf("#" + this.id + " ") == -1) {
                initConfig.validobjectids = (validobjectids == "" ? "#" + this.id : validobjectids + ",#" + this.id);
            }

            //初始化显示信息
            if (!initConfig.alertmessage) {
                $.formValidator.setTipState(this, "onShow", setting.onshow);
            }

            var srcTag = this.tagName.toLowerCase();
            var stype = this.type;
            var defaultval = setting.defaultvalue;
            //处理默认值
            if (defaultval) {
                jqobj.val(defaultval);
            }

            if (srcTag == "input" || srcTag == "textarea") {
                //注册获得焦点的事件。改变提示对象的文字和样式，保存原值
                jqobj.focus(function() {
                    if (!initConfig.alertmessage) {
                        //保存原来的状态
                        var tipjq = $("#" + tip);
                        this.lastshowclass = tipjq.attr("class");
                        this.lastshowmsg = tipjq.html();
                        $.formValidator.setTipState(this, "onFocus", setting.onfocus);
                    }
                    if (stype == "password" || stype == "text" || stype == "textarea" || stype == "file") {
                        this.validoldvalue = jqobj.val();
                    }
                });
                //注册失去焦点的事件。进行校验，改变提示对象的文字和样式；出错就提示处理
                jqobj.bind(setting.triggerevent, function() {
                    var settings = this.settings;
                    var returnObj = $.formValidator.oneIsValid(this.id, 1);
                    if (returnObj == null) { return; }
                    if (returnObj.ajax >= 0) {
                        $.formValidator.showAjaxMessage(returnObj);
                    }
                    else {
                        var showmsg = $.formValidator.showMessage(returnObj);
                        if (!returnObj.isvalid) {
                            //自动修正错误
                            var auto = setting.automodify && (this.type == "text" || this.type == "textarea" || this.type == "file");
                            if (auto && !initConfig.alertmessage) {
                                alert(showmsg);
                                $.formValidator.setTipState(this, "onShow", setting.onshow);
                            }
                            else {
                                if (initConfig.forcevalid || setting.forcevalid) {
                                    alert(showmsg); this.focus();
                                }
                            }
                        }
                    }
                });
            }
            else if (srcTag == "select") {
                //获得焦点
                jqobj.bind("focus", function() {
                    if (!initConfig.alertmessage) {
                        $.formValidator.setTipState(this, "onFocus", setting.onfocus);
                    }
                });
                //失去焦点
                jqobj.bind("blur", function() { jqobj.trigger("change") });
                //选择项目后触发
                jqobj.bind("change", function() {
                    var returnObj = $.formValidator.oneIsValid(this.id, 1);
                    if (returnObj == null) { return; }
                    if (returnObj.ajax >= 0) {
                        $.formValidator.showAjaxMessage(returnObj);
                    } else {
                        $.formValidator.showMessage(returnObj);
                    }
                });
            }
        });
    };

    $.fn.inputValidator = function(controlOptions) {
        var settings =
	{
	    isvalid: false,
	    min: 0,
	    max: 99999999999999,
	    type: "size",
	    onerror: "输入错误",
	    validatetype: "InputValidator",
	    empty: { leftempty: true, rightempty: true, leftemptyerror: null, rightemptyerror: null },
	    wideword: true
	};
        controlOptions = controlOptions || {};
        $.extend(true, settings, controlOptions);
        return this.each(function() {
            $.formValidator.appendValid(this.id, settings);
        });
    };

    $.fn.compareValidator = function(controlOptions) {
        var settings =
	{
	    isvalid: false,
	    desid: "",
	    operateor: "=",
	    onerror: "输入错误",
	    validatetype: "CompareValidator"
	};
        controlOptions = controlOptions || {};
        $.extend(true, settings, controlOptions);
        return this.each(function() {
            $.formValidator.appendValid(this.id, settings);
        });
    };

    $.fn.regexValidator = function(controlOptions) {
        var settings =
	{
	    isvalid: false,
	    regexp: "",
	    param: "i",
	    datatype: "string",
	    onerror: "输入的格式不正确",
	    validatetype: "RegexValidator"
	};
        controlOptions = controlOptions || {};
        $.extend(true, settings, controlOptions);
        return this.each(function() {
            $.formValidator.appendValid(this.id, settings);
        });
    };

    $.fn.functionValidator = function(controlOptions) {
        var settings =
	{
	    isvalid: true,
	    fun: function() { this.isvalid = true; },
	    validatetype: "FunctionValidator",
	    onerror: "输入错误"
	};
        controlOptions = controlOptions || {};
        $.extend(true, settings, controlOptions);
        return this.each(function() {
            $.formValidator.appendValid(this.id, settings);
        });
    };

    $.fn.ajaxValidator = function(controlOptions) {
        var settings =
	{
	    isvalid: false,
	    lastValid: "",
	    type: "GET",
	    url: "",
	    addidvalue: true,
	    datatype: "html",
	    data: "",
	    async: true,
	    cache: false,
	    beforesend: function() { return true; },
	    success: function() { return true; },
	    complete: function() { },
	    processdata: false,
	    error: function() { },
	    buttons: null,
	    onerror: "服务器校验没有通过",
	    onwait: "正在等待服务器返回数据",
	    validatetype: "AjaxValidator"
	};
        controlOptions = controlOptions || {};
        $.extend(true, settings, controlOptions);
        return this.each(function() {
            $.formValidator.appendValid(this.id, settings);
        });
    };

    $.fn.defaultPassed = function(onshow) {
        return this.each(function() {
            var settings = this.settings;
            for (var i = 1; i < settings.length; i++) {
                settings[i].isvalid = true;
                if (!$.formValidator.getInitConfig(settings[0].validatorgroup).alertmessage) {
                    var ls_style = onshow ? "onShow" : "onCorrect";
                    $.formValidator.setTipState(this, ls_style, settings[0].oncorrect);
                }
            }
        });
    };

    $.fn.unFormValidator = function(unbind) {
        return this.each(function() {
            this.settings[0].bind = !unbind;
            if (unbind) {
                $("#" + this.settings[0].tipid).hide();
            } else {
                $("#" + this.settings[0].tipid).show();
            }
        });
    };

    $.fn.showTooltips = function() {
        if ($("body [id=fvtt]").length == 0) {
            fvtt = $("<div id='fvtt' style='position:absolute;z-index:56002'></div>");
            $("body").append(fvtt);
            fvtt.before("<iframe src='about:blank' class='fv_iframe' scrolling='no' frameborder='0'></iframe>");

        }
        return this.each(function() {
            jqobj = $(this);
            s = $("<span class='top' id=fv_content style='display:block'></span>");
            b = $("<b class='bottom' style='display:block' />");
            this.tooltip = $("<span class='fv_tooltip' style='display:block'></span>").append(s).append(b).css({ "filter": "alpha(opacity:95)", "KHTMLOpacity": "0.95", "MozOpacity": "0.95", "opacity": "0.95" });
            //注册事件
            jqobj.mouseover(function(e) {
                $("#fvtt").append(this.tooltip);
                $("#fv_content").html(this.Tooltip);
                $.formValidator.localTooltip(e);
            });
            jqobj.mouseout(function() {
                $("#fvtt").empty();
            });
            jqobj.mousemove(function(e) {
                $("#fv_content").html(this.Tooltip);
                $.formValidator.localTooltip(e);
            });
        });
    }

})(jQuery);

function getElementWidth(objectId) {
    x = document.getElementById(objectId);
    return x.offsetWidth;
}

function getTopLeft(objectId) {
    obj = new Object();
    o = document.getElementById(objectId);
    oLeft = o.offsetLeft;
    oTop = o.offsetTop;
    while (o.offsetParent != null) {
        oParent = o.offsetParent;
        oLeft += oParent.offsetLeft;
        oTop += oParent.offsetTop;
        o = oParent;
    }
    obj.top = oTop;
    obj.left = oLeft;
    return obj;
}