*--------------- 客戶端表單通用驗證checkForm(oForm) -----------------
* 本程序最初是由wanghr100(灰豆寶寶.net)的checkForm基礎上進行修改的,增加了很多功能,如下:
* 1.對非ie的支持
* 2.增加了內置表達式和內置提示
* 3.增加了顯示方式(彈出式和頁面顯示式)
* 4.增加了顯示一條和顯示全部
* 5.進行了封裝(CLASS_CHECK)
* 6.支持外接函數或表達式(應用在密碼一致)
* 7.簡化了調用方式,所有操作只需要<script language='javascript' src='checkform.js'>,
然后在HTML里定義各標簽驗證格式
* 8.對IE增加了對鍵盤輸入的限制(如:定義usage='int'時,輸入框只能輸入數字(非IE無效)
* 9.增加了對disabled的不驗證
* 10.自定義報警方式(重寫showMessageEx方法)
*-----------------------------申明信息-----------------------------
*
* 作者: ttyp
* 郵箱: ttyp@21cn.com
* 博客: http://www.cnblogs.com/ttyp/
* 聲明: 對本程序可以任意復制傳播,但請保留這些聲明,對于內置的表達式有些沒有做到很嚴格,如果你
有好的建議和意見,歡迎郵件和我聯系或者上我的博客留言
* 簡介:
本程序只需要對需要驗證的標簽設置三個屬性:usage,exp,tip
usage : 內置格式或表達式或函數
exp : 正則表達式(注意如果指定了usage則忽略exp)
tip : 出錯提示(如果是內置格式可以不要此屬性,有缺省提示)
調用時只需要引用<script language='javascript' src='checkform.js'>,然后為每個標記
增加以上3個屬性(不一定需要全部)
* 原作者: wanghr100(灰豆寶寶.net)
* email: wanghr100@126.com
*
*--------------- 客戶端表單通用驗證checkForm(oForm) -----------------
*/
////////////////////////////////////////////////////////////////////////////////
function CLASS_CHECK()
{
this.pass = true; //是否通過驗證
this.showAll = true; //是否顯示所有的驗證錯誤
this.alert = false; //報警方式(默認alert報警)
this.message = ""; //錯誤內容
this.first = null; //在顯示全部驗證錯誤時的第一個錯誤控件(用于回到焦點)
//定義內置格式
var aUsage =
{
"int":"^([+-]?)\\d+$", //整數
"int+":"^([+]?)\\d+$", //正整數
"int-":"^-\\d+$", //負整數
"num":"^([+-]?)\\d*\\.?\\d+$", //數字
"num+":"^([+]?)\\d*\\.?\\d+$", //正數
"num-":"^-\\d*\\.?\\d+$", //負數
"float":"^([+-]?)\\d*\\.\\d+$", //浮點數
"float+":"^([+]?)\\d*\\.\\d+$", //正浮點數
"float-":"^-\\d*\\.\\d+$", //負浮點數
//郵件
"email":"^\\w+((-\\w+)|(\\.\\w+))*\\@[A-Za-z0-9]+((\\.|-)[A-Za-z0-9]+)*\\.[A-Za-z0-9]+$",
"color":"^#[a-fA-F0-9]{6}", //顏色
"url":"^http[s]?:\\/\\/([\\w-]+\\.)+[\\w-]+([\\w-./?%&=]*)?$", //聯接
"chinese":"^[\\u4E00-\\u9FA5\\uF900-\\uFA2D]+$", //僅中文
"ascii":"^[\\x00-\\xFF]+$", //僅ACSII字符
"zipcode":"^\\d{6}$", //郵編
"mobile":"^0{0,1}13[0-9]{9}$", //手機
"ip4":"^\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}.\\d{1,3}$", //ip地址
"notempty":"^\\S+$", //非空
"picture":"(.*)\\.(jpg|bmp|gif|ico|pcx|jpeg|tif|png|raw|tga)$", //圖片
"rar":"(.*)\\.(rar|zip|7zip|tgz)$", //壓縮文件
"date":"^\\d{4}(\\-|\\/|\.)\\d{1,2}\\1\\d{1,2}$" //日期
};
//缺省消息
var aMessage =
{
"int" :"請輸入整數", //整數
"int+" :"請輸入正整數", //正整數
"int-" :"請輸入負整數", //負整數
"num" :"請輸入數字", //數字
"num+" :"請輸入正數", //正數
"num-" :"請輸入負整數", //負數
"float" :"請輸入浮點數", //浮點數
"float+":"請輸入正浮點數", //正浮點數
"float-":"請輸入負浮點數", //負浮點數
"email" :"請輸入正確的郵箱地址", //郵件
"color" :"請輸入正確的顏色", //顏色
"url" :"請輸入正確的連接地址", //聯接
"chinese":"請輸入中文", //中文
"ascii" :"請輸入ascii字符", //僅ACSII字符
"zipcode":"請輸入正確的郵政編碼", //郵編
"mobile":"請輸入正確的手機號碼", //手機
"ip4" :"請輸入正確的IP地址", //ip地址
"notempty":"不能為空", //非空
"picture":"請選擇圖片", //圖片
"rar" :"請輸入壓縮文件", //壓縮文件
"date" :"請輸入正確的日期" //日期
}
var me = this;
function checkForm(oForm)
{
me.pass = true;
me.message = "";
me.first = null;
var els = oForm.elements;
//遍歷所有表元素
for(var i=0;i<els.length;i++)
{
//取得格式
var sUsage = els[i].getAttribute("Usage");
var sReg = "";
//如果設置Usage,則使用內置正則表達式,忽略Exp
if(typeof(sUsage)!="undefined"&&sUsage!=null)
{
//如果Usage在表達室里找到,則使用內置表達式,無則認為是表達式;表達式可以是函數;
if(aUsage[sUsage]!=null)
{
sReg = aUsage[sUsage];
}
else
{
try
{
if(eval(sUsage)==false)
{
me.pass = false;
if(me.first==null)
{
me.first = els[i];
}
addMessage(getMessage(els[i]));
if(me.showAll==false)
{
setFocus(els[i]);
break;
}
}
}
catch(e)
{
alert("表達式[" + sUsage +"]錯誤:" + e.description)
return false;
}
}
}
else
{
sReg = els[i].getAttribute("Exp");
}
if(typeof(sReg)!="undefined"&&sReg!=null)
{
//對于失效狀態不驗證
if(isDisabled(els[i])==true)
{
continue;
}
//取得表單的值,用通用取值函數
var sVal = getValue(els[i]);
//字符串->正則表達式,不區分大小寫
var reg = new RegExp(sReg,"i");
if(!reg.test(sVal))
{
me.pass = false;
if(me.first==null)
{
me.first = els[i];
}
//alert(reg);
//驗證不通過,彈出提示warning
var sTip = getMessage(els[i]);
if(sTip.length==0&&typeof(sUsage)!="undefined"&&sUsage!=null&&aMessage[sUsage]!=null)
{
sTip = aMessage[sUsage];
}
addMessage(sTip);
if(me.showAll==false)
{
//該表單元素取得焦點,用通用返回函數
setFocus(els[i]);
break;
}
}
}
}
if(me.pass==false)
{
showMessage();
if(me.first!=null&&me.showAll==true)
{
setFocus(me.first);
}
}
return me.pass;
}
/*
* 添加錯誤信息
*/
function addMessage(msg)
{
if(me.alert==true)
{
me.message += msg + "\n";
}
else
{
me.message += msg + "<br>";
}
}
/*
* 顯示錯誤
*/
function getMessage(els)
{
var sTip = els.getAttribute("tip");
if(typeof(sTip)!="undefined"&&sTip!=null)
{
return sTip;
}
else
{
return "";
}
}
/*
* 顯示錯誤
*/
function showMessage()
{
//外接顯示錯誤函數
if(typeof(me.showMessageEx)=="function")
{
return me.showMessageEx(me.message);
}
if(me.alert==true)
{
alert(me.message);
}
else
{
var divTip;
divTip = document.getElementById("divErrorMessage");
try
{
if(typeof(divTip)=="undefined"||divTip==null)
{
divTip = document.createElement("div");
divTip.id = "divErrorMessage";
divTip.name = "divErrorMessage";
divTip.style.color = "red";
document.body.appendChild(divTip);
}
divTip.innerHTML = me.message;
}catch(e){}
}
}
/*
* 獲得元素是否失效(失效的元素不做判斷)
*/
function isDisabled(el)
{
//對于radio,checkbox元素,只要其中有一個非失效元素就驗證
if(el.type=="radio"||el.type=="checkbox")
{
//取得第一個元素的name,搜索這個元素組
var tmpels = document.getElementsByName(el.name);
for(var i=0;i<tmpels.length;i++)
{
if(tmpels[i].disabled==false)
{
return false;
}
}
return true;
}
else
{
return el.disabled;
}
}
/*
* 取得對象的值(對于單選多選框把其選擇的個數作為需要驗證的值)
*/
function getValue(el)
{
//取得表單元素的類型
var sType = el.type;
switch(sType)
{
//文本輸入框,直接取值el.value
case "text":
case "hidden":
case "password":
case "file":
case "textarea": return el.value;
//單多下拉菜單,遍歷所有選項取得被選中的個數返回結果"0"表示選中一個,"00"表示選中兩個
case "checkbox":
case "radio": return getRadioValue(el);
case "select-one":
case "select-multiple": return getSelectValue(el);
}
//取得radio,checkbox的選中數,用"0"來表示選中的個數,我們寫正則的時候就可以通過0{1,}來表示選中個數
function getRadioValue(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 getSelectValue(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 setFocus(el)
{
//取得表單元素的類型
var sType = el.type;
switch(sType)
{
//文本輸入框,光標定位在文本輸入框的末尾
case "text":
case "hidden":
case "password":
case "file":
case "textarea":
try{el.focus();var rng = el.createTextRange(); rng.collapse(false); rng.select();}catch(e){};
break;
//單多選,第一選項非失效控件取得焦點
case "checkbox":
case "radio":
var els = document.getElementsByName(el.name);
for(var i=0;i<els.length;i++)
{
if(els[i].disabled == false)
{
els[i].focus();
break;
}
}
break;
case "select-one":
case "select-multiple":
el.focus();
break;
}
}
//自動綁定到所有form的onsubmit事件
if(window.attachEvent)
{
window.attachEvent("onload",function(){for(var i=0;i<document.forms.length;i++){var theFrom = document.forms[i]; if(theFrom){theFrom.attachEvent("onsubmit",function(){return checkForm(theFrom);});}}});
}
else
{
window.onsubmit = function(e){var theFrom = e.target;if(theFrom){return checkForm(theFrom);}}
}
this.keyCheck = function()
{
if(window.attachEvent)
{
window.attachEvent("onload",function(){for(var i=0;i<document.forms.length;i++){var theFrom = document.forms[i]; if(theFrom){myKeyCheck(theFrom);}}});
}
else
{
//TOOD
}
function myKeyCheck(oForm)
{
var els = oForm.elements;
//遍歷所有表元素
for(var i=0;i<els.length;i++)
{
//取得格式
var sUsage = els[i].getAttribute("Usage");
//如果設置Usage,則使用內置正則表達式,忽略Exp
if(typeof(sUsage)!="undefined"&&sUsage!=null)
{
switch(sUsage.toLowerCase ())
{
case "zipcode":
case "int":
els[i].onkeypress = function(){return /\d/.test(String.fromCharCode(event.keyCode))||(this.value.indexOf('+')<0?String.fromCharCode(event.keyCode)=="+":false)||(this.value.indexOf('-')<0?String.fromCharCode(event.keyCode)=="-":false);}
els[i].onpaste = function(){return !clipboardData.getData('text').match(/\D/);}
els[i].ondragenter = function(){return false;}
els[i].style.imeMode= "disabled";
break;
case "mobile":
case "int+":
els[i].onkeypress = function(){return /\d/.test(String.fromCharCode(event.keyCode))||(this.value.indexOf('+')<0?String.fromCharCode(event.keyCode)=="+":false);}
els[i].onpaste = function(){return !clipboardData.getData('text').match(/\D/);}
els[i].ondragenter = function(){return false;}
els[i].style.imeMode= "disabled";
break;
case "int-":
els[i].onkeypress = function(){return /\d/.test(String.fromCharCode(event.keyCode))||(this.value.indexOf('-')<0?String.fromCharCode(event.keyCode)=="-":false);}
els[i].onpaste = function(){return !clipboardData.getData('text').match(/\D/);}
els[i].ondragenter = function(){return false;}
els[i].style.imeMode= "disabled";
break;
case "float":
case "num":
els[i].onkeypress = function(){return /[\+\-\.]|\d/.test(String.fromCharCode(event.keyCode));}
els[i].onpaste = function(){return !clipboardData.getData('text').match(/\D/);}
els[i].ondragenter = function(){return false;}
els[i].style.imeMode= "disabled";
break;
case "float+":
case "num+":
els[i].onkeypress = function(){return /[\+\.]|\d/.test(String.fromCharCode(event.keyCode));}
els[i].onpaste = function(){return !clipboardData.getData('text').match(/\D/);}
els[i].ondragenter = function(){return false;}
els[i].style.imeMode= "disabled";
break;
case "float-":
case "num-":
els[i].onkeypress = function(){return /[\-\.]|\d/.test(String.fromCharCode(event.keyCode));}
els[i].onpaste = function(){return !clipboardData.getData('text').match(/\D/);}
els[i].ondragenter = function(){return false;}
els[i].style.imeMode= "disabled";
break;
case "ascii":
els[i].style.imeMode= "disabled";
break;
case "ip4":
els[i].onkeypress = function(){return /[\.]|\d/.test(String.fromCharCode(event.keyCode));}
els[i].onpaste = function(){return !clipboardData.getData('text').match(/\D/);}
els[i].ondragenter = function(){return false;}
els[i].style.imeMode= "disabled";
els[i].maxLength = 15;
break;
case "color":
els[i].onkeypress = function(){return /[a-fA-Z]|\d/.test(String.fromCharCode(event.keyCode))||(this.value.indexOf('#')<0?String.fromCharCode(event.keyCode)=="#":false);}
els[i].onpaste = function(){return !clipboardData.getData('text').match(/\D/);}
els[i].ondragenter = function(){return false;}
els[i].maxLength = 7;
els[i].style.imeMode= "disabled";
break;
case "date":
els[i].onkeypress = function(){return /[\/\-\.]|\d/.test(String.fromCharCode(event.keyCode));}
els[i].onpaste = function(){return !clipboardData.getData('text').match(/\D/);}
els[i].ondragenter = function(){return false;}
els[i].style.imeMode= "disabled";
break;
}
}
}
}
}
}
//初始化
var g_check = new CLASS_CHECK();
g_check.keyCheck();