增加客户端的表单验证可以为用户提供更快的体验,但客户端验证永远不应该取代服务器端的验证,而只是辅助和增强。因此,为页面增加客户端验证是学习JavaScript分离式编程的不错案例。
在开始表单脚本编程之前,需要制作好表单并确保它能按要求工作。下面的表单示例使用了语义化的XHTML表单,在表单内,所有<input>元素都进行了归类,冰雨正确的label一起包含在合适的fieldset中。
<html> <head> <title>Simple Form</title> </head> <body> <form action="" method="POST"> <fieldset class="login"> <legend>Login Information</legend> <label for="username" class="hover">Username</label> <input type="text" id="username" class="required text"/> <label for="password" class="hover">Password</label> <input type="password" id="password" class="required text"/> </fieldset> <fieldset> <legend>Personal Information</legend> <label for="name">Name</label> <input type="text" id="name" class="required text"/><br/> <label for="email">Email</label> <input type="text" id="email" class="required email text"/><br/> <label for="date">Date</label> <input type="text" id="date" class="required date text"/><br/> <label for="url">Website</label> <input type="text" id="url" class="url text" value="http://"/><br/> <label for="phone">Phone</label> <input type="text" id="phone" class="phone text"/><br/> <label for="age">Over 13?</label> <input type="checkbox" id="age" name="age" value="yes"/><br/> <input type="submit" value="Submit Form" class="submit"/> </fieldset> </form> </body> </html>
接下来为表单赋予基本的CSS样式,让它看起来更美观些。
form { font-family: Arial; font-size: 14px; width: 300px; } fieldset { border: 1px solid #CCC; margin-bottom: 10px; } fieldset.login input { width: 125px; } legend { font-weight: bold; font-size: 1.1em; } label { display: block; width: 60px; text-align: right; float: left; padding-right: 10px; margin: 5px 0; } input { margin: 5px 0; } input.text { padding: 0 0 0 3px; width: 172px; } input.submit { margin: 15px 0 0 70px; }
经过格式化后的表单如下图所示:
这表单验证这一部分,实现了校验不同输入元素的特定代码,这些验证程序看起来相对独立,但结合起来就可以提供完整的验证和测试功能。
1. 必填字段
通常,检查必填字段可以简化为检查字段的值是否为空或者是默认值。这两种检查一般可以对<input type=”text”>,<select><textarea>这些元素进行检查。如果是复选框或者是单选钮则一般找出拥有相同name的字段,然后检查用户是否选择了其中的一个。下面的代码实现了检查必填字段功能(包括复选框和单选钮)
// 检查表单元素是否输入信息的通用函数 function checkRequired( elem ) { if ( elem.type == "checkbox" || elem.type == "radio" ) return getInputsByName( elem.name ).numChecked; else return elem.value || elem.value == elem.defaultValue; } // 找出指定 name 的所有 Input 元素 function getInputsByName( name ) { // 匹配的 input 元素的数组 var results = []; // 追踪被选中元素的数量 results.numChecked = 0; // 查找所有的 input 元素 var input = document.getElementsByTagName("input"); for ( var i = 0; i < input.length; i++ ) { // 查找具有指定名称的表单域 if ( input[i].name == name ) { // 找出具有指定 name 的字段并保存它 results.push( input[i] ); // 记录被选中字段的数量 if ( input[i].checked ) results.numChecked++; } } // 返回匹配的数组 return results; } // 等待文档载入完成 window.onload = function( ){ // 检查年龄 var elem = document.getElementById("age"); if( !checkRequire( elem )){ alert("Required field is empty – " + "you must be over 13 to use this site"); return false } // 确保输入 name var elem = document.getElementById("name"); if( !checkRequire( elem )){ alert("Required field is empty – Please provide you name."); return false } } [/code] <strong>2. 模式匹配</strong> 验证输入的第二方面是模式匹配,即检验字段的内容是否符合要求。这方面包括电子邮件地址、URL、电话号码和日期 <strong>电子邮件</strong> 要求填写电子邮件是Web表单中再普通不过的需求了,因为它是鉴定和交流的普遍手段。下面的代码展示了一个检查输入字段是否包含电子邮件地址的例子: // 检查 input 元素内容是否符合 email 地址要求的通用函数 function checkEmail( elem ) { // 确保输入的内容是正确的 email 地址 return !elem.value || /^[a-z0-9_+.-]+\@([a-z0-9-]+\.)+[a-z0-9]{2,4}$/i.test( elem.value ); } // 获取需要检查的 email 元素 var elem = document.getElementById("email"); // 检查这个字段是否正确 if ( ! checkEmail( elem ) ) { alert( "Field is not an email address." ); }
URL
在表单中要求用户输入网站的URL也是一个普通要求,虽然比较复杂,但只需实现规范中的一小部分就可以达到目的。
// 检查 input 元素是否包含 URL 的通用函数 function checkURL( elem ) { // 确保有文本键入,且不是默认的 http:// 文本 return !elem.value || elem.value == 'http://' || // 确保它是一个正确的 URL /^https?:\/\/([a-z0-9-]+\.)+[a-z0-9]{2,4}.*$/.test( elem.value ); } // 获取需要检查的 input 字段 var elem = document.getElementById("url"); // 检查它是否是一个正确的 URL if ( ! checkURL( elem ) ) { alert( "Field does not contain a URL." ); }
电话号码
电话号码的规则是123-456-7890或(123)456-7890。
// 检查 input 元素是否包含电话号码的通用函数 function checkPhone( elem ) { // 检查是否符合电话号码的要求 var m = /(\d{3}).*(\d{3}).*(\d{4})/.exec( elem.value ); // 电话号码的要求是: (123) 456-7890 if ( m ) obj.value = "(" + m[1] + ") " + m[2] + "-" + m[3]; return !elem.value || m; } // 获取需要检查的 input 元素 var elem = document.getElementById("phone"); // 检查这个字段是否包含正确的电话号码 if ( ! checkPhone( elem ) ) { alert( "Field does not contain a phone number." ); }
日期
日期格式为:MM/DD/YYYY。
// 检查 input 元素是否包含日期的通用函数 function checkDate( elem ) { // 时间格式: MM/DD/YYYY return !elem.value || /^\d{2}\/\d{2}\/\d{2,4}$/.test(obj.value); } // 获取需要检查的 input 元素 var elem = document.getElementById("date"); // 检查这个字段是否包含正确的日期 if ( ! checkDate( elem ) ) { alert( "Field is not a date." ); }
运用各种不同的验证函数就可以构建一个用以处理不同验证的通用技术架构了。下面的代码构建了验证引擎的规则和错误描述的标准集合:
var errMsg = { // 检查必填字段 required: { msg: "This field is required.", test: function(obj,load) { // 确保字段尚未有字段输入,并在页面加载时不作检查 return obj.value || load || obj.value == obj.defaultValue; } }, // 检查Email地址 email: { msg: "Not a valid email address.", test: function(obj) { // 确保有输入内容并符合email地址的格式 return !obj.value || /^[a-z0-9_+.-]+\@([a-z0-9-]+\.)+[a-z0-9]{2,4}$/i.test( obj.value ); } }, // 检查电话号码 phone: { msg: "Not a valid phone number.", test: function(obj) { // 检查是否符合电话号码的要求 var m = /(\d{3}).*(\d{3}).*(\d{4})/.exec( obj.value ); // 检查它的格式是否符合要求: (123) 456-7890 if ( m ) obj.value = "(" + m[1] + ") " + m[2] + "-" + m[3]; return !obj.value || m; } }, // 检查日期格式 MM/DD/YYYY date: { msg: "Not a valid date.", test: function(obj) { // 确保有输入内容并符合 MM/DD/YYYY 的时间格式 return !obj.value || /^\d{2}\/\d{2}\/\d{2,4}$/.test(obj.value); } }, // 检查url格式 url: { msg: "Not a valid URL.", test: function(obj) { // 确保有内容输入,并且不是默认的 http:// 文本 return !obj.value || obj.value == 'http://' || // 确保它是一个正确的url /^https?:\/\/([a-z0-9-]+\.)+[a-z0-9]{2,4}.*$/.test( obj.value ); } } };