首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

表单作为接受用户输入数据的一种手段,对Web开发者非常有用。但是,用户能做什么、能输入什么数据和表单的可用性如何等情况,却有不少的限制。

构建一个基于语义设计的表单后,就到增加一些能为用户提供反馈的JavaScript的开发阶段了。理解表单某些效果的前因后果,用户就可以快捷地使用表单,也因此拥有更好的用户体验。

在本章中,我们将探索客户端表单的相关基本操作——验证并在一定程度上反馈验证的结果给用户,基于分离式脚本编程技术。接着探索全面改进表单的一些可行方法。这两种技术结合起来可以让表单的可用性显著提升,从而用户也更乐意于填写表单。

8.1 表单验证

增加客户端的表单验证可以为用户提供更快的体验,但决不能忽视的是,客户端表单验证永远不应该取代服务器端的验证,而只能是辅助和增强。因此,为页面增加客户端表单验证是你刚学过的分离式脚本编程技术的不错案例。

在开始任何形式的表单脚本编程之前,你应该已经制作好表单并确保它完全能按要求工作(比如,验证用户的输入、反馈恰当的错误信息等)。在本章中,你使用的都是语义化的XHTML表单。在表单内,所有<input>元素都精细地分好类(比如,type为text的元素其class也为 text),并与正确的label一起被包含在合适的fieldset内。所有这些都可参考代码清单8-1。

代码清单8-1 一个简单的XHTML表单,你将要使用JavaScript改进它

<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样式,让它看起来更美观。这可帮助你显示更加友好的错误信息和反馈,在后面的章节会讨论到。这个表单用到的CSS见代码清单8-2。

代码清单8-2 用以提高表单视觉质量的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;

}

文本框:  
图8-1 你将为之增加JavaScript行为的表单,
经过样式化后的屏幕截图
图8-1是该表单的屏幕截图,可以让你对这个表单(已经为JavaScript行为层做好准备)有个初步的印象。

有了这么一个漂亮的表单,现在就可以在更深程度上探索客户端的验证了。用在表单上验证技术有好几种,它们都需要保证用户输入的数据是服务器端软件所预期的。

提供客户端验证的主要优点在于,用户可以有一个校验他们输入的实时反馈,从而全面提高表单的输入体验。但这并不等于,实现了客户端的表单验证就可以忽视或者删除服务器端的验证。应该继续测试禁止JavaScript情况下的表单,确保不使用JavaScript的用户可继续拥有其他的可用性体验。

在这一部分中,你将会看到校验各种不同输入元素的特定代码,以确保它们包含符合表单要求的特定数据。这些验证程序看起来相对独立,但结合起来就可以提供完整的验证和测试系列,我们会稍后讨论。

8.1.1 必填字段

字段验证中最重要的可能就是必填字段(表示该条目用是户必须填写的)了。通常,这个必要条件可以简化为检查字段的值是否为空。但有时候,字段可能有一个默认的值,这就要求在注意这种可能性的同时要检查用户是否至少改变了字段默认值。这两种检查包含了表单字段的主要形式,包括<input type="text">,<select>和<textarea>。

尽管如此,当你试图检查用户是否修改了必填的复选框或者单选框时,还是可能产生问题。要巧妙地解决这个问题,你需要找出所有拥有相同name(这是字段元素关联的纽带)的字段,然后检查用户是否选择了其中的一个。

代码清单8-3是一个检查必填字段的例子。

代码清单8-3 检查一个必填字段是否被修改(包括复选框和单选框)

// 检查输入元素是否键入了信息的通用函数

function checkRequired( elem ) {

      if ( elem.type == "checkbox" || elem.type == "radio" )

           return getInputsByName( elem.name ).numChecked;

      else

           return elem.value.length > 0 && 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++ ) {

           // 找出所有指定name的字段

           if ( input[i].name == name ) {

               // 保存结果,稍后会返回

               results.push( input[i] );

               // 记录被选中字段的数量

               if ( input[i].checked )

                   results.numChecked++;

           }

     }

      // 返回匹配的字段集合

      return results;

}

// 等待文档完成加载

window.onload = function()

    // 获得表单并监听提交事件

   document.getElementsByTagName("form")[0].onsubmit = function(){

        // 获取需检查的input元素

        var elem = document.getElementById("age");

        // 确保年龄的必填字段已经被选中

        if ( ! checkRequired( elem ) ) {

             // 否则显示错误并阻止表单提交

            alert( "Required field is empty – " +

                "you must be over 13 to use this site." );

            return false;

        }

        // 获取需检查的input元素

        var elem = document.getElementById("name");

        // 确保名字字段有文本输入

        if ( ! checkRequired( elem ) ) {

          // 否则显示错误并阻止表单提交

          alert( "Required field is empty – please provide your name." );

          return false;

        }

    };

};

检查必填字段后,还需要确保字段的内容符合要求。接下来,你会看到如何验证字段的内容。

8.1.2 模式匹配

验证输入元素(尤其是文本字段)的第二大组件是模式匹配,它检验字段的内容是否符合要求。

使用以下技术的要点在于明白无误地定义字段的必须条件,否则,你可能会让用户产生困惑。比如日期格式会在特定文化的差异,甚至是不同规范的情况下而差别巨大。

在这一部分中,你会看到几种不同的验证字段内容的技术,包括电子邮件地址、URL、电话号码和日期。

1.电子邮件

要求填写电子邮件地址无疑是Web表单中再普通不过的需求了,因为它是鉴定和交流的普遍手段。但要完全检查电子邮件地址的正确性(取决于它的规则)却非常复杂。你可以只概括性地检查所有可能的输入情况。代码清单8-4展示了一个检查输入字段是否包含电子邮件地址的例子。

代码清单8-4 检查指定的input元素是否包含电子邮件地址

// 检查input元素内容是否符合emial地址要求的通用函数

function checkEmail( elem ) {

      // 确保输入的内容是正确的email地址

      return elem.value == '' ||

          /^[a-z0-9_+.-]+\@([a-z0-9-]+\.)+[a-z0-9]{2,4}$/i.test( elem.value );

}

// 获取需要检查的input元素

var elem = document.getElementById("email");

// 检查这个字段是否正确

if ( ! checkEmail( elem ) ) {

      alert( "Field is not an email address." );

}

2.URL

表单(和其他的网络相关区域)的一个常见需求是要求用户输入网站的URL。与电子邮件地址一样,URL又是一个难以实现完全符合规范定义的例子,但只需实现规范中的一小部分即可达到目的。实际上,你只需检查基于http或https的Web地址(当然,即使有所不同也可方便修改)。此外,URL字段通常会有http://这样的字符串打头,在检查表单时必须考虑这种情形。代码清单8-5是检查表单中URL正确性的一个例子。

代码清单8-5 检查input元素是否包含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 );

}

// 获取需要检查的inpu元素

var elem = document.getElementById("url");

// 检查它是否是一个正确的URL

if ( ! checkURL( elem ) ) {

    alert( "Field does not contain a URL." );

}

3.电话号码

接下来你会看到两个的字段是:电话号码和日期。取决于你的所在地,它们有着不同的情形。为简化起见,我将使用美国式的电话号码(和日期)。当然,改变它们的规则以适应另一个国家或地区并不是十分困难。

记住了这些,你还要试着处理电话号码字段中的一些特别之处。电话号码可以以不同的形式书写,所以你需要允许这些形式的输入(如123-456-7890或(123)456-7890)。

这样一来你不仅需要验证数字本身,还要验证这种特殊的格式。你可以简单地逆向检查电话号码字段的值,看它是否被分为包含3个数字的两部分以及一个包含4个数字的部分,而忽略包住电话号码的任何多余的信息。

执行这个验证并强行检查字段值的代码如代码清单8-6所示。

代码清单8-6 检查字段是否包含电话号码

// 检查input元素是否包含电话号码的通用函数

function checkPhone( elem ) {

      // 检查是否符合电话号码的要求

      var m = /(\d{3}).*(\d{3}).*(\d{4})/.exec( elem.value );

      // 如果是,可能也只是表面正确而已——强行检查它的格式是否符合我们的要求:(123) 456-7890

      if ( m !== null )

          elem.value = "(" + m[1] + ") " + m[2] + "-" + m[3];

      return elem.value == '' || m !== null;

}

// 获取需要检查的inpu元素

var elem = document.getElementById("phone");

// 检查这个字段是否包含正确的电话号码

if ( ! checkPhone( elem ) ) {

    alert( "Field does not contain a phone number." );

}

4.日期

最后要探索的是日期的验证。再次,你会看到美国式的日期书写格式(MM/DD/YYYY)。 就像电话号码或者其他由国别决定的不同字段,如果有必要,你可以方便修改验证的正则表达式以满足本土化需求。使用如代码清单8-7所示的具体验证函数,你就可以验证日期字段的内容了。

代码清单8-7 检查字段是否包含日期

//检查input元素是否包含日期的通用函数

function checkDate( elem ) {

      // 确保输入了内容并检查是否符合MM/DD/YYYY的时间格式

      return !elem.value || /^\d{2}\/\d{2}\/\d{2,4}$/.test(elem.value);

}

// 获取需要检查的inpu元素

var elem = document.getElementById("date");

// 检查这个字段是否包含正确的日期

if ( ! checkDate( elem ) ) {

      alert( "Field is not a date." );

}

8.1.3 规则集合

运用上一部分所述的各种不同验证函数,现在你可以构建一个用以处理不同验证的通用技术架构了。需要注意的是,所有的测试都分别需要通用的名称和语义化的错误信息。完整的规则集合数据结构可以参考代码清单8-8。

代码清单8-8 构建验证引擎的规则和错误描述的标准集合

var errMsg = {

      // 检查特定字段是否为必填

      required: {

          msg: "This field is required.",

          test: function(obj,load) {

                // 确保字段尚未有内容输入,并在页面加载时不作检查

                //(在加载时显示“必填字段”可能会让用户感到厌烦)

                return obj.value.length > 0 || 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 );

       }

   }

};

使用这个新的规则集合的数据结构,现在你就可以编写通用的、牢固的表单验证工具了,并可以显示错误信息,这正是接下来我们要讨论的。

查看所有评论(0)条】

最近评论



正在载入评论列表...
热点评论