鲲鹏

C# asp.net

导航

jQuery表单验证功能

Posted on 2009-06-11 21:55  昆鹏  阅读(488)  评论(0编辑  收藏  举报

比较常见的表单验证功能

当在网站中使用jQuery时,我们必须时常提醒自己如果用户禁用了JavaScript,那么页面看起来会怎样、功能是否还健全(当然,除非我们知道用户是谁,而且知道他们会怎样配置浏览器)。但是,这并不意味着我们不能为JavaScript的用户创建更美观或者功能更强大的网站。渐进增强 的原则在JavaScript开发者中间如此流行,就是因为它在为多数人提供额外功能的同时,还能照顾到全体用户的需求。

效果图如下:

如果我上面这个示例用户禁用了js,效果图如下:

此时内容结构还是一样的清晰明了。

下面来看一下过程:

Html代码 复制代码

  1. <fieldset>
  2. <legend>Personal Info</legend>
  3. <form action="">
  4. <ol>
  5. <li>
  6. <label for="first-name">First Name</label>
  7. <input class="required" type="text" name="first-name" id="first-name"/>
  8. <span>(required)</span>
  9. </li>
  10. <li>
  11. <label for="last-name">Last Name</label>
  12. <input class="required" type="text" name="last-name" id="last-name"/>
  13. <span>(required)</span>
  14. </li>
  15. <li>
  16.             How would you like to be contacted?(choose at least one method)   
  17. <ul>
  18. <li>
  19. <label for="by-email"><input type="checkbox" name="by-contact-type" value="E-mail" id="by-email"/>by E-mail</label>
  20. <input class="contional" type="text" name="email" id="email" />
  21. <span>(required when corresponding checkbox checked)</span>
  22. </li>
  23. <li>
  24. <label for="by-phone"><input type="checkbox" name="by-contact-type" value="phone" id="by-phone"/>by Phone</label>
  25. <input class="contional" type="text" name="phone" id="phone" />
  26. <span>(required when corresponding checkbox checked)</span>
  27. </li>
  28. <li>
  29. <label for="by-fax"><input type="checkbox" name="by-contact-type" value="fax" id="by-fax"/>by Fax</label>
  30. <input class="contional" type="text" name="fax" id="fax" />
  31. <span>(required when corresponding checkbox checked)</span>
  32. </li>
  33. </ul>
  34. </li>
  35. </ol>
  36. <input type="submit" value="send" id="send"/>
  37. </form>
  38. </fieldset>
<fieldset>
<legend>Personal Info</legend>
<form action="">
	<ol>
		<li>
			<label for="first-name">First Name</label>
			<input class="required" type="text" name="first-name" id="first-name"/>
			<span>(required)</span>
		</li>
		<li>
			<label for="last-name">Last Name</label>
			<input class="required" type="text" name="last-name" id="last-name"/>
			<span>(required)</span>
		</li>
		<li>
			How would you like to be contacted?(choose at least one method)
			<ul>
				<li>
					<label for="by-email"><input type="checkbox" name="by-contact-type" value="E-mail" id="by-email"/>by E-mail</label>
					<input class="contional" type="text" name="email" id="email" />
					<span>(required when corresponding checkbox checked)</span>				
				</li>
				<li>
					<label for="by-phone"><input type="checkbox" name="by-contact-type" value="phone" id="by-phone"/>by Phone</label>
					<input class="contional" type="text" name="phone" id="phone" />
					<span>(required when corresponding checkbox checked)</span>				
				</li>	
				<li>
					<label for="by-fax"><input type="checkbox" name="by-contact-type" value="fax" id="by-fax"/>by Fax</label>
					<input class="contional" type="text" name="fax" id="fax" />
					<span>(required when corresponding checkbox checked)</span>				
				</li>	
			</ul>		
		</li>
	</ol>
	<input type="submit" value="send" id="send"/>
</form>
</fieldset>

1.通常表单会用fieldset来构建。

fieldset:用于对表单中的元素进行分组并在文档中区别标出文本。它与窗口框架的行为有些相似。

legend: 在 fieldset 对象绘制的方框内插入一个标题。

由于legend的样式兼容性很差(这里我就不讲是怎么兼容的了),我们就用js把legend标签替换成h3标题标签


Js代码 复制代码

  1. <STRONG>var heading = $("legend","fieldset").remove().text();   
  2. $("<h3></h3>").text(heading).prependTo("fieldset");</STRONG> 
var heading = $("legend","fieldset").remove().text();
$("<h3></h3>").text(heading).prependTo("fieldset");


2.在这个联系表单中,必填字段都带有class=”require“以便应用样式和响应用户的输入;而每种联系方式的输入都带有class="conditional"。


首先清理必填字段的提示信息


Js代码 复制代码

  1. <STRONG>var requiredFlag = "*";   
  2. var requiredKey = $("input.required:first").next("span").text();   
  3. requiredKey = requiredFlag + requiredKey.replace(/^\((.+)\)$/,"$1");   
  4. var conditionalFlag = "**";   
  5. var contionalKey = $("input.contional:first").next("span").text();   
  6. contionalKey = conditionalFlag + contionalKey.replace(/^\((.+)\)$/,"$1");   
  7. $("<p></p>").addClass("field-key").append(requiredKey + "<br />").append(contionalKey).insertBefore("fieldset:first");   
  8. $(":input").filter(".required").next("span").text(requiredFlag).end().prev("label").addClass("req-label");   
  9. $(":input").filter(".contional").next("span").text(conditionalFlag);</STRONG> 
var requiredFlag = "*";
var requiredKey = $("input.required:first").next("span").text();
requiredKey = requiredFlag + requiredKey.replace(/^\((.+)\)$/,"$1");
var conditionalFlag = "**";
var contionalKey = $("input.contional:first").next("span").text();
contionalKey = conditionalFlag + contionalKey.replace(/^\((.+)\)$/,"$1");
$("<p></p>").addClass("field-key").append(requiredKey + "<br />").append(contionalKey).insertBefore("fieldset:first");
$(":input").filter(".required").next("span").text(requiredFlag).end().prev("label").addClass("req-label");
$(":input").filter(".contional").next("span").text(conditionalFlag);

设置两个标记变量requiredFlag和conditionalFlag,向每个必填的span中分别填入这两个变量。再把提示信息保存到另外两个变量requiredKey和contionalKey中,并且将每个标记与相应的信息(去掉了原括号)连接起来。


这里用了正则表达式以及replace方法。

.replace(/^\((.+)\)$/,"$1");

^:表示后面跟着的应该是字符串的开始位置。

\(\):原括号,\用于转义。

(.+):查找一个或多个同一行的任意字符。

$:字符串的结束位置。

$1:代表的是位于圆括号内部但不包含圆括号的所有字符。


由于必填是一个*号,可能不会立即吸引用户的注意力,所以还需要为每个必填字段的<label>添加class=“req-label”,让每个必填字段的<label>变成粗体


创建一个新的段落,把requiredKey和contionalKey添加到这个段落中,再将这个段落插入到联系表单的前面。


3.我们再围绕询问用户愿意使用哪种联系方式来进一步增强这组字段。因为只有当用户选择了相应的复选框之后,才需要填写后面的文字输入字段,所以可以在文档加载完成后首先隐藏他们。


Js代码 复制代码

  1. <STRONG>$("input.contional").each(function(){   
  2. var $thisInput = $(this);   
  3. var $thisFlag = $thisInput.next("span").hide();   
  4.     $thisInput.prev("label").find(":checkbox").click(function(){   
  5. if(this.checked){   
  6.             $thisInput.show().addClass("required");   
  7.             $thisFlag.show();   
  8.             $(this).parent("label").addClass("req-label");     
  9.         }   
  10. else{   
  11.             $thisInput.hide().removeClass("required").blur();   
  12.             $thisFlag.hide();   
  13.             $(this).parent("label").removeClass("req-label");   
  14.         }   
  15.         });    
  16. });</STRONG> 
$("input.contional").each(function(){
	var $thisInput = $(this);
	var $thisFlag = $thisInput.next("span").hide();
	$thisInput.prev("label").find(":checkbox").click(function(){
		if(this.checked){
			$thisInput.show().addClass("required");
			$thisFlag.show();
			$(this).parent("label").addClass("req-label");	
		}
		else{
			$thisInput.hide().removeClass("required").blur();
			$thisFlag.hide();
			$(this).parent("label").removeClass("req-label");
		}
        });	
});

当用户单击复选框时,需要检查复选框是否被选中;如果是,则显示文字输入字段,显示提示标记,然后再为对应的label添加加粗的样式。否则,隐藏条件元素并移除加粗样式。


4.表单验证

在通过jQuery向表单添加验证功能之前,必须记住一条重要的规则:客户端验证不能取代服务器端验证。同样,也不能依赖用户启用javascript。使用jQuery的客户端表单验证具有服务器端无法比拟的一个优势--即时反馈 。服务器端代码,无论是ASP、PHP,还是其他的什么,都需要重载页面才能生效。通过jQuery,可以在必填字段失去焦点(blur)或者用户按下某个键盘按键时,利用灵活的客户端代码实现验证功能

必填的验证

Js代码 复制代码

  1. <STRONG>$("input").blur(function(){   
  2.     $(this).parent("li").removeClass("warning").find("span.errorMessage").remove();   
  3. if($(this).is(".required")){   
  4. var $listItem = $(this).parent("li");   
  5. if(this.value == ""){   
  6. var errorMessage = "This is a required field";   
  7. if($(this).is(".contional")){   
  8.                   errorMessage += ", when its related checkbox is checked";    
  9.                 };   
  10.                 $("<span></span>").addClass("errorMessage").text(errorMessage).appendTo($listItem);   
  11.                 $listItem.addClass("warning");   
  12. return;   
  13.              }   
  14.         }   
  15. });</STRONG> 
$("input").blur(function(){
	$(this).parent("li").removeClass("warning").find("span.errorMessage").remove();
	if($(this).is(".required")){
		var $listItem = $(this).parent("li");
		if(this.value == ""){
			var errorMessage = "This is a required field";
			if($(this).is(".contional")){
			      errorMessage += ", when its related checkbox is checked";	
		        };
		        $("<span></span>").addClass("errorMessage").text(errorMessage).appendTo($listItem);
		        $listItem.addClass("warning");
		        return;
	         }
        }
});

格式的验证

Js代码 复制代码

  1. <STRONG>      if($(this).is("#email")){   
  2. var $listItem = $(this).parent("li");   
  3. if(this.value != " " && !/.+@.+\.[a-zA-Z]{2,4}$/.test(this.value)){   
  4. var errorMessage = "Please use proper e-mail format (e.g.joe@example.com)";   
  5.            }   
  6.            $("<span></span>").addClass("errorMessage").text(errorMessage).appendTo($listItem);   
  7.            $listItem.addClass("warning");   
  8.     }   
  9. if($(this).is("#phone")){   
  10. var $listItem = $(this).parent("li");   
  11. if(this.value != " " && !/86\-1[0-9]{10}$/.test(this.value)){   
  12. var errorMessage = "Please use proper phone format (86-13912312312)";   
  13.         }   
  14.         $("<span></span>").addClass("errorMessage").text(errorMessage).appendTo($listItem);   
  15.         $listItem.addClass("warning");   
  16.     }   
  17. if($(this).is("#fax")){   
  18. var $listItem = $(this).parent("li");   
  19. if(this.value != " " && !/0086\-[0-9]{3,4}\-[0-9]{8}$/.test(this.value)){   
  20. var errorMessage = "Please use proper phone format (0086-021-68869163)";   
  21.         }   
  22.         $("<span></span>").addClass("errorMessage").text(errorMessage).appendTo($listItem);   
  23.         $listItem.addClass("warning");   
  24.     }</STRONG> 
      if($(this).is("#email")){
	       var $listItem = $(this).parent("li");
	       if(this.value != " " && !/.+@.+\.[a-zA-Z]{2,4}$/.test(this.value)){
	              var errorMessage = "Please use proper e-mail format (e.g.joe@example.com)";
	       }
	       $("<span></span>").addClass("errorMessage").text(errorMessage).appendTo($listItem);
	       $listItem.addClass("warning");
	}
	if($(this).is("#phone")){
		var $listItem = $(this).parent("li");
		if(this.value != " " && !/86\-1[0-9]{10}$/.test(this.value)){
			var errorMessage = "Please use proper phone format (86-13912312312)";
		}
		$("<span></span>").addClass("errorMessage").text(errorMessage).appendTo($listItem);
		$listItem.addClass("warning");
	}
	if($(this).is("#fax")){
		var $listItem = $(this).parent("li");
		if(this.value != " " && !/0086\-[0-9]{3,4}\-[0-9]{8}$/.test(this.value)){
			var errorMessage = "Please use proper phone format (0086-021-68869163)";
		}
		$("<span></span>").addClass("errorMessage").text(errorMessage).appendTo($listItem);
		$listItem.addClass("warning");
	}

最终检查

实际上,我们有必要在用户提交表单时再检查一遍表单中的字段,这次是整体性的检查。通过表单上的.submit()时间处理程序,可以在所有必填字段上触发blur事件

Js代码 复制代码

  1. <STRONG>$("form:first").submit(function(){   
  2.     $("#submit-message").remove();   
  3.     $("input.required").trigger("blur");   
  4. var numWarnings = $(".warning",this).length;   
  5. if(numWarnings){   
  6. var fieldList = [];   
  7.         $(".warning label").each(function(){   
  8.             fieldList.push($(this).text());   
  9.         });   
  10.         $("<div></div>").attr({"id":"submit-message","class":"warning"}).append("Please correct errors with "+numWarnings+" fields:<br />").append("• " + fieldList.join("<br /> • ")).insertBefore("#send");   
  11. return false;   
  12.     }   
  13. });</STRONG> 
$("form:first").submit(function(){
	$("#submit-message").remove();
	$("input.required").trigger("blur");
	var numWarnings = $(".warning",this).length;
	if(numWarnings){
		var fieldList = [];
		$(".warning label").each(function(){
			fieldList.push($(this).text());
		});
		$("<div></div>").attr({"id":"submit-message","class":"warning"}).append("Please correct errors with "+numWarnings+" fields:<br />").append("• " + fieldList.join("<br /> • ")).insertBefore("#send");
		return false;
	}
});


  • 58352a95-1604-3e34-b4e7-2a619ec200a5-thumb
  • 大小: 68.8 KB
  • 5a6d8a84-9edf-381b-bc69-407b39e6d982-thumb
  • 大小: 56.2 KB