很多时候在网站上注册时,我们会发现,注册表单通常需要检查用户名和电子邮件地址的可用性;从而确保用户之间不拥有相同的用户名和电子邮件地址;一些网站喜欢在用户提交填写的用户信息时,做信息可用性的检查,而一些网站会做实时的用户名和电子邮件地址可用性检查,例如:“用户名”文本框失去焦点时;就用户体验来说,实时的用户信息检查用户体验效果更好,而不是在表单提交后,告诉用户信息不符合系统要求。
下面截图是新浪微博的注册界面,它采用的是实时的用户信息检查,如:手机号码和用户名等信息。
图1新浪微博注册表单
1、正文
假设,现在要求我们实现一个注册界面并且它采用实时方式检查用户信息是否符合系统的要求。
其中,注册界面包含:用户名,邮件地址,密码和微博地址等信息;实时检查:当文本框失去焦点时对信息进行实时检查,例如:“用户名”文本框失去焦点时,触发页面发送Ajax请求,到数据库中用户是否可用,接着把查询结果返回到前端页面中。
对于表单输入检查,我们将使用前一博文《自定义jQuery插件Step by Step》中,自定义表单信息检查插件对输入信息进行检查。
图2注册验证过程
注册表单设计
现在,让我们定义注册表单,它包含:用户名,邮件地址,密码和微博地址等信息,由于时间的关系,我们已经把注册表单界面的定义好了,具体实现代码如下:
<body> <div id="Div1"> <!-- Start Sign Up Form --> <form action="#signup-form" id="Form1"> <h2> Sign Up</h2> <fieldset> <div class="fieldgroup"> <label for="name"> Name</label> <input class="form_element" type="text" name="name" validation="required nameAvailable" /> <span class='availability_status'></span> </div> <div class="fieldgroup"> <label for="email"> Email</label> <input class="form_element" type="text" name="email" validation="email" /> <span></span> </div> <div class="fieldgroup"> <label for="password"> Password</label> <input class="form_element" type="password" name="password" validation="password" /> <span></span> </div> <div class="fieldgroup"> <label for="weibo"> Weibo</label> <input class="form_element" type="text" name="weibo" validation="url" /> <span></span> </div> <div class="fieldgroup"> <input type="submit" class="submit" value="Sign up"> <span></span> </div> </fieldset> <div class="fieldgroup"> <p> Already registered"http://www.cnblogs.com/rush">Sign in</a>.</p> </div> </form> <!-- End Sign Up Form --> </div> </body>
上面,我们实现了注册表单,它包含:用户名,邮件地址,密码和微博地址文本框,当“用户名”失去焦点时,发送Ajax请求实时检查用户名是否可用,并且动态地加载图片表示检查中和相应的检查结果。
图3注册表单
jQuery Validation插件
现在,我们需要修改一下前一博文中定义的表单检查控件,需要增加用户名检查和文本框失去焦点事件(blur event)。
首先,我们在Validation类型中,增加用户名检查方法,由于用户检查是通过发送Ajax请求,然后到数据库中查询是否存在该用户名来确定该用户名是否可用。
nameAvailable: { check: function(value) { if (value) { var dataString = 'username=' + value; var result; // Checking availability... // Loads checking image. $(".availability_status").html('<img src="/UploadFiles/2021-04-02/loader.gif">上面,我们完成了在Validation类型中增加nameAvailable()方法,它通过发送异步Ajax请求来检查用户名是否可用,在检查的过程中,在输入框右边动态地加载图片来表示检查中,当检查结束加载相应的图片表示用户是否可用。
接下来,我们将添加focus和blur事件,当文本框得到焦点时触发focus事件,提示输入信息的要求,当文本框失去焦点时触发blur事件,发生实时Ajax请求,例如:检查用户名是否可用。
由于,事件方法应该是Field类型公开的方法,确实我们也不想为每个Field对象都定义自己事件方法,所以我们通过原型链的方式公开事件方法focus()和blur(),具体实现如下:
// The prototype of Field type. Field.prototype = { // Public method. attach: function(event) { // The object refers to Field object. var obj = this; // When field lost focus, then invoked the validate method. if (event == "blur") { obj.field.bind("blur", function() { return obj.validate(); }); } // When field got focus, then invoked the hint method. if (event == "focus") { obj.field.bind("focus", function() { return obj.hint(); }); } } }我们给Field的原型链添加了事件响应事件blur和focus,当失去焦点时触发Field的vlidate()方法,获得焦点时触发Field的hint()方法。
数据表设计
前面,我们提到注册表单的用户名可用性检查设计是通过发送Ajax请求,然后到数据库中查询用户名是否存在来确定用户名的可用性。
接下来,我们添加数据库表jk_user用来存储用户信息,它包括用户名、密码(注意:这里没有考虑隐私信息的加密存储)、显示名称和注册日期等,具体设计如下:
-- ============================================= CREATE TABLE [dbo].[jk_users]( -- This is the reference to Users table, it is primary key. [ID] [bigint] IDENTITY(1,1) NOT NULL, [user_login] [varchar](60) NOT NULL, [user_pass] [varchar](64) NOT NULL, [user_nicename] [varchar](50) NOT NULL, [user_email] [varchar](100) NOT NULL, [user_url] [varchar](100) NOT NULL, -- This field get the default from function GETDATE(). [user_registered] [datetime] NOT NULL CONSTRAINT [DF_jk_users_user_registered] DEFAULT (getdate()), [user_activation_key] [varchar](60) NOT NULL, [user_status] [int] NOT NULL CONSTRAINT [DF_jk_users_user_status] DEFAULT ((0)), [display_name] [varchar](250) NOT NULL ) ajaxform2图4数据表设计
服务端设计
前面,我们实现了用户表的设计,由于注册表单通过发送Ajax请求访问服务器端公开的方法,然后通过该公开方法访问数据库。
接下来,我们定义用户表(jk_user)的数据库访问对象(DAO),它包含方法IsAvailableUser()用来检查用户名是否可用,具体的实现如下:
/// <summary> /// The user dao manager. /// </summary> public class UserManager { private const string Query = "SELECT user_login, user_email, user_url FROM jk_users WHERE (user_login = @user_login)"; /// <summary> /// Initializes a new instance of the <see cref="UserManager"/> class. /// </summary> public UserManager() { } /// <summary> /// Determines whether the user is available or not, with specified username. /// </summary> /// <param name="userName">Name of the user.</param> /// <returns> /// <c>true</c> if is available user; otherwise, <c>false</c>. /// </returns> public bool IsAvailableUser(string userName) { using (var con = new SqlConnection(ConfigurationManager.ConnectionStrings["SQLCONN2"].ToString())) using (var com = new SqlCommand(Query, con)) { // Pass user_login parameter to sql statement. com.Parameters.Add("@user_login", SqlDbType.VarChar).Value = userName; com.Connection.Open(); return !com.ExecuteReader().HasRows; } } }现在,我们完成了数据库访问对象UserManager,它包含方法IsAvailableUser()来检查用户是否可用,如果该用户名已经存在返回false,反之返回true。
接下来,我们需要实现服务器端类UserService,让客户端通过它来调用UserManager中的IsAvailableUser()方法,首先我们创建一般处理程序(ASHX文件),实现ProcessRequest()方法,具体实现如下:
/// <summary> /// The user availability check service. /// </summary> public class UserService : IHttpHandler { public void ProcessRequest(HttpContext context) { // Response json type. context.Response.ContentType = "application/json"; context.Response.Charset = "utf-8"; var manager = new UserManager(); string userName = context.Request.QueryString["username"]; // Checks the username empty or not. if (string.IsNullOrEmpty(userName)) { throw new Exception("Username can't be empty"); } // Invokes the IsAvailableUser method. var result = manager.IsAvailableUser(userName); // Serializes data to json format. var json = new DataContractJsonSerializer(result.GetType()); json.WriteObject(context.Response.OutputStream, result); } // Whether can resuable by other handler or not. public bool IsReusable { get { return true; } } }大家注意到UserService类实现了IHttpHandler接口,该接口包含一个方法ProcessRequest()方法和一个属性IsReusable;ProcessRequest()方法用于处理入站的Http请求,在默认情况下,UserService类把Response内容类型定义为application/json,这样我们就可以把数据通过JSON格式进行传输;IsReusable属性表示相同的处理程序是否可以用于多个请求,这里我们设置为true,那么处理程序可以用于多个请求。
前端实现
注册表单在检查用户名时会在输入框的右边动态地加载图片,这里我们使用CSS Sprite技巧实现图片的动态加载。
当页面加载时,不是加载每个单独图片,而是一次加载整个组合图片。这是一个了不起的改进,因为我们只需发送一个HTTP请求获取组合图片就OK了,它大大减少了HTTP请求的次数,减轻服务器压力,同时缩短了悬停加载图片所需要的时间延迟,使效果更流畅,不会停顿。
这里,我们使用可以一个在线的工具SpritePad设计组合图片和生成相应的CSS代码。
图5组合图片
上面,我们已经准备好组合图片了,接下来我们添加CSS代码动态加载“正确”和“出错”图片,具体实现如下:
/*CSS Sprite*/ /*Loads tick picture*/ .tick { width: 17px; height: 17px; margin: 6px 0 0; float: right; background: url(../images/tipicon.png); background-position: 0px -32px; display: block; /*text-decoration: none; vertical-align:middle;*/ } /*Loads error picture*/ span.error { width: 17px; height: 17px; margin: 6px 0 0; float: right; background: url(../images/tipicon.png); background-position: 0px -15px; display: block; /*text-decoration: none; vertical-align:middle;*/ }接着,我们在nameAvailable()方法中的Ajax方法添加文件“UserService.ashx”请求,并传递用户名给服务器;在数据库中查询用户名是否已经存在,存在返回“false”,否则返回“true”。
// Sends ajax request to check the name is available or not. $.ajax({ type: "GET", url: "UserService.ashx", data: dataString, success: function(data) { // When the checking completed, then loaded corresponding css style. $('.availability_status').ajaxComplete(function(event, request, settings) { if (data == false) { $('.availability_status').html(''); $('.availability_status').removeClass('tick'); $('.availability_status').addClass('error'); return true; } else { $('.availability_status').html(''); $('.availability_status').removeClass('error'); $('.availability_status').addClass('tick'); return false; } }); } });最后,我们在注册表单中添加调用自定义验证控件的jQuery代码,具体实现如下:
<script type="text/javascript"> // Sets display image size. pic = new Image(16, 16); pic.src = "loader.gif"; $(function() { // jQuery DOM ready function. // Get the form object. var signUpForm = $("#signup-form"); // Invokes the validation method. signUpForm.validation(); }); </script>图6用户注册界面
如果大家还想深入学习,可以点击两个精彩的专题:jquery表单验证大全 JavaScript表单验证大全
本文主要介绍了Ajax注册表单的设计,通过发送Ajax请求方式实时地检查用户名的可用性,并且使用了自定义的表单验证插件检查输入信息的正确性。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新日志
- 【雨果唱片】中国管弦乐《鹿回头》WAV
- APM亚流新世代《一起冒险》[FLAC/分轨][106.77MB]
- 崔健《飞狗》律冻文化[WAV+CUE][1.1G]
- 罗志祥《舞状元 (Explicit)》[320K/MP3][66.77MB]
- 尤雅.1997-幽雅精粹2CD【南方】【WAV+CUE】
- 张惠妹.2007-STAR(引进版)【EMI百代】【WAV+CUE】
- 群星.2008-LOVE情歌集VOL.8【正东】【WAV+CUE】
- 罗志祥《舞状元 (Explicit)》[FLAC/分轨][360.76MB]
- Tank《我不伟大,至少我能改变我。》[320K/MP3][160.41MB]
- Tank《我不伟大,至少我能改变我。》[FLAC/分轨][236.89MB]
- CD圣经推荐-夏韶声《谙2》SACD-ISO
- 钟镇涛-《百分百钟镇涛》首批限量版SACD-ISO
- 群星《继续微笑致敬许冠杰》[低速原抓WAV+CUE]
- 潘秀琼.2003-国语难忘金曲珍藏集【皇星全音】【WAV+CUE】
- 林东松.1997-2039玫瑰事件【宝丽金】【WAV+CUE】