跳转到主要内容

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

当您初次登录到 developerWorks 时,将会为您创建一份概要信息。您在 developerWorks 概要信息中选择公开的信息将公开显示给其他人,但您可以随时修改这些信息的显示状态。您的姓名(除非选择隐藏)和昵称将和您在 developerWorks 发布的内容一同显示。

所有提交的信息确保安全。

  • 关闭 [x]

当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

单击提交则表示您同意developerWorks 的条款和条件。 查看条款和条件.

所有提交的信息确保安全。

  • 关闭 [x]

Ajax 和 XML: 用于表单的 Ajax

使用 Ajax 技术创建输入表单

Jack D Herrington (jherr@pobox.com), 高级软件工程师, Leverage Software Inc.
Jack D. Herrington 是一位有着超过 20 年经验的高级软件工程师。他是 Code Generation in ActionPodcasting Hacks PHP Hacks 这三本书的作者。他还发表了 30 多篇文章。可以通过 jherr@pobox.com 与 Jack 联系。

简介: 在 HTML 表单中结合 Asynchronous JavaScript™ + XML (Ajax) 的服务器回调机制,对表单应用 Ajax,对于为应用程序增加 Web 2.0 功能来说是一种可行的办法。通过本文了解增加 Ajax 代码改进 PHP 应用程序用户体验的各种技术。

查看本系列更多内容

发布日期: 2008 年 2 月 13 日
级别: 中级 原创语言: 英文
访问情况 : 3861 次浏览
评论: 


谈到 Web 2.0 应用程序,首先想到的就是那些最杰出的应用:YouTube 的视频、 üGoogle Maps 可滚动的地图以及 Flikr 的地理定位功能。但是人们常常忽略的是,在这些网站上那些粗糙的 HTML 表格正随着 Ajax 技术的普及经历一场重大的变革。

请访问 Ajax 技术资源中心,这是有关 Ajax 编程模型信息的一站式中心,包括很多文档、教程、论坛、blog、wiki 和新闻。任何 Ajax 的新信息都能在这里找到。

RSS 订阅 Ajax 相关文章和教程的 RSS 提要

本文介绍了如何利用 Prototype.js JavaScript 库在表单中结合 Ajax 代码来解决常见的用户体验问题。

简单的 Ajax 表单提交

我们从最简单的东西入手:一个包含多个字段的注册表单,希望通过 Ajax 而不是常规的 Web 表单上传办法来提交。清单 1 显示了这个简单的表单。


清单 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>

文件的一开始包含了 prototype.js JavaScript 文件,它将帮助我完成所有的 Ajax 操作。接下来是传统的 HTML 表单,包含三个字段:firstlastemail。再下面是使用 dosubmit() JavaScript 函数提交表单的按钮。

dosubmit() 函数使用 Ajax.Updater 类把数据上传给 add.php 脚本。然后添加调用选项。这里将提交方法设置为 post,然后使用表单的 serialize() 方法添加参数。serialize() 方法不是标准的 JavaScript 代码,由 JavaScript 库来提供。

调用 Ajax.Updater 的第一项是 <div> 标记的 ID,它接收 add.php 脚本返回的 HTML。在用户单击按钮时通知用户发生了什么,这是最简单的办法。

add.php 脚本如清单 2 所示。


清单 2. add.php
                
Thanks <?php echo( $_POST['first'] ) ?> <?php echo( $_POST['last'] ) ?>!

脚本仅仅回显表单上传的内容。事实上,这时候可能需要增加一条数据库记录,这类业务逻辑处理您可以自己完成。

第一次打开表单的时候,浏览器中显示的结果如 图 1 所示。


图 1. 简单的 Ajax 表单
简单的 Ajax 表单

然后单击 Submit,将表单数据发送到页面,add.php 页面返回的 HTML 显示在 Submit 按钮下面,如 图 2 所示。


图 2. 提交之后的响应
提交之后的响应

Ajax 表单的另一个变化是自动填充表单,根据某些关键字段的值更新字段值 — 比如,输入客户 ID 并单击按钮就可以在另一个字段中得到当前客户的记录。

这类自动填充表单如 清单 3 所示。


清单 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>

清单 1 所示表单的基础上增加了一个字段 ID。这里存放客户的 ID。然后新增的 dofill() 函数调用 getdata.php 页面,后者返回包含给定客户名字、姓氏和电子邮件地址的 XML 代码。

发送给 Ajax.Updater 调用的 onSuccess 处理程序使用所有浏览器都支持的文档对象模型(DOM)函数解析下载的 XML 数据。然后将 elFirstelLastelEmail <input> 项设置为 XML 返回的数据。

getdata.php 页面如 清单 4 所示。


清单 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>

这里的代码实际上是一个存根方法,通常需要访问数据库来得到给定记录的名字、姓氏和电子邮件地址。

第一次打开该页面的结果如 图 3 所示。


图 3. 填充表单
填充表单

然后在 ID 字段中输入 1 并单击 Fill Fields,于是访问 getdata.php 页面获得名字、姓氏和电子邮件地址并更新相应的字段。如 图 4 所示。


图 4. 根据 ID 填充字段
根据 ID 填充字段

下一个 Ajax 小例子将创建一个就地更新(in-place)的 to-do 列表。


原地更新的列表

最常见的 Ruby on Rails 范例是原地 更新的 to-do 列表。就是说列表在页面上部,列表下有一个文本框。在文本框中输入一些内容并单击 Submit 之后,页面上方的列表就会加上新的项目而不改变页面。输入文本的文本框重置以便输入新的内容。

实际上非常困难,因此采用 PHP 来完成。to-do 列表所在页面如 清单 5 所示。


清单 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>

这里没有将 to-do 列表存储到数据库中,而采用普通文本文件 list.txt 存储,每行一项。因此,要将列表置于页面顶部,只需要打开文件并把每一行读入 ID 为 result<div> 标记中。

表单如下,其中包含作为 to-do 项的输入文本。 下方是调用 dosubmit() JavaScript 函数的按钮。这个 JavaScript 函数使用 Ajax.Updater 类调用 add.php 页面,后者添加新的项并返回添加了新项的列表。

add.php 脚本如 清单 6 所示。


清单 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 );
}
?>

有点傻里傻气的 to-do 列表如 清单 7 所示。


清单 7. list.txt
                
Get swim goggles
Practice swimming
Swim in race

第一次打开页面的结果如 图 5 所示。


图 5. 准备添加 to-do 项
准备添加 to-do 项

输入 Finish in record time 然后单击 Submit。在页面没有刷新的情况下得到的结果如 图 6 所示。


图 6. 插入记录后的页面
插入记录后的页面

当然这绝不是 Rails to-do 列表范例惟一的精彩之处。但的确是 Web 2.0 令人侧目的因素之一。实际上,如果还没有尝试过 Rails,我建议所有的 Web 工程师都应当试一试。即便不在项目中应用,看看应用程序是如何组织的、MVC 机制是如何使用的、数据库持久模型是多么简单也很有意思。

另一种常见的 Web 需求是扩展字段列表。我称之为 expando 列表


Expando 列表

如果某条记录有无数多个关键字怎么办?当然,一种办法是使用逗号分隔关键字。另一种办法是让按钮随时增加新的关键字,允许用户根据需要添加任意多的关键字。清单 8 采用了第二种办法。


清单 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>

其中的关键在于 addkeyword() 函数,它使用 insertRowinsertCell 在关键字表格中创建新行。然后用 document.createElement 建立存放关键字的新的输入字段。Ajax.Updater 在用户单击 Submit 时被调用,本身则调用 add.php 脚本。add.php 脚本返回表单给出的关键字列表。脚本如 清单 9 所示。


清单 9. add.php
                
Post Result:<br/>
<?php var_export( $_POST ) ?>

在浏览器中打开的时候,页面如 图 7 所示。


图 7. 只有一个关键字的表单
只有一个关键字的表单

多次单击 Add Keyword 添加新的字段,然后单击 Submit。结果如 图 8 所示。


图 8. 添加关键字并提交之后的表单
添加关键字并提交之后的表单

为了让用户添加和同一记录关联的多个值,比如电话号码、关键字和地址,这是一种理想的办法。Ajax 另一种常见的用法是实现登录表单。


登录表单

Ajax 登录窗口非常棒,因为能够马上得到反馈是否能够登录进去,而且可完成原地登录。假设您正在寻找一篇希望提供建议的文章,但是没有登录。利用 Ajax 可以在查找的同时登录。如果身份得到认可,将出现一个新表单供您添加评论。这种方法和跟踪查找的文章然后在登录之后重定向相比要容易得多。

Ajax 登录的简单版本如 清单 10 所示。


清单 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>

UserPassword 字段位于文件上方的表单。此后是 ID 为 noway<div> 标记,登录不成功的话将显示它。login() JavaScript 方法使用 Ajax.Request 类尝试登录。若 login.php 返回的 XML 是 <ok />,表单把用户重定向到主页。否则显示 noway 文本。

login.php 代码如 清单 11 所示。


清单 11. login.php
                
<?php
header( 'Content-type: text/xml' );
if ( $_POST['user'] == 'jack' && $_POST['password'] == 'password' )
 echo( "<ok/>" );
else
 echo( "<bad/>" );
?>

这段简单的代码检查硬编码的用户和密码,匹配返回 ok,否则返回 bad

为了完整起见,主页代码如 清单 12 所示。


清单 12. home.html
                
<html>
<body>
 You are logged in and this is your home page.
</body>
</html>

在浏览器中打开该页然后输入错误的用户名和密码并单击 Login。结果如 图 9 所示。


图 9. 输入错误密码后的登录页面
输入错误密码后的登录页面

然后修改用户名和密码并单击 Login,就会重定向到主页,如 图 10 所示。


图 10. 输入正确用户名和密码之后的登录页面
输入正确用户名和密码之后的登录页面

本文的最后一个例子是基于 XForms 的 Ajax 文章。


XForms Ajax

我不认为自己是一位 XForms 专家,但认为这是一个不错的标准。本文将客户端 XForms、Protoype.js 与 Ajax 技术结合了起来。

这个简单的 XForms 例子如 清单 13 所示。


清单 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>

文件开始部分是 XForm 的 XML 模型。接下来是一些 XForms 标签和组成表单的输入字段。Submit 按钮调用 submit() JavaScript 函数。该函数利用 XMLSerializer JavaScript 对象将 XForms 数据模型转化成 XML 字符串传递给 params.php。params.php 脚本如 清单 14 所示,它把 XML 作为 HTML 返回以便能看到页面输出的内容。


清单 14. params.php
                
<?php
echo( htmlentities( $_POST['data'] ) );
?>

在浏览器中(安装了 XForms 增件)打开 XForms 页面的结果如 图 11 所示。


图 11. 支持 Ajax 的 XForms 页面
支持 Ajax 的 XForms 页面

然后填充表单并单击 Submit 得到 图 12 所示的结果。


图 12. 提交之后的页面
提交之后的页面

它显示了转化成 XML 文本、发送给 params.php 然后返回到 result <div> 标记的数据模型。


结束语

利用 Ajax 来改进 HTML 表单有很多事情可做,本文仅仅介绍了一点皮毛。但至少希望能帮助您了解如何稍加修改页面代码来改进您的应用程序。



下载

描述名字大小下载方法
表单应用程序的源代码x-ajaxxml9-forms.zip101KBHTTP

关于下载方法的信息


参考资料

学习

讨论

关于作者

Jack D. Herrington 是一位有着超过 20 年经验的高级软件工程师。他是 Code Generation in ActionPodcasting Hacks PHP Hacks 这三本书的作者。他还发表了 30 多篇文章。可以通过 jherr@pobox.com 与 Jack 联系。

关于报告滥用的帮助

报告滥用

谢谢! 此内容已经标识给管理员注意。


关于报告滥用的帮助

报告滥用

报告滥用提交失败。 请稍后重试。


developerWorks:登录


需要一个 IBM ID?
忘记 IBM ID?


忘记密码?
更改您的密码

单击提交则表示您同意developerWorks 的条款和条件。 使用条款

 


当您初次登录到 developerWorks 时,将会为您创建一份概要信息。您在 developerWorks 概要信息中选择公开的信息将公开显示给其他人,但您可以随时修改这些信息的显示状态。您的姓名(除非选择隐藏)和昵称将和您在 developerWorks 发布的内容一同显示。

请选择您的昵称:

当您初次登录到 developerWorks 时,将会为您创建一份概要信息,您需要指定一个昵称。您的昵称将和您在 developerWorks 发布的内容显示在一起。

昵称长度在 3 至 31 个字符之间。 您的昵称在 developerWorks 社区中必须是唯一的,并且出于隐私保护的原因,不能是您的电子邮件地址。

(长度在 3 至 31 个字符之间)


单击提交则表示您同意developerWorks 的条款和条件。 使用条款.

 


为本文评分

评论

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=XML, Web development
ArticleID=288955
ArticleTitle=Ajax 和 XML: 用于表单的 Ajax
publish-date=02132008
author1-email=jherr@pobox.com
author1-email-cc=dwxed@us.ibm.com

标签

Help
使用 搜索 文本框在 My developerWorks 中查找包含该标签的所有内容。

使用 滑动条 调节标签的数量。

热门标签 显示了特定专区最受欢迎的标签(例如 Java technology,Linux,WebSphere)。

我的标签 显示了特定专区您标记的标签(例如 Java technology,Linux,WebSphere)。

使用搜索文本框在 My developerWorks 中查找包含该标签的所有内容。热门标签 显示了特定专区最受欢迎的标签(例如 Java technology,Linux,WebSphere)。我的标签 显示了特定专区您标记的标签(例如 Java technology,Linux,WebSphere)。