遇到使用者註冊等情況時,如果等使用者輸入所有資訊,點擊註冊按鈕提交後,再驗證輸入是否正確,體驗很不好,而且很浪費使用者的時間,增加註冊成本,這裡提供一個例子,示範了怎麼使用ajax進行單步驗證,使用thinkphp 3.2架構,環境WAMPServer 2.4,版本PHP 5.4.16+ Apache 2.4.4+ MySql 5.6.12
一、資料庫設計:
資料庫名 thinkphp
表名 tp_user 其中tp_是表首碼,可以在config.php中定義,動作表的時候只用user就行
CREATE TABLE IF NOT EXISTS `tp_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(30) NOT NULL,
`password` varchar(255) NOT NULL,
`email` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
二、頁面設計
三、HTML部分
<form method="post" action="{:U('Index/register')}">
<div class="form-element">
<label class="left">使用者名稱:</label>
<div>
<input type="text" name="username" id="username" value="" />
<div id="tooltip1" class="tooltip-info prompt">
<span class="tooltip-icon-border"></span>
<span class="tooltip-icon-bg"></span>
<span class="state"></span>
<span id="mess1" class="mess"></span>
</div>
</div>
</div>
<div class="form-section">
<div class="form-element">
<label>密碼:</label>
<div>
<input type="password" name="password" id="password" value="" />
<div id="tooltip2" class="tooltip-info prompt">
<span class="tooltip-icon-border"></span>
<span class="tooltip-icon-bg"></span>
<span class="state"></span>
<span id="mess2" class="mess"></span>
</div>
</div>
</div>
<div class="form-element">
<label>確認密碼:</label>
<div>
<input type="password" name="repassword" id="repassword" value="" />
<div id="tooltip22" class="tooltip-info prompt">
<span class="tooltip-icon-border"></span>
<span class="tooltip-icon-bg"></span>
<span class="state"></span>
<span id="mess22" class="mess"></span>
</div>
</div>
</div>
<div class="form-element">
<label>郵箱:</label>
<div>
<input type="text" name="email" id="email" value="" />
<div id="tooltip3" class="tooltip-info prompt">
<span class="tooltip-icon-border"></span>
<span class="tooltip-icon-bg"></span>
<span class="state"></span>
<span id="mess3" class="mess"></span>
</div>
</div>
</div>
</div>
<div>
<div>
<button type="submit" name="c12" id="submit1"
class="button-action large">註冊</button>
</div>
</div>
</form>
四、thinkphp自動驗證
相關資料參考:http://doc.thinkphp.cn/manual/auto_validate.html
在UserModel定義驗證規則
protected $_validate=array(
array('username','require','使用者名稱不可為空!'),
array('username','','使用者名稱已經存在',0,'unique',1),
array('username','/^[a-zA-Z][a-zA-Z0-9_]{1,19}$/','使用者名稱不合法!'),
array('email','require','郵箱不可為空!'),
array('email','email','郵箱格式不正確!'),
array('email','','該郵箱已經註冊過!',0,'unique',1),
);
protected $_auto = array(
array('password', 'md5', 1, 'function'), // 對password欄位在新增的時候使md5函數處理
);
五、 使用ajax
使用者輸入使用者名稱後,當輸入框失去焦點時會觸發blur事件,可以在這時候驗證使用者名稱輸入是否正確
jQuery.post( url, [data], [callback], [type] ) :使用POST方式來進行非同步請求
參數:
url (String) : 發送請求的URL地址.
data (Map) : (可選) 要發送給伺服器的資料,以 Key
alue 的索引值對形式表示。
callback (Function) : (可選) 載入成功時回呼函數(只有當Response的返回狀態是success才是調用該方法)。
type (String) : (可選)官方的說明是:Type of data to be sent。其實應該為用戶端請求的類型(JSON,XML,等等)
$('#username').blur(
function() {
var username = $(this).val();
$.post("index.php/Home/Index/checkName", {
'username' : username//前一個username需要跟UserModel對應,即跟資料庫欄位對應
}, function(data) {
if (data == 0) {
error['username'] = 0;
$('#tooltip1').attr('class',
'tooltip-info visible-inline success');
} else {
error['username'] = 1;
$('#tooltip1').attr('class',
'tooltip-info visible-inline error');
$('#mess1').html(data);
}
})
});
密碼,重複密碼,郵箱驗證類似
驗證郵箱的時候需要注意,如果使用者輸入郵箱後,立刻點擊註冊按鈕,這時候會同時執行註冊按鈕的click事件,郵箱輸入框的blur事件,由於郵箱驗證是$.post是非同步,post還沒有執行完,click事件裡 error['email']=1,不會執行$('#submit1').submit();所以這時候再設定一個標誌error['submit'] = 0;0表示點擊過註冊按鈕,預設為1,在郵箱blur回呼函數中判斷error['submit'] 是否等於0,即判斷是否點擊過,如果點擊過,提交表單,如果沒點擊過,只需要驗證郵箱。
使用者輸入郵箱後,滑鼠在螢幕上其他地方點擊,只執行blur,跟使用者名稱,密碼情況一樣。
六、伺服器處理
public function checkName() {
$user = D ( 'user' );
if (! $user->create ()) {
exit ( $user->getError () );
} else {
echo 0;//這是回傳給$.post的資料,對應上面的data
}
}
以上是單步驗證使用者名稱的方法,下面來看怎麼把所有資料提交給伺服器
七、 把所有資料提交給伺服器
通過上面的html代碼注意到這裡用了一個form,以post方式提交表單,action指向伺服器能處理的地址
點擊註冊按鈕時,先判斷所有輸入是否正確,如果正確,才執行提交表單
$('#submit1').click(function() {
if ($('#username').val() == '') {
$('#tooltip1').attr('class', 'tooltip-info visible-inline error');
$('#mess1').html("使用者名稱不可為空!");
}
if ($('#password').val() == '') {
$('#tooltip2').attr('class', 'tooltip-info visible-inline error');
$('#mess2').html("密碼不可為空!");
}
if ($('#repassword').val() == '') {
$('#tooltip22').attr('class', 'tooltip-info visible-inline error');
$('#mess22').html("確認密碼不可為空!");
}
if ($('#email').val() == '') {
$('#tooltip3').attr('class', 'tooltip-info visible-inline error');
$('#mess3').html("郵箱不可為空!");
}
if (error['username'] == 1) {
var scroll_offset = $("#tooltip1").offset(); // 如果使用者名稱驗證失敗,螢幕會滾動到使用者名稱的位置,讓使用者重新輸入
$("body,html").animate({
scrollTop : scroll_offset.top
// 讓body的scrollTop等於pos的top,就實現了滾動
}, 0);
return false;
} else if (error['password'] == 1) {
return false;
} else if (error['email'] == 1) {
error['submit'] = 0;
return false;
} else {
$('#submit1').submit();
return true;
}
});
伺服器端register方法接收所有資料,如果成功跳轉到Home/index頁面,如果失敗,跳轉到錯誤提示頁面
public function register() {
$user = D ( 'user' );
if (! $user->create ()) {
dump ( $user->getError () );
}
$uid = $user->add ();
if ($uid) {
$_SESSION ['username'] = $_POST ['username'];
$this->redirect ( 'Home/index' );
} else {
$this->error ( "註冊失敗!" );
}
}
八、config.php配置
<?php
return array(
/* 資料庫配置 */
'DB_TYPE' => 'mysql', // 資料庫類型
'DB_HOST' => '127.0.0.1', // 伺服器位址
'DB_NAME' => 'thinkphp', // 資料庫名
'DB_USER' => 'root', // 使用者名稱
'DB_PWD' => '123', // 密碼
'DB_PORT' => '3306', // 連接埠
'DB_PREFIX' => 'tp_', // 資料庫表首碼
);