Khi nghĩ về các ứng dụng Web 2.0, bạn thường nghĩ về vẻ đẹp quyến rũ nhất trong số các ứng dụng đó: video của YouTube, bản đồ cuộn über-cool thú vị của của Google Maps, chức năng định vị-địa lý trong Flikr. Tuy nhiên, trong các trang web như vậy bạn thường bỏ sót biểu mẫu HTML nhỏ bé đã trải qua một phép biến đổi lớn nhờ tính phổ biến của công nghệ Ajax.
Trong bài viết này, tôi chỉ cho bạn cách sử dụng thư viện JavaScript prototype.js để giải quyết các vấn đề trải nghiệm chung của người dùng khi bạn tăng thêm các biểu mẫu với mã Ajax.
Đệ trình biểu mẫu Ajax đơn giản
Bắt đầu với một biểu mẫu nào đó thực sự đơn giản: một biểu mẫu đăng ký có nhiều trường mà bạn muốn đệ trình với Ajax thay vì sử dụng đường dẫn đăng lên mạng của biểu mẫu thông thường. Trang các biểu mẫu đơn giản này như trong Liệt kê 1.
Liệt kê 1. index.html
<html>
<head>
<script src="prototype.js"></script>
</head>
<body>
<form id="myform">
<table>
<tr><td>First</td><td><input type="text" name="first"></td></tr>
<tr><td>Last</td><td><input type="text" name="last"></td></tr>
<tr><td>Email</td><td><input type="text" name="email"></td></tr>
</table>
<input type="button" onclick="dosubmit()" value="Submit">
</form>
<div id="result" style="padding:5px;">
</div>
<script>
function dosubmit( ) {
new Ajax.Updater( 'result', 'add.php', { method: 'post',
parameters: $('myform').serialize() } );
$('myform').reset();
}
</script>
</body>
</html>
|
Ở đầu tệp này, tôi đưa vào tệp JavaScript prototype.js, sẽ làm tất cả công
việc Ajax cho tôi. Sau đó là một biểu mẫu HTML truyền thống có ba trường:
đầu tiên (first), cuối cùng (last) và thư điện tử
(email). Phía dưới là nút đệ trình biểu mẫu khi sử dụng hàm JavaScript
dosubmit().
Hàm dosubmit() này sử dụng lớp
Ajax.Updater để gửi dữ liệu tới kịch bản lệnh
add.php. Sau đó, bạn có thêm các tùy chọn cho cuộc gọi. Trong trường hợp
này, tôi thiết lập phương thức đệ trình để post
(đăng bài) và thêm các tham số từ biểu mẫu bằng cách sử dụng phương thức
serialize() trên biểu mẫu. Phương thức
serialize() này không phải là mã JavaScript
tiêu chuẩn: Thư viện JavaScript cung cấp nó.
Mục đầu tiên trong cuộc gọi đến Ajax.Updater là
mã định danh ID của thẻ <div>, nhận các
mã HTML mà kịch bản lệnh add.php trả về . Đó là cách dễ nhất để nhận được
thông báo trả về cho người dùng những gì đã xảy ra khi người dùng đã nhấn
nút.
Kịch bản lệnh add.php được chỉ ra trong Liệt kê 2.
Liệt kê 2. Kịch bản lệnh add.php
Thanks <?php echo( $_POST['first'] ) ?> <?php echo( $_POST['last'] ) ?>!
|
Tất cả những thứ mà kịch bản lệnh add.php làm là sự phản hồi lại những gì đã được đăng theo biểu mẫu này. Trong thực tế, việc này có thể sẽ thêm một bản ghi vào cơ sở dữ liệu, nhưng bạn có thể tự mình quản lý loại công việc logic nghiệp vụ đó.
Lần đầu tiên nạp biểu mẫu này, tôi thấy nó giống như Hình 1 trong trình duyệt của tôi.
Hình 1. Một biểu mẫu Ajax đơn giản
Rồi tôi nhấn nút Submit (Đệ trình), để gửi dữ liệu trong biểu mẫu tới trang web và tôi nhận được HTML trả về từ trang add.php bên phải phía dưới nút Submit, như trong Hình 2.
Hình 2. Đáp ứng sau khi đệ trình
Một sự thay đổi khác trên các biểu mẫu với Ajax là biểu mẫu điền-tự động, cập nhật các giá trị trường tùy thuộc vào giá trị của một số trường chủ chốt — ví dụ, gõ mã định danh ID của khách hàng, nhấn một nút và sau đó nhận được các bản ghi hiện tại của khách hàng trong các trường khác.
Kiểu biểu mẫu điền-tự động này được chỉ ra trong Liệt kê 3.
Liệt kê 3. index.html
<html>
<head>
<script src="prototype.js"></script>
</head>
<body>
<form id="myform">
<table>
<tr><td>ID</td><td><input
type="text" name="id"></td></tr>
<tr><td>First</td><td><input type="text"
name="first" id="elFirst"></td></tr>
<tr><td>Last</td><td><input type="text"
name="last" id="elLast"></td></tr>
<tr><td>Email</td><td><input type="text"
name="email" id="elEmail"></td></tr>
</table>
<input type="button" onclick="dofill()" value="Fill Fields">
</form>
<script>
function dofill( ) {
new Ajax.Updater( 'result', 'getdata.php',
{ method: 'post', parameters: $('myform').serialize(),
onSuccess: function( transport ) {
$('elFirst').value = transport.responseXML.getElementsByTagName('first')
[0].firstChild.nodeValue;
$('elLast').value = transport.responseXML.getElementsByTagName('last')
[0].firstChild.nodeValue;
$('elEmail').value = transport.responseXML.getElementsByTagName('email')
[0].firstChild.nodeValue;
} } );
}
</script>
</body>
</html>
|
Tôi đã thêm một trường mới có tên là ID vào biểu mẫu ban đầu trong
Liệt kê 1. Đó là nơi bạn đưa vào mã định danh ID
của khách hàng. Sau đó, hàm dofill() mới gọi
trang getdata.php, trả về mã XML có tên, họ và địa chỉ e-mail với ID của
khách hàng cụ thể.
Trình xử lý onSuccess mà tôi gửi tới cuộc gọi
Ajax.Updater sử dụng các hàm DOM (Document
Object Model – Mô hình đối tượng tài liệu) nguyên gốc có sẵn trong tất cả
các trình duyệt để bẻ khóa dữ liệu XML đã tải về. Rồi nó thiết lập giá trị
của các mục elFirst,
elLast và
elEmail <input> cho các giá trị được trả
về trong XML.
Trang getdata.php như chỉ ra trong Liệt kê 4.
Liệt kê 4. getdata.php
<?php
header( "content-type: text/xml" );
$first = ' ';
$last = ' ';
$email = ' ';
if ( $_POST['id'] == '1' )
{
$first = 'Jack';
$last = 'Herrington';
$email = 'jherr@pobox.com';
}
?>
<data>
<first><?php echo( $first ) ?></first>
<last><?php echo( $last ) ?></last>
<email><?php echo( $email ) ?></email>
</data>
|
INó thực sự chỉ là một phương thức rẽ nhánh của mã, như thường lệ gọi cơ sở dữ liệu để nhận được tên, họ và địa chỉ e-mail của bản ghi cụ thể.
Lần đầu tiên vào trang này, tôi thấy như Hình 3.
Hình 3. Biểu mẫu điền vào
Rồi tôi gõ 1 vào trường ID và nhấn
Fill Fields (Điền vào các trường) để chuyển sang trang
getdata.php để có được tên, họ và địa chỉ e-mail và cập nhật các trường
tương ứng. Điều này được thể hiện trong Hình 4.
Hình 4. Kịch bản lệnh điền vào các trường dựa trên ID
Với sự khéo tay về Ajax tiếp theo của mình, tôi tạo ra một danh sách cần làm để cập nhật đúng chỗ.
Một trong những trình diễn phổ biến với Ruby on Rails là danh sách cần làm để cập nhật đúng chỗ. Điều đó có nghĩa là danh sách các mục này ở đầu trang và có một hộp văn bản ở dưới danh sách đó. Khi tôi gõ một cái gì đó vào hộp văn bản và nhấn vào Submit, danh sách ở đầu trang cập nhật mục mới mà không cần thay đổi trang. Và hộp văn bản mà tôi đã gõ văn bản vào sẽ thiết lập lại để cho tôi có thể dễ dàng thêm vào thứ gì đó.
Đây thực sự là một thủ thuật hết sức khó khăn, vì vậy tôi đã tính đưa ra cách thực hiện nó trong PHP. Trang này với danh sách cần làm sẽ được chỉ ra trong Liệt kê 5.
Liệt kê 5. index.php
<html>
<head>
<script src="prototype.js"></script>
</head>
<body>
<div id="result" style="padding:5px;">
<?php
$fh = fopen( 'list.txt', 'r' );
while( $str = fgets( $fh ) ) {
?>
<?php echo( $str ); ?><br/>
<?php
}
?>
</div>
<form id="myform">
<input type="text" name="todo">
</form>
<input type="button" onclick="dosubmit()" value="Submit">
<script>
function dosubmit( ) {
new Ajax.Updater( 'result', 'add.php',
{ method: 'post', parameters: $('myform').serialize() } );
$('myform').reset();
}
</script>
</body>
</html>
|
Thay vì giữ danh sách cần làm trong một cơ sở dữ liệu, tôi chỉ cần sử dụng
một tệp văn bản phẳng gọi là list.txt để lưu trữ các mục của danh
sách đó trên mỗi dòng. Vì vậy, để đặt danh sách đó ở đầu trang, tôi chỉ
cần mở tệp này và đọc từng dòng trong thẻ tag
<div> với mã định danh ID của
result.
Dưới đó là biểu mẫu có mục nhập văn bản cho mục cần làm. Và ở dưới
đó là nút gọi hàm JavaScript
dosubmit(). Hàm JavaScript đó sử dụng lớp
Ajax.Updater để gọi trang add.php, thêm vào mục
đó và trả về danh sách mới với mục đã viết thêm vào nó.
Kịch bản lệnh Add.php này được chỉ ra trong Liệt kê 6.
Liệt kê 6. add.php
<?php
$total = '';
$fh = fopen( 'list.txt', 'r' );
while( $str = fgets( $fh ) ) {
?>
<?php echo( $str ); ?><br/>
<?php
$total .= $str;
}
if ( array_key_exists( 'todo', $_POST ) )
{
?>
<?php echo( $_POST['todo'] ); ?><br/>
<?php
$fh = fopen( 'list.txt', 'w' );
fwrite( $fh, $total."\n".$_POST['todo'] );
fclose( $fh );
}
?>
|
Danh sách ngờ nghệch của tôi về các mục cần làm được chỉ ra trong Liệt kê 7.
Liệt kê 7. list.txt
Get swim goggles
Practice swimming
Swim in race
|
Lần đầu tiên vào trang này, tôi thấy như Hình 5.
Hình 5. Chuẩn bị thêm một mục cần làm
Tôi gõ Finish in record time (kết thúc thời gian
của bản ghi), rồi nhấn vào Submit. Sau đó, không cần làm mới một
trang , tôi thấy kết quả như trong Hình 6.
Hình 6. Trang này sau khi chèn một bản ghi
Tất nhiên, đây không phải là điều thú vị duy nhất trong bản trình diễn (demo) của Rails về một danh sách cần làm. Nhưng đó là một phần yếu tố "thành công" của Web 2.0. Trên thực tế, nếu bạn vẫn chưa thử dùng Rails, tôi khuyến cáo dùng nó với bất kỳ kỹ sư Web nào. Ngay cả khi bạn không sử dụng nó trong các dự án riêng của mình, thực ra rất thú vị để xem ứng dụng được tổ chức như thế nào, cơ chế MVC (model-view-controller – Trình điều khiển khung nhìn mô hình hóa) được dùng ra sao và mô hình lâu bền của cơ sở dữ liệu là dễ dàng như thế nào.
Một yêu cầu web phổ biến khác là danh sách mở rộng của các trường. Tôi gọi chúng là các danh sách mở rộng cần làm.
Điều gì xảy ra khi bạn có thể có một số lượng không hạn chế các từ khóa có liên quan đến một bản ghi? Vậy có một cách để xử lý là sử dụng các dấu phẩy để tách các từ khoá. Một cách khác là sử dụng một nút thêm vào các trường từ khóa mới đang hoạt động để cho phép những người dùng thêm các từ khoá nhiều như họ muốn. Tôi sử dụng cách tiếp cận thứ hai trong Liệt kê 8.
Liệt kê 8. index.html
<html>
<head>
<script src="prototype.js"></script>
</head>
<body>
<form id="myform">
<table id="keytable">
<tr><td>Keyword</td><td><input type="text"
name="keyword_1"></td></tr>
</table>
</form>
<input type="button" onclick="addkeyword()" value="Add Keyword">
<input type="button" onclick="dosubmit()" value="Submit">
<div id="result" style="padding:5px;">
</div>
<script>
var nextkeyid = 2;
function addkeyword()
{
var elTR = $('keytable').insertRow( -1 );
var elTitleTD = elTR.insertCell( -1 );
elTitleTD.appendChild( document.createTextNode( 'Keyword' ) );
var elInput = document.createElement( 'input' );
elInput.type = 'text';
elInput.name = 'keyword_'+nextkeyid;
nextkeyid++;
var elInputTD = elTR.insertCell( -1 );
elInputTD.appendChild( elInput );
}
function dosubmit( ) {
new Ajax.Updater( 'result', 'add.php',
{ method: 'post', parameters: $('myform').serialize() } );
}
</script>
</body>
</html>
|
Ở đây thủ thuật thực sự là hàm addkeyword(), sử
dụng insertRow và insertCell để tạo ra một hàng mới trong bảng các từ khoá. Sau
đó, hàm này lại sử dụng document.createElement
để tạo ra một trường nhập mới để giữ từ khoá. Mã Ajax.Updater, được gọi khi người dùng nhấn vào Submit,
gọi kịch bản lệnh add.php. Kịch bản lệnh add.php này chỉ cần trả về danh
sách các từ khóa mà biểu mẫu đó cấp cho nó. Kịch bản lệnh này được chỉ ra
trong Liệt kê 9.
Liệt kê 9. add.php
Post Result:<br/>
<?php var_export( $_POST ) ?>
|
Khi đưa trang web này vào trình duyệt của mình, lần đầu tiên tôi thấy nó như Hình 7.
Hình 7. Biểu mẫu từ khoá với một từ khóa duy nhất
Tôi nhấn vào Add Keyword (Thêm từ khoá) một vài lần để thêm các trường mới, rồi nhấn Submit. Tôi nhận được màn hình như trong Hình 8.
Hình 8. Biểu mẫu từ khoá sau khi thêm các từ khóa và nhấn Submit
Đây là một cách lý tưởng để cho phép người dùng thêm nhiều giá trị liên kết với một bản ghi duy nhất cho những thứ như các số điện thoại, các từ khoá và các địa chỉ. Một cách sử dụng Ajax phổ biến là triển khai thực hiện các biểu mẫu đăng nhập.
Các biểu mẫu đăng nhập trong Ajax đặc biệt thú vị, vì chúng có thể phản hồi ngay lập tức cho bạn về việc bạn đã có thể đăng nhập được chưa và cũng vì chúng có thể thực hiện các đăng nhập đúng chỗ. Hãy tưởng tượng rằng bạn đang xem một bài viết mà bạn muốn nhận xét vào đó, nhưng bạn lại chưa đăng nhập. Với Ajax, bạn có thể đăng nhập trong khi bạn vẫn đọc bài viết đó. Nếu các ủy quyền của bạn được chấp nhận, một biểu mẫu mới xuất hiện để cho bạn có thể sử dụng để thêm vào một nhận xét. Quá trình này dễ dàng hơn nhiều so với việc phải theo dõi bài viết mà một người đã đang đọc thông qua quá trình đăng nhập để chuyển hướng người dùng sau khi đăng nhập thành công.
Phiên bản đơn giản của tôi về đăng nhập Ajax như trong Liệt kê 10.
Liệt kê 10. index.html
<html>
<head>
<script src="prototype.js"></script>
</head>
<body>
<form id="logform">
User: <input type="text" name="user"><br/>
Password: <input type="password" name="password"><br/>
<input type="button" onclick="login()" value="Login">
</form>
<div id="noway" style="display:none;">
No way!
</div>
<script>
function login() {
new Ajax.Request( 'login.php',
{
method: 'post',
postBody: $('logform').serialize(),
onSuccess: function( transport ) {
if( transport.responseText.match( /\<ok\/\>/ ) )
window.location = 'home.html';
else
$('noway').style.display='block';
}
} );
}
</script>
</body>
</html>
|
Các trường User (Người dùng) và Password (Mật khẩu) theo biểu
mẫu ở đầu tệp này. Dưới chúng là một thẻ
<div> có ID là
noway, sẽ được chỉ ra nếu đăng nhập này không
được chấp nhận. Phương thức JavaScript login()
cố đăng nhập bằng cách sử dụng lớp
Ajax.Request. Nếu XML được trả về từ login.php
là <ok />, biểu mẫu này sẽ chuyển hướng
người dùng đến trang chủ. Nếu không, nó sẽ đưa ra văn bản
noway.
Mã login.php như trong Liệt kê 11.
Liệt kê 11. login.php
<?php
header( 'Content-type: text/xml' );
if ( $_POST['user'] == 'jack' && $_POST['password'] == 'password' )
echo( "<ok/>" );
else
echo( "<bad/>" );
?>
|
Mã đơn giản này kiểm tra dựa vào một giá trị được mã hoá-cứng cho người
dùng và mật khẩu, sau đó trả về ok nếu khớp và
ngược lại trả về badNêu.
Để hoàn thiện, mã trang chủ được chỉ ra trong Liệt kê 12.
Liệt kê 12. home.html
<html>
<body>
You are logged in and this is your home page.
</body>
</html>
|
Để bắt đầu ví dụ này trong trình duyệt, tôi vào trang này, gõ tên người sử dụng và mật khẩu không hợp lệ và nhấn vào Login. Kết quả như trong Hình 9.
Hình 9. Trang đăng nhập sau khi nhập một mật khẩu không đúng
Rồi, khi tôi thay đổi tên người dùng và mật khẩu bằng các giá trị đúng và nhấn Login, tôi được chuyển sang trang chủ như trong Hình 10.
Hình 10. Trang đăng nhập sau khi nhập tên và mật khẩu đúng
Ví dụ cuối cùng của tôi cho bài viết này là một bài viết về Ajax dựa trên-XForms .
Tôi sẽ không tự coi mình là một chuyên gia XForms, nhưng tôi thấy ở nó một chuẩn thú vị. Trong bài viết này, tôi pha trộn chất liệu Xforms phía máy khách với Protoype.js và các kỹ thuật Ajax.
Mã với ví dụ Xforms đơn giản của tôi như trong Liệt kê 13.
Liệt kê 13. index.xhtml
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:xforms="http://www.w3.org/2002/xforms">
<head>
<title>XForms AJAX Example</title>
<xforms:model id="modelData">
<xforms:instance xmlns="">
<Data>
<First>First</First>
<Last>Last</Last>
<Email>email@email.com</Email>
</Data>
</xforms:instance>
</xforms:model>
<script src="prototype.js"></script>
</head>
<body>
<xforms:input ref="/Data/First">
<xforms:label>First: </xforms:label>
</xforms:input><br/>
<xforms:input ref="/Data/Last">
<xforms:label>Last: </xforms:label>
</xforms:input><br/>
<xforms:input ref="/Data/Email">
<xforms:label>Email: </xforms:label>
</xforms:input><br/><br/>
<button onclick="submit()">Submit</button>
<script>
function submit()
{
var m = $('modelData');
var base = m.getElementsByTagName('Data')[0];
var s = new XMLSerializer();
var data = ( s.serializeToString( base ) ).toString();
new Ajax.Updater( 'result', 'params.php',
{ method: 'post', parameters: 'data='+escape( data ) } );
}
</script>
<br/><br/>
<div id="result">
</div>
</body></html>
|
Ở đầu tệp là mô hình XML cho Xform. Sau đó, có một tập các nhãn và các đầu
vào của Xforms để tự tạo biểu mẫu cho nó. Nút Submit gọi hàm
JavaScript submit(). Sau đó, hàm này sử dụng
đối tượng JavaScript XMLSerializer để chuyển mô
hình dữ liệu XForms thành một chuỗi XML, mà sau đó được đăng lên kịch bản
lệnh params.php. Kịch bản lệnh params.php, như trong Liệt kê 14, trả về XML dưới dạng HTML để cho bạn có thể nhìn thấy
những gì xảy ra bên ngoài trang này.
Liệt kê 14. params.php
<?php
echo( htmlentities( $_POST['data'] ) );
?>
|
Khi vào trang XForms trong trình duyệt của mình (với bổ sung XForms đã được cài đặt), tôi thấy như Hình 11.
Hình 11. Một trang XForms Ajax-được kích hoạt
Sau đó, khi tôi điền biểu mẫu và nhấn Submit, tôi thấy như Hình 12.
Hình 12. Trang này sau khi nhấn nút
Điều này cho thấy mô hình dữ liệu, đã được chuyển thành văn bản XML, đã gửi
sang kịch bản lệnh params.php, rồi được trả về trong thẻ
result
<div> tag.
Bạn có thể làm rất nhiều với Ajax để kích hoạt các biểu mẫu HTML và bài viết này chỉ là những phác thảo bề ngoài. Tuy nhiên, nó sẽ cho bạn một số ý tưởng và các ví dụ thực hành về những gì bạn có thể làm trong các ứng dụng riêng của mình với các sửa đổi tương đối dễ dàng theo mã trang web của bạn.
| Mô tả | Tên | Kích thước | Phương thức tải |
|---|---|---|---|
| Source code for forms application | x-ajaxxml9-forms.zip | 101KB | HTTP |
Học tập
-
Trang chủ PHP: Truy cập một nguồn tài nguyên
vô giá cho các lập trình viên PHP.
-
Thư viện Prototype: Khám phá
khung công tác JavaScript này được thiết kế để dễ dàng phát triển các ứng
dụng web động.
-
Thư viện JavaScript Scriptaculous:
Tìm các trình trợ giúp hiển thị và các hiệu ứng để làm cho trang web của
bạn bay cùng với khung công tác dựa trên Prototype này.
-
Các bổ sung
XForms cho Firefox: Hãy thực hiện ví dụ của XForms trong công việc
của bài viết này với bạn.
-
Trang tài liệu prototype.js:
Nhận thêm thông tin về thư viện JavaScript Prototype với các liên kết đến
các blog Prototype chính thức và nhiều tài nguyên khác.
-
jQuery: Khám phá một thư viện JavaScript
khác cung cấp chức năng tương tự như prototype.js.
-
Thư viện giao diện người dùng
của Yahoo!: Xem bộ công cụ của Yahoo! cho Ajax.
-
Các
diễn
đàn thảo vùng XML: Tham gia vào bất kỳ trong một số diễn đàn tập
trung vào XML.
-
Chứng chỉ XML
của IBM: Tìm hiểu cách bạn có thể trở thành một nhà phát triển có
chứng chỉ-IBM về công nghệ XML và các công nghệ liên quan.
-
Thư viện
kỹ thuật XML: Xem Vùng XML của developerWorks với một loạt các bài
báo và thủ thuật kỹ thuật, các hướng dẫn, các tiêu chuẩn và các sách Đỏ
của IBM.
-
Các sự kiện kỹ thuật và Webcast của developerWorks: Theo sát với
các sự kiện kỹ thuật trong các phiên này.
Thảo luận
-
Các diễn
đàn thảo vùng XML: Tham gia vào bất kỳ trong một số diễn đàn tập
trung vào XML.
-
Vùng XML của developerWorks: Chia sẻ các suy nghĩ của bạn: Sau
khi bạn đọc bài viết này, hãy đăng lên nhận xét và suy nghĩ của mình trong
diễn đàn này. Các biên tập viên của vùng XML điều phối diễn đàn và chào
đón hoạt động này của bạn.