Trước khi bắt đầu với bài viết này, tớ đã phải gặp nhiều vấn đề rắc rối khi đăng ký thành viên tại một số diễn đàn, website
. Khi đăng ký thành viên, quá trình thông báo lỗi của nó khiến cho tớ rất bực bội (có thể là bỏ lun, không đăng ký nữa). Vì mổi lần có 1 lỗi nào đó thì dữ liệu được viết trước đó mất hết cả và thế là phải "còng tay" viết lại. Vấn đề ở đây có thể là trùng tên username, password strength, blah, blah... cũng đã có rất nhiều bạn đã gặp và đã tìm cách khắc phục bằng AJAX. Ở bài viết này tớ sẽ giới thiệu cách để validate form dùng AJAX of jQuery.
What can we do?
Live username checking
Trước hết, tớ cần có 1 server base để có thể checking username live. Đoạn mã PHP đơn giản dưới đây sẽ được gọi bởi AJAX.
<?php
// giả lập users hiện có trong db
$users_taken = array('kenphan',
'mjt',
'uoon',
'tk',
'tg',
'johnphan',
'quachtrananh',
'example',
'test'
);
// dữ liệu username được gởi bởi user
$username = $_POST['username'];
// checking username
$valid = check_username($username, $users_taken);
// dùng json_encode function để encode từ array sang JSON
echo json_encode($valid);
// function check validate username
function check_username($username, $users_taken) {
$username = trim($username); // strip any white space
$response = array(); // our response
// nếu chưa nhập username
if (!$username) {
$response = array(
'ok' => false,
'msg' => "Please specify a username");
} else if (strlen($username) < 2) {
$response = array(
'ok' => false,
'msg' => "Your username must consist of at least 2 characters.");
// nếu username không có các giá trị a-z or '.', '-', '_' thì nó not valid
} else if (!preg_match('/^[a-z0-9.-_]+$/', $username)) {
$response = array(
'ok' => false,
'msg' => "Your username can only contain ".
"alphanumerics and period, dash and underscore (.-_)");
// nếu username đã có người sử dụng, ở đây giả sử là hàm username_taken()
} else if (in_array($username, $users_taken)) {
$response = array(
'ok' => false,
'msg' => "The selected username is not available");
// everything okay
} else {
$response = array(
'ok' => true,
'msg' => "This username is free");
}
return $response;
}
?>
Ở đoạn mã trên, các bạn để ý sẽ thấy rằng hàm check_username() sẽ trả về kiểu dữ liệu là array() và convert nó sang JSON. That's good, bởi vì chúng ta dùng AJAX nên sử dụng JSON là cách tốt nhất ở đây.
jQuery code:
$(document).ready(function () {
// Username validation logic
var validateUsername = $('#validateUsername');
// event keyup function
$('#username').keyup(function () {
/* cache the 'this' instance as we need
access to it within a setTimeout, where 'this' is set to 'window' */
var t = this;
/* only run the check if the username
has actually changed - also means we skip meta keys */
if (this.value != this.lastValue) {
/* the timeout logic means the ajax doesn't
fire with *every* key press, i.e. if the user holds down
a particular key, it will only fire when the release the key.*/
if (this.timer) {
clearTimeout(this.timer);
}
// show our holding text in the validation message space
validateUsername
.removeClass('error')
.removeClass('success')
.html('<img src="loader.gif" height="16" width="16" />'+
'checking availability...');
// fire an ajax request in 1/5 of a second
this.timer = setTimeout(function () {
$.ajax({
url: 'username.php',
data: { username: t.value },
dataType: 'json',
type: 'post',
success: function (j) {
// checking debug
if(!j.ok) {
validateUsername.addClass('error');
} else {
validateUsername.addClass('success');
}
/* put the 'msg' field from the $resp array from
check_username (php code) in to the validation message */
validateUsername.html(j.msg);
}
});
}, 200);
/* copy the latest value to avoid sending
requests when we don't need to */
this.lastValue = this.value;
}
});
});
-->
Chạy jQuery khi document được load
$(document).ready(function () {
Tạo một biến cache của span validateUsername tag, nó sẽ giúp tối ưu hoá code (it’s a good practise to have).
var validateUsername = $('#validateUsername');
Khi có sự kiện keyup tại input username
$('#username').keyup(function () {
Chỉ cho check nếu username có dữ liệu được thay đổi (also means we skip meta keys)
if (this.value != this.lastValue) {
Nếu user holds down một phím nào đó, nó chỉ thực thi khi được thả ra
if (this.timer) {
clearTimeout(this.timer);
}
Span #validateUsername tag sẽ được gọi và remove 2 class là error và success và thanh loader được hiển thị
validateUsername
.removeClass('error')
.removeClass('success')
.html('<img src="loader.gif" height="16" width="16" /> checking availability...');
Ajax được gọi với 200 seconds
this.timer = setTimeout(function () {
Còn đây là hàm AJAX của jQuery. Request username.php và dữ liệu được trả về là false thì Span #validateUsername tag sẽ được addClass là error. Ngược lại là success.
$.ajax({
url: 'username.php',
data: { username: t.value },
dataType: 'json',
type: 'post',
success: function (j) {
// checking debug
if(!j.ok) {
validateUsername.addClass('error');
} else {
validateUsername.addClass('success');
}
// put the 'msg' field from the $resp array from
//check_username (php code) in to the validation message
validateUsername.html(j.msg);
}
});
Cuối cùng, đặt giá trị hiện tại đến một bộ nhớ cache this.lastValue để đảm bảo rằng chúng ta đã bỏ qua các phím meta (ở trên).
bài viết đến đây là kết thúc, chả có gì khó khăn phải không nào ?! Từ bài viết này, bạn có thể viết được những ứng dụng khác tương tự như thế. Chúc bạn thành công !
... if(j.ok) { window.location.href = url } ...