﻿//----------------------------------------------------------------------//
//                                                                      //
//                          钱文田  2007-12-25                          //
//                                                                      //
//                    页面控件类型、为空验证、XML操作                   //
//                                                                      //
//                  需要外面调用页面引用 Common.js文件                  //
//                                                                      //
//----------------------------------------------------------------------//

var Func = 
{
    /// <summary>
    /// 初始化控件容器中所有控件事件
    /// </summary>
    /// <param name="container">控件容器</param>
    initDataTypeEvent : function(container)
    {
        if (!container)
        {
            // 若容器为空, 设置默认容器为整个页面文档
            container = document.body;
        }

        initChildNodes(container.childNodes);

        /// <summary>
        /// 递归附加控件容器中子控件事件
        /// </summary>
        /// <param name="controls">控件集合</param>
        function initChildNodes(controls)
        {
            for(var i=0; i<controls.length; i++)
            {
                Func.addControlEvent(controls[i]);
                initChildNodes(controls[i].childNodes);
            }
        }
    },

    /// <summary>
    /// 附加控件事件
    /// </summary>
    /// <param name="control">控件对象</param>
    addControlEvent : function(control)
    {
        switch (control.type)
        {
            case "password":
            case "text":
                addEvent(control, "focus", focusEvent);
                addEvent(control, "blur", blurEvent);
                addEvent(control, "keydown", keydownEvent);
                addEvent(control, "keypress", keypressEvent);
                addEvent(control, "keyup", keyupEvent);
//                addEvent(control, "change", changeEvent);
                // qianwt 2008-11-08 如果是数值类型, 向右对齐
                if (isNumType(getAttribute(control, "DataType", true)))
                {
                    control.style.textAlign = "right";
                }
                break;
            case "checkbox":
                addEvent(control, "focus", focusEvent);
                addEvent(control, "blur", blurEvent);
                addEvent(control, "keydown", keydownEvent);
                break;
            case "textarea":
                addEvent(control, "focus", focusEvent);
                addEvent(control, "blur", blurEvent);
                break;
            case "select-one":
            case "select-multiple":
                //addEvent(control, "focus", focusEvent);
                //addEvent(control, "blur", blurEvent);
                addEvent(control, "keydown", keydownEvent);
                break;
            default:
                break;
        };

        function focusEvent(e)
        {
            e = e ? e : event;
            var obj = (e.target ? e.target : e.srcElement);
            if (isNumType(getAttribute(obj, "DataType", true)))
            {
                obj.style.textAlign = "left";
                if (getAttribute(obj, "HasComma", true) == "true")
                {
                    obj.value = removeCommas(obj.value.trim());
                }
                obj.focus();
                obj.select();
            }
            
            Func.showInfo(obj);
        }

//        function changeEvent(e)
//        {
//            e = e ? e : event;
//            var obj = (e.target ? e.target : e.srcElement);
//            Func.showInfo(obj);
//        }

        function blurEvent(e)
        {
            e = e ? e : event;
            var obj = (e.target ? e.target : e.srcElement);
            if (isNumType(getAttribute(obj, "DataType", true)))
            {
                obj.style.textAlign = "right";
                if (getAttribute(obj, "HasComma", true) == "true")
                {
                    obj.value = addCommas(obj.value.trim());
                }
            }
            Func.hideInfo();
        }
        
        function keydownEvent(e)
        {
            e = e ? e : event;
            var obj = (e.target ? e.target : e.srcElement);

            if (e.keyCode == 13)
            {
                // 回车键当成TAB键处理
                if (getAttribute(obj, "AutoTab", true) == "true")
                {
                    if (gIsIE)
                    {
                        e.keyCode = 9;
                    }
                    else if (gIsNS)
                    {
                        // 在网上找了很久, 对于 firefox 改动 e.keyCode 都无效
                        // firefox
                        // var evt = document.createEvent("KeyEvents");
                        // evt.initKeyEvent("keypress", true, true, document.defaultView, e.ctrlKey, e.altKey, e.shiftKey, e.metaKey, 9, 0);
                        // e.target.dispatchEvent(evt);
                        // e.preventDefault();
                    }
                }
                // 回车键执行脚本
                var script = getAttribute(obj, "EnterScript")
                if (script)
                {
                    eval(script);
                }
            }
        }

        function keypressEvent(e)
        {
            e = e ? e : event;
            var obj = (e.target ? e.target : e.srcElement);
//            if (top.__debug)
//            {
//                top.status = "e.keyCode = " + e.keyCode + "; e.charCode = " + e.charCode;
//            }
            // 在 ie 中控制键在 keypress 事件中不触发 
            // 在 firefox 中控制键触发 keypress, 值在 keyCode 上, 而 charCode = 0, 字符的时候是 keyCode = 0, charCode = 键值
            if (gIsNS && e.keyCode) return true;

            // firefox charCode; ie keyCode;
            var keyCode = (e.charCode ? e.charCode : e.keyCode);

            var dt = getAttribute(obj, "DataType", true);

            // 不是数值型, 不用控制
            if (!isNumType(dt)) return true;

            // 字符 0 - 9, 可以
            if (keyCode >= 48 && keyCode <= 57) return true;

            // 若当前是负号键, 当没有负号键可以
            if (keyCode == 45)
            {
                if (obj.value.indexOf("-") != -1)
                {
                    // firefox 有 e.preventDefault 方法, 不用默认处理
                    if (e.preventDefault) e.preventDefault();
                    return false;
                }
                return true;
            }

            // 若当前是小数点, 当没有小数点可以
            if (keyCode == 46)
            {
                // int, num0 不允许有小数点, 已经有小数点也不允许有小数点
                if (dt == "int" || dt == "num0" || obj.value.indexOf(".") != -1)
                {
                    // firefox 有 e.preventDefault 方法, 不用默认处理
                    if (e.preventDefault) e.preventDefault();
                    return false;
                }
                return true;
            }

            // 其它字符不可以
            if (e.preventDefault) e.preventDefault();
            return false;
        }

        function keyupEvent(e)
        {
            e = e ? e : event;
            var obj = (e.target ? e.target : e.srcElement);
            Func.showInfo(obj);
        }
    },

    /// <summary>
    /// 检查容器中控件数据是否有效
    /// </summary>
    /// <param name="container">控件容器</param>
    checkData : function (container)
    {
        if (!container)
        {
            // 若容器为空, 设置默认容器为整个页面文档
            container = document.body;
        }

        // 执行递归检查之前方法
        if (window.checkDataBefore && !window.checkDataBefore())
            return false;

        // 递归检查数据
        if (!initChildNodes(container.childNodes))
            return false;

        // 执行递归检查之后方法
        if (window.checkDataAfter && !window.checkDataAfter())
            return false;

        return true;

        /// <summary>
        /// 递归检查控件数据是否有效
        /// </summary>
        /// <param name="controls">控件集合</param>
        function initChildNodes(controls)
        {
            for(var i=0; i<controls.length; i++)
            {
                if (!Func.checkControlData(controls[i]))
                    return false;

                if (!initChildNodes(controls[i].childNodes))
                    return false;
            }

            return true;
        }
    },

    /// <summary>
    /// 检查控件数据是否有效
    /// </summary>
    /// <param name="control">控件对象</param>
    checkControlData : function (control)
    {
        switch (control.type)
        {
            case "checkbox":
            case "password":
            case "text":
            case "textarea":
                // 判断文本框是否允许空值
                if (getAttribute(control, "AllowEmpty", true) == "false" && control.value.trim() == "")
                {
                    top.MessageBox.show("info", isNull(getAttribute(control, "EmptyErrorMessage")) ? "此项值不能为空, 请输入!" : getAttribute(control, "EmptyErrorMessage"), "", function() { setFocus(control) });
                    return false;
                }
                // 判断文本框的值类型是否正确
                var datatype = getAttribute(control, "datatype");
                if (datatype)
                {
                    var methodName = "is" + datatype.substring(0, 1).toUpperCase() + datatype.substring(1).toLowerCase();
                    if (!eval("removeCommas(control.value.trim())." + methodName + "()"))
                    {
                        top.MessageBox.show("info", isNull(getAttribute(control, "TypeErrorMessage")) ? "此项值类型错误, 请重新输入!" : getAttribute(control, "TypeErrorMessage"), "", function() { setFocus(control) });
                        return false;
                    }
                }
                // 当文本框的值不为空的时候, 检查是否符合正则表达式
                // 由于正则表达式内容大小写有区别, 不能转化成小写
                if (control.value != "" && control.getAttribute("RegExp") && control.value.match(new RegExp(control.getAttribute("RegExp"))) == null)
                {
                    top.MessageBox.show("info", isNull(getAttribute(control, "RegErrorMessage")) ? "此项值输入错误, 请输入!" : getAttribute(control, "RegErrorMessage"), "", function() { setFocus(control) });
                    return false;
                }
                // 检查执行方法
                var execfunc = getAttribute(control, "execfunc");
                if (execfunc)
                {
                    var func = window[execfunc];
                    if (typeof(func) == "function")
                    {
                        try
                        {
                            if (func() == false)
                            {
                                return false;
                            }
                        }
                        catch(e)
                        {
                            if (top.__debug) throw e;
                        }
                    }
                    else
                    {
                        try
                        {
                            var newfunc = Function(execfunc);
                            if (newfunc() == false)
                            {
                                return false;
                            }
                        }
                        catch(e)
                        {
                            if (top.__debug) throw e;
                        }
                    }
                }
                break;
            case "select-one":
                // 判断下拉框是否允许空值
                if (getAttribute(control, "AllowEmpty", true) == "false")
                {
                    var selectedIndex = control.selectedIndex;
                    if (selectedIndex == -1 || control.options[selectedIndex].value == "")
                    {
                        top.MessageBox.show("info", isNull(getAttribute(control, "EmptyErrorMessage")) ? "此项值不能为空, 请选择!" : getAttribute(control, "EmptyErrorMessage"), "", function() { setFocus(control) });
                        return false;
                    }
                }
                // 检查执行方法
                var execfunc = getAttribute(control, "execfunc");
                if (execfunc)
                {
                    var func = window[execfunc];
                    if (typeof(func) == "function")
                    {
                        try
                        {
                            if (func() == false)
                            {
                                return false;
                            }
                        }
                        catch(e)
                        {
                            if (top.__debug) throw e;
                        }
                    }
                    else
                    {
                        try
                        {
                            var newfunc = Function(execfunc);
                            if (newfunc() == false)
                            {
                                return false;
                            }
                        }
                        catch(e)
                        {
                            if (top.__debug) throw e;
                        }
                    }
                }
                break;
            default:
                break;
        };
        return true;

        /// <summary>
        /// 如果可以获得焦点, 让控件获得焦点
        /// </summary>
        /// <param name="control">控件对象</param>
        function setFocus(control)
        {
            control.focus
            try
            {
                control.focus();
                control.select();
            }
            catch(e)
            {
            }
        }
    },
    
    /// <summary>
    /// 显示自定义提醒或者警告
    /// </summary>
    /// <param name="obj">控件</param>
    /// <param name="type">显示类型</param>
    showInfo : function(obj)
    {
        var errorMsg = getErrorMsg(obj);
        if(errorMsg == "")
        {
            // 如果没有错误, 也没有提示, 直接返回, 不用创建提示iframe
            obj.style.backgroundColor = "white";
            if (isNull(getAttribute(obj, "Tipmsg")))
            {
                Func.hideInfo();
                return;
            }
        }
        // 需要显示提示或者错误框架
        var infoObj = $("dialog_func_info");
        if (!infoObj)
        {
            infoObj = createPanel(window, "dialog_func_info", top.ApplicationPath + "/Js/Func.aspx", onloadEvent);
            infoObj.className = "DialogHint";
            return;
        }

        onloadEvent();
        
        function onloadEvent()
        {
            var infoWin = $F("dialog_func_info");

            // 不知为何 在ie7 中有时已经触发了onload
            // 但是页面 document.body 对象为null
            // 所以在此处加上判断, 如果为null, 延时直至可以访问对象为止
            if (!infoWin.document.body)
            {
                setTimeout(onloadEvent, 50);
                return;
            }

            if (errorMsg != "")
            {
                // 显示错误
                $S(infoObj, true);
                $S($("img_warning", infoWin), false);
                $S($("img_error", infoWin), true);
                $("span_info", infoWin).innerHTML = errorMsg;
                obj.style.backgroundColor = "yellow";
            }
            else
            {
                // 显示提示
                $S(infoObj, true);
                $S($("img_warning", infoWin), true);
                $S($("img_error", infoWin), false);
                $("span_info", infoWin).innerHTML = getAttribute(obj, "Tipmsg");
            }

            // 计算框架左上角位置
            var pt = getPosition(obj);
            infoObj.style.top = pt.top + obj.offsetHeight
            infoObj.style.left = pt.left;
            // 框架中提示框DIV的实际高度、宽带来设置框架高度、宽度
            var tipMsg = $("TipMsg", infoWin);
            infoObj.style.width = tipMsg.offsetWidth;
            infoObj.style.height = tipMsg.offsetHeight;
        }
    },
    
    /// <summary>
    /// 隐藏自定义提醒或者警告
    /// </summary>
    hideInfo : function ()
    {
        $S($("dialog_func_info"), false);
    },

    /// <summary>
    /// 禁用容器中控件的（text改成只读、checkbox、不让单击、radio, select disabled）
    /// </summary>
    /// <param name="container">容器</param>
    /// <param name="inputclassname">文本框样式表</param>
    /// <param name="textareaclassname">多行文本框样式表</param>
    disabledContainer : function (container, inputclassname, textareaclassname)
    {
        if (!container)
        {
            // 若容器为空, 设置默认容器为整个页面文档
            container = document.body;
        }

        disabledChildNodes(container.childNodes, inputclassname, textareaclassname);

        /// <summary>
        /// 递归禁用控件容器中子控件
        /// </summary>
        /// <param name="controls">控件集合</param>
        function disabledChildNodes(controls, childNodesinputclassname, textareaclassname)
        {
            for(var i=0; i<controls.length; i++)
            {
                Func.disabledControl(controls[i], inputclassname, textareaclassname);
                disabledChildNodes(controls[i].childNodes, childNodesinputclassname, textareaclassname);
            }
        }
    },

    /// <summary>
    /// 禁用控件（text改成只读、checkbox、不让单击、radio, select disabled）
    /// </summary>
    /// <param name="control">控件对象</param>
    /// <param name="inputclassname">文本框样式表</param>
    /// <param name="textareaclassname">多行文本框样式表</param>
    disabledControl : function(control, inputclassname, textareaclassname)
    {
        switch (control.type)
        {
            case "password":
            case "text":
                control.onblur = null;
                control.onkeypress = null;
                control.onkeydown = null;
                control.onkeyup = null;
                control.onclick = null;
                control.onfocus = null;
                control.readOnly = true;
                control.className = inputclassname;
                break;
            case "textarea":
                control.onblur = null;
                control.onkeypress = null;
                control.onkeydown = null;
                control.onkeyup = null;
                control.onclick = null;
                control.onfocus = null;
                control.readOnly = true;
                control.className = textareaclassname;
                break;
            case "checkbox":
                control.onclick = function(){return false;}
                break;
            case "radio":
                control.disabled = true;
                break;
            case "select-one":
            case "select-multiple":
                control.disabled = true;
                break;
            default:
                break;
        };
    }
}
