/*
    描述：数据格式有效性验证
    作者：杨秀东
    日期：2009-03-25

    常见的33种表达式已经做成了库，调用时可以直接写关键字：
    例如：
    <input type="text" name="id" check="empty" warning="不能为空">
    关键字              说明
    empty               //非空
    password;           //不少于6位的密码
    phone               //电话号码
    select              //必须选择；用于select和radio
    check_1             //必须选中至少1项；用于checkbox
    check_2             //必须选中至少2项；用于checkbox
    check_3             //必须选中至少3项；用于checkbox
    empty_20            //非空，且不少于20个字
    email               //email
    http_url            //url地址，必须用http开头的url地址http://www.sina.com.cn/
    qq                  //QQ号
    postcode            //邮政编码
    id                  //身份证，18位或15位
    ip                  //ip地址
    user_name           //匹配帐号是否合法(字母开头，允许5-16字节，允许字母数字下划线)
    chinese             //必须是中文
    file_img            //匹配上传图片类型：验证jpeg,jpg,gif。
    file_doc            //匹配上传文档类型：验证doc,txt,pdf,xls
    z_integer           //正整数
    no_integer      　　//非正整数（负整数 + 0）
    f_integer       　　//负整数
    integer       　　　//整数
    zero_integer    　　//非负整数（正整数 + 0）
    zero_float          //非负浮点数（正浮点数 + 0）
    z_float             //正浮点数
    float           　　//浮点数  
    no_float            //非正浮点数（负浮点数 + 0）  
    f_float             //负浮点数 
    26zm                //由26个英文字母组成的字符串
    big_26zm            //由26个英文字母的大写组成的字符串
    small_26zm          //由26个英文字母的小写组成的字符串
    number_zm           //由数字和26个英文字母组成的字符串
    number_zm_line      //由数字、26个英文字母或者下划线组成的字符串 
 */
  
//验证主函数
function CheckForm(oForm)
{
    var els = oForm.elements;
    var count=els.length;
    var ret = true;
　　//遍历所有表元素
　　for(var i=0;i<count;i++)
　　{
　　    //验证元素，如果有一个验证不通过，则返回空
　　    if(!CheckEls(els[i]))
　　　　{
　　　　    //验证失败，则该元素获得焦点
　　　　    //如果多次验证，则获得焦点的为第一个验证失败的元素
　　　　    if(ret)
　　　　    {
　　　　        els[i].focus();
　　　　        ret = false;
　　　　    }　　　　    
　　　　    　　　
　　　　}　　　　
    }
    return ret;
}

//验证单个元素主数
//<input class="HomeTextBox" id="Text1" onblur="CheckEls(this);" check="phone" warning="电话号码无效！"/>
//function CheckEls(oEls)
//{
//    alert(oEls.id);
//}

//验证主函数
function CheckEls(oEls)
{
    var ret = true;
　　
　　    //是否需要验证
　　　　if(oEls.getAttribute("check"))
　　　　{
　　　　    //取得验证的正则字符串
　　　　　　var sReg = oEls.getAttribute("check");            
            switch(sReg)
            {
                //定义常用验证正则表达式库，继续扩展中。。。        
                case "empty":sReg= "^\\S";//非空
                      break;
                case "password":sReg="^\\S{6,}";//不少于6位的密码
                      break;
                case "phone":sReg="^\\d+$";//电话号码
                      break;
                case "select":sReg="^0$";//必须选择；用于select和radio
                      break;
                case "check_1":sReg="^0{1,}$";//必须选中至少1项；用于checkbox
                      break;
                case "check_2":sReg="^0{2,}$";//必须选中至少2项；用于checkbox
                      break;
                case "check_3":sReg="^0{3,}$";//必须选中至少3项；用于checkbox
                      break;
                case "empty_20":sReg="^[\\s|\\S]{20,}$";//非空，且不少于20个字
                      break;
                case "email":sReg="\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*";//email
                      break;
                case "http_url":sReg="^[a-zA-z]+://(\\w+(-\\w+)*)(\\.(\\w+(-\\w+)*))*(\\?\\S*)?$";//url地址，必须用http开头的url地址http://www.sina.com.cn/
                      break;
                case "qq":sReg="[1-9][0-9]{4,}";//QQ号
                      break;
                case "postcode":sReg="[0-9]\\d{5}(?!\\d)";//邮政编码
                      break;
                case "id":sReg="\\d{15}|\\d{18}";//身份证，18位或15位
                      break;
                case "ip":sReg="\\d+\\.\\d+\\.\\d+\\.\\d+";//ip地址
                      break;
                case "user_name":sReg="^[a-zA-Z][a-zA-Z0-9_]{4,15}$";//匹配帐号是否合法(字母开头，允许5-16字节，允许字母数字下划线)
                      break;
                case "chinese":sReg="[\\u4e00-\\u9fa5]";//必须是中文
                      break;
                case "file_img":sReg="(.*)(\\.jpg|\\.gif|\\.jpeg|\\.png|\\.bmp)$";//图片验证
                      break;
                case "file_doc":sReg="(.*)(\\.txt|\\.doc|\\.pdf|\\.xls)$";//文本验证
                      break;                                   
                case "z_integer":sReg="^[0-9]*[1-9][0-9]*$";　　//正整数  
                      break;  
                case "no_integer":sReg="^((-\\d+)|(0+))$";　　//非正整数（负整数 + 0）  
                      break;  
                case "f_integer":sReg="^-[0-9]*[1-9][0-9]*$"　　//负整数   
                      break;  
                case "integer":sReg="^-?\\d+$";　　　　//整数     
                      break; 
                case "zero_integer":sReg="^\\d+$";　　//非负整数（正整数 + 0）    
                      break;  
                case "zero_float":sReg="^\\d+(\\.\\d+)?$";　　//非负浮点数（正浮点数 + 0） 
                      break;
                case "z_float":sReg="^(([0-9]+\\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\\.[0-9]+)|([0-9]*[1-9][0-9]*))$";//正浮点数
                      break;  
                case "float":sReg="^(-?\\d+)(\\.\\d+)?$";　　//浮点数  
                      break;  
                case "no_float":sReg="^((-\\d+(\\.\\d+)?)|(0+(\\.0+)?))$";　　//非正浮点数（负浮点数 + 0）      
                      break; 
                case "f_float":sReg="^(-(([0-9]+\\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\\.[0-9]+)|([0-9]*[1-9][0-9]*)))$";//负浮点数       
                      break;  
                case "26zm":sReg="^[A-Za-z]+$"　　   //由26个英文字母组成的字符串  
                      break;   
                case "big_26zm":sReg="^[A-Z]+$"　　//由26个英文字母的大写组成的字符串    
                      break; 
                case "small_26zm":sReg="^[a-z]+$"　　//由26个英文字母的小写组成的字符串     
                      break;   
                case "number_zm":sReg="^[A-Za-z0-9]+$"　　//由数字和26个英文字母组成的字符串      
                      break;  
                case "number_zm_line":sReg="^\\w+$"　　//由数字、26个英文字母或者下划线组成的字符串      
                      break;   
                case "mumber_8_15":sReg="^[A-Za-z0-9_]{8,15}"　　//由数字、26个英文字母或者下划线组成的字符串      
                      break;
                default:
                      sReg=sReg;
                      break;
            }
            
            var emement  = "err_" + oEls.id;
            if (document.getElementById(emement)!=null)
                deleteNode(emement);
                
　　　　　　var _txt = document.createElement("<span ></span>");
　　　　　　_txt.id = "err_" + oEls.id;
　　　　　　_txt.style.top = oEls.clientTop - oEls.offsetHeight - 3 +"px";
            _txt.style.left = oEls.offsetLeft + oEls.offsetWidth + 2 + "px";
            _txt.onclick = new Function( _txt.id + ".style.display='none';");
            if(!document.getElementById(_txt.id))
                oEls.parentNode.insertBefore(_txt, oEls.nextSibling);
            
            ///取得表单的值,用通用取值函数
　　　　　　var sVal = GetValue(oEls);         
　　　　　  //字符串->正则表达式,不区分大小写
　　　　　　var reg = new RegExp(sReg,"i");
　　　　　　//验证不通过,弹出提示warning
　　　　　　if(!reg.test(sVal))
　　　　　　{
                _txt.className = "js_validator_error_style";
                _txt.title = "点击关闭错误提示！"
                _txt.innerHTML = oEls.getAttribute("warning");
　　　　　　　　//该表单元素取得焦点,用通用返回函数
　　　　　　　　//GoBack(oEls);//这里还有点问题,等待解决.不过已经能让部分input获得焦点 //by bridgler
                //oEls.focus();
　　　　　　　  ret = false;
　　　　    }
　　　　    else
　　　　    {
                _txt.className = "js_validator_right_style";
                _txt.innerHTML = "";
　　　　    }
　　    }
    
    return ret;
}

//判断2个id对应的value是否相等，错误提示将出现在id2后方。
function CheckEqual(id1,id2)
{
    var oEls=document.getElementById(id2);
　　var emement  = "err_" + oEls.id;
    if (document.getElementById(emement)!=null)
        deleteNode(emement);
        
　　var _txt = document.createElement("<span ></span>");
　　_txt.id = "err_" + oEls.id;
　　_txt.style.top = oEls.clientTop - oEls.offsetHeight - 3 +"px";
    _txt.style.left = oEls.offsetLeft + oEls.offsetWidth + 2 + "px";
    _txt.onclick = new Function( _txt.id + ".style.display='none';");
    if(!document.getElementById(_txt.id))
        oEls.parentNode.insertBefore(_txt, oEls.nextSibling);
    
    ///取得表单的值,用通用取值函数
　　//var sVal = GetValue(oEls);         
　  //字符串->正则表达式,不区分大小写
　　//var reg = new RegExp(sReg,"i");
　　//验证不通过,弹出提示warning
　　if(document.getElementById(id1).value != document.getElementById(id2).value)
　　{
        _txt.className = "js_validator_error_style";
        _txt.title = "点击关闭错误提示！"
        _txt.innerHTML = oEls.getAttribute("warning");
　　　　//该表单元素取得焦点,用通用返回函数
　　　　//GoBack(oEls);//这里还有点问题,等待解决.不过已经能让部分input获得焦点 //by bridgler
        //oEls.focus();
　　　  ret = false;
    }
    else
    {
        _txt.className = "js_validator_right_style";
        _txt.innerHTML = "";
    }
}

//判断2个id对应的value是否相等，错误提示将出现在id2后方。
function ShowMsg(oEls,msg)
{
    //var oEls=document.getElementById(id);　　
　　var _txt = document.createElement("<span ></span>");
　　_txt.id = "err_" + oEls.id;
　　_txt.style.top = oEls.clientTop - oEls.offsetHeight - 3 +"px";
    _txt.style.left = oEls.offsetLeft + oEls.offsetWidth + 2 + "px";
    _txt.onclick = new Function( _txt.id + ".style.display='none';");
    
    var emement  = "err_" + oEls.id;
    if (document.getElementById(emement)!=null)
    {
        deleteNode(emement);
    }
                
    if(!document.getElementById(_txt.id))
    {
        oEls.parentNode.insertBefore(_txt, oEls.nextSibling);
    }
　　
    _txt.className = "js_validator_load_style";
    _txt.title = "点击关闭错误提示！"
    _txt.innerHTML = msg;
    
}



//通用取值函数分三类进行取值
//文本输入框,直接取值el.value
//单多选,遍历所有选项取得被选中的个数返回结果"00"表示选中两个
//单多下拉菜单,遍历所有选项取得被选中的个数返回结果"0"表示选中一个
function GetValue(el)
{
    //取得表单元素的类型
　　var sType = el.type;
　　switch(sType)
　　{
　　    case "text":
　　　　case "hidden":
　　　　case "password":
　　　　case "file":
　　　　case "textarea": return el.value;
　　　　case "checkbox":
　　　　case "radio": return GetValueChoose(el);
　　　　case "select":
　　　　case "select-one":
　　　　case "select-multiple": return GetValueSel(el);
    }
　　//取得radio,checkbox的选中数,用"0"来表示选中的个数,我们写正则的时候就可以通过0{1,}来表示选中个数
　　function GetValueChoose(el)
　　{
　　    var sValue = "";
　　　　//取得第一个元素的name,搜索这个元素组
　　　　var tmpels = document.getElementsByName(el.name);
　　　　for(var i=0;i<tmpels.length;i++)
　　　　{
　　　　    if(tmpels[i].checked)
　　　　　　{
　　　　　　    sValue += "0";
　　　　　　}
　　　　}
　　　　return sValue;
    }
    //取得select的选中数,用"0"来表示选中的个数,我们写正则的时候就可以通过0{1,}来表示选中个数
　　function GetValueSel(el)
　　{
　　    var sValue = "";
　　　　for(var i=0;i<el.options.length;i++)
　　　　{
　　　　    //单选下拉框提示选项设置为value=""
　　　　　　if(el.options[i].selected && el.options[i].value!="")
　　　　　　{
　　　　　　    sValue += "0";
　　　　　　}
　　　　}
　　　　return sValue;
    }
}

//通用返回函数,验证没通过返回的效果.分三类进行取值
//文本输入框,光标定位在文本输入框的末尾
//单多选,第一选项取得焦点
//单多下拉菜单,取得焦点
function GoBack(el)
{
　　//取得表单元素的类型
　　var sType = el.type;
　　switch(sType)
    {
　　    case "text":
　　　　case "hidden":
　　　　case "password":
　　　　case "file":
　　　　case "textarea": el.focus();var rng = el.createTextRange(); rng.collapse(false); rng.select();
　　　　case "checkbox":
　　　　case "radio": var els = document.getElementsByName(el.name);els[0].focus();
　　　　case "select-one":
　　　　case "select-multiple":el.focus();
    }
}

function deleteNode(nodeid)
{
	var node = document.getElementById(nodeid);
	if(node.parentNode)
	{
		var parent = node.parentNode;
		parent.removeChild(node);
	}
	//位于body节点当中
	else
	{
		var headElement = document.documentElement.getElementsByTagName("head")[0];
		var bodyElement = headElement.nextSibling;
		while (bodyElement.nodeName.toLowerCase() != "body") 
		{
			bodyElement = bodyElement.nextSibling;
		}
		
		if (bodyElement.hasChildNodes()) 
		{
			var currentNode = document.getElementById(Nodes);
			bodyElement.removeChild(currentNode);
		}
	}
}