XForms 入门简介,第 2 部分: 表单、模型、控件和提交动作

创建基本的表单

本系列的第 1 部分中已经创建了一个非常简单的表单,其中包括一个文本输入字段和一个提交按钮,可以向本地主机上假想的搜索引擎发送请求(如图 1 所示)。这类表单仍然很常见,尽管它通常不是孤立在单独的网页上。

图 1. 非常简单的 Web 表单
非常简单的 Web 表单

这是个很好的起点,我们再来看看 XHTML 和 XForms 代码(清单 1)。XForms 的专用代码用粗体字显示,很容易看到,文档的其他部分是纯粹的 XHTML 1.1 Strict。

清单 1. 起点
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:xf="http://www.w3.org/2002/xforms"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:ev="http://www.w3.org/2001/xml-events">
<head>
<title>Search Form</title>
<xf:model>
    <xf:submission action="http://localhost/imaginary-search-engine" 
        method="get" id="submit-search"/>
</xf:model>
</head>
<body>
<h1>Search Form</h1>

<p>
Enter a search string, then click the Search button.
</p>

<p>
<xf:input ref="query"><xf:label>Find:</xf:label></xf:input>
<xf:submit 
submission="submit-search"><xf:label>Search</xf:label>
</xf:submit>
</p>
</body>
</html>

增加 XForms 名称空间(使用 xf: 前缀)后,已经有了一个 <xf:model> 块,它声明了名为 submit-search 的提交动作,可以使用标准的 HTTP GET 方法提交指定的搜索字符串。<body>, <xf:input> 和 <xf:submit> 元素中的内容构成了简单的表单,包括输入字段和提交按钮,后者触发 <xf:model> 中声明的动作。

如果愿意的话,可以直接试一试,<xf:input> 和 <xf:submit> 元素的距离、先后或位置没有任何特殊要求,它们可以出现在文档 <body> 的任何地方。表单的输入部件表示与其数据模型分离开来。

由于将使用该文档作为本文中其他 XForms 文档的出发点,这里还提供了 XMLSchema 和 xml-events 的 XML 名称空间声明,XForms 利用这两个辅助标准分别提供标准数据类型和表单事件。

创建一个简单的模型

XForms 的吸引人的原因之一是其将数据模型从表示中分离出来的方法。再看看清单 1,模型(<xf:model> 块中)本身存在于 XHTML 文档的<head> 中。

当然,除了一个提交动作之外这个模型完全是空的。它不含任何数据!

不过,先别忙。系统(在这里就是支持 XForms 的浏览器)为您创建了一个(如清单 2 所示),其中包含表单引用的数据字段。

清单 2. 简单表单默认的完整 <xf:model>
<xf:model>
    <xf:instance>
        <data xmlns="">
            <query/>
        </data>
    </xf:instance>
    <xf:submission action="http://localhost/imaginary-search-engine" 
        method="get" id="submit-search"/>
</xf:model>

显式地包含这种形式的实例为表单额外增加了一层验证;表单控件(比如这个简单表单中的文本字段和提交按钮)所引用的字段必须存在于模型实例之中。引用不存在的实例元素的控件要么不能呈现,要么生成错误消息(取决于 XForms 实现)。

默认值

如果显式地声明数据实例,可用它来定义默认值,只要将默认值放在字段元素中即可。清单 3 中的模型和清单 2 相同,只不过为查询提供了一个有帮助的默认值(如图 2 所示)。

清单 3. 在 <xf:instance> 中直接包含默认值
<xf:model>
    <xf:instance>
        <data xmlns="">
            <query>One or more search keywords.</query>
        </data>
    </xf:instance>
    <xf:submission action="http://localhost/imaginary-search-engine" 
        method="get" id="submit-search"/>
</xf:model>
图 2. 在模型实例中包含帮助性的提示或者有意义的默认值
在模型实例中包含帮助性的提示或者有意义的默认值

隐藏值和隐藏控件

用户触发提交动作时,XForms 发送完整的 XML 文档(数据模型实例)。创建模型实例时可以包含需要的任何数据。

因而不再需要在表单中使用隐藏控件。如果有些数据需要发送到服务器上的表单处理程序,但是又不必显示给用户(或者需要保持不变),那么可以将其添加到模型实例中(如清单 4 所示)。

清单 4. 在实例而不是表单中包含隐藏数据或者常量
<xf:model>
    <xf:instance>
        <data xmlns="">
            <query>One or more search keywords.</query>
            <engine-version>2</engine-version>
            <results>25</results>
        </data>
    </xf:instance>
    <xf:submission action="http://localhost/imaginary-search-engine" 
        method="get" id="submit-search"/>
</xf:model>

该例中,<engine-version> 和 <results> 永远不会被表单控件引用,也不会被用户看到(除非用户查看源代码)。这些数据组作为查询的一部分发送给 imaginary-search-engine,imaginary-search-engine 可以利用它们选择搜索引擎和设置返回的结果数。

加载实例

如果数据模型很大,或者需要向用户隐藏某些数据,可以从外部 XML 文件加载实例(如清单 5 所示)。

清单 5. XML 文件中的简单模型实例
<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="">
    <query>One or more search keywords.</query>
    <engine-version>2</engine-version>
    <results>25</results>
</data>

只要让 <xf:instance> 引用具体的实例 URL(如清单 6 所示)就可以了。

清单 6. 引用外部模型实例
<xf:model>
    <xf:instance src="search-instance.xml"/>
    <xf:submission action="http://localhost/imaginary-search-engine" 
        method="get" id="submit-search"/>
</xf:model>

由于 <xf:instance> 的 src 属性可以从任何 URL 加载 XML 数据,可以用 XForms 编辑或原样表示任何数据。多数 XForms 实现都要求源文档的 URL 在同一个域中,但部分 XForms 实现也允许您配置一个可信任的站点列表。

XML 数据中的引用

加载 XML 文件作为数据实例时,有可能无法控制 XML;数据也许是数据库或者其他某个应用程序提供的。如何引用 XML 中的某个元素呢?到目前为止,您还只看到了引用与数据模型匹配的元素。

XForms 表单元素使用的数据模型引用实际上是 XPath 表达式,因此可用 XPath 表达式来引用模型中的任何元素。清单 7 显示了一个扩展后的实例,其中包括一些嵌套元素。

清单 7. 更复杂的数据模型实例
<?xml version="1.0" encoding="UTF-8"?>
<data xmlns="">
    <query>One or more search keywords.</query>
    <engine-version>2</engine-version>
    <results>25</results>
    <some>
        <additional>
            <info status="important">Nested info.</info>
        </additional>
    </some>
</data>

可用 XPath 表达式 some/additional/info(或者 /data/some/additional/info,如果使用绝对路径的话)来访问 <info> 元素,或者用some/additional/info/@status 访问 <info> 元素的 status 属性。清单 8 显示了可用于编辑该数据文件的表单,在这里假设 Web 服务器支持PUT 方法(可能需要某种身份验证来保护这种功能)。

清单 8. 编辑更复杂的 XML 数据
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:xf="http://www.w3.org/2002/xforms">
<head>
<title>Search Form</title>
<xf:model>
    <xf:instance src="http://localhost/~chrish/data.xml"/>
    <xf:submission action="http://localhost/~chrish/data.xml" 
        method="put" id="submit-edit"/>
</xf:model>
</head>
<body>
<h1>XPath</h1>

<p>
Change the info and status!
</p>

<p>
<xf:input ref="some/additional/info"><xf:label>New 
info:</xf:label></xf:input><br/>
<xf:input ref="some/additional/info/@status"><xf:label>New 
status:</xf:label></xf:input>
<xf:submit 
submission="submit-edit"><xf:label>Save</xf:label></xf:submit>
</p>
</body>
</html>

无论在客户机还是服务器上,对 XForms 来说 XPath 都是一种很好的辅助技术;一旦掌握了 XPath,就可以在表单和表单处理程序中使用它。

控件的类型

到目前为止,我们只用到了 <xf:input> 和 <xf:submit> 控件,但是 XForms 还提供了很多其他的表单控件。我们来看看这些控件及其在 HTML 中的等价物。

<xf:group>(HTML <fieldset>)用于对表单中的控件进行逻辑分组。清单 9 说明了如何使用 <xf:group> 为三个输入字段加标签。

清单 9. 分组控件
<xf:group>
   <xf:label>Personal Information</xf:label>
   <p><xf:input ref="lastname"><xf:label>Last 
name:</xf:label></xf:input></p>
   <p><xf:input ref="firstname"><xf:label>First 
name:</xf:label></xf:input></p>
   <p><xf:input 
ref="address"><xf:label>Address:</xf:label></xf:input></p>
</xf:group>

<xf:input>(HTML <input type="text">)显示一个标准的文本输入字段,我们已经多次用到了它。

<xf:secret>(HTML <input type="password">)显示一个文本输入字段,输入的内容隐藏起来,适用于输入口令或者其他保密数据。<xf:secret> 与文档源代码中的 <xf:input> 完全相同。

<xf:select appearance="full">(HTML <input type="checkbox">)为用户提供一个或多个可选项,允许多选。清单 10 给出了一个例子。

清单 10. 多选控件
<xf:select ref="potato-chips" appearance="full">
   <xf:label>Favourite flavours:</xf:label>
   <xf:item><xf:label>Dill 
Pickle</xf:label><xf:value>dill</xf:value></xf:item>
   
<xf:item><xf:label>Ketchup</xf:label><xf:value>ketchup<
/xf:value></xf:item>
   
<xf:item><xf:label>Plain</xf:label><xf:value>plain<
/xf:value></xf:item>
   <xf:item><xf:label>Salt & 
Vinegar</xf:label><xf:value>snv</xf:value></xf:item>
</xf:select>

<xf:select appearance="minimal">(HTML <select multiple>)用于从菜单或列表中选择一个或多个项,对 appearance 属性使用 minimal 可以在更小的区域中呈现项目列表。

<xf:select1>(HTML <input type="radio">)类似于 <xf:select>,但是只允许用户从列表中选择一项。它可以呈现为一组单选按钮、可滚动的选择区域或者菜单,使用 appearance 属性告诉呈现引擎应该呈现为什么。

<xf:select1> 和嵌套的 <xf:choices>(HTML <select> 和嵌套的 <optgroup>)允许用户从分组列表中选择一项。<xf:choices> 子列表的标签呈现在列表中,但是不能选择。清单 11 显示了一个饮料列表让用户选择,用户也可以从非酒精和酒精饮料中选择。

清单 11. 从多个分组中选择一项
<xf:select1 ref="drink">
   <xf:label>Drink:</xf:label>
   <xf:item><xf:label>None</xf:label><xf:value>none
</xf:value></xf:item>
   <xf:choices>
      <xf:label>Soft drinks</xf:label>
      
<xf:item><xf:label>Juice</xf:label><xf:value>juice
</xf:value></xf:item>
      
<xf:item><xf:label>Milk</xf:label><xf:value>milk
</xf:value></xf:item>
      
<xf:item><xf:label>Soda</xf:label><xf:value>soda
</xf:value></xf:item>
      
<xf:item><xf:label>Water</xf:label><xf:value>water<
/xf:value></xf:item>
   </xf:choices>
   <xf:choices>
      <xf:label>Wine and beer</xf:label>
      
<xf:item><xf:label>Beer</xf:label><xf:value>beer<
/xf:value></xf:item>
      <xf:item><xf:label>Red 
wine</xf:label><xf:value>redwine</xf:value></xf:item>
      <xf:item><xf:label>White 
wine</xf:label><xf:value>whitewine</xf:value></xf:item>
   </xf:choices>
</xf:select1>

<xf:textarea>(HTML <textarea>)显示一个多行文本输入字段,如果默认值不合适可使用 CSS 样式控制区域的大小。

<xf:trigger>(HTML <input type="button">)呈现一个动作按钮。按钮没有预定义的行为,因此需要为其附加一个动作,按钮被激活时将触发该动作。清单 12 中的 <xf:trigger> 激活一个 JavaScript™ 函数,名为 calculate()

清单 12. 调用 JavaScript 函数 calculate() 的按钮
<xf:trigger>
    <xf:label>Calculate</xf:label>
    <script ev:event="DOMActivate" type="text/javascript">
    calculate();
    </script>
</xf:trigger>

要注意,这里第一次使用 ev: 名称空间,虽然在前面的基本表单的示例中早已声明。它用于引用标准 XML Events 属性 ev:event,它告诉触发器什么时候激活脚本。

<xf:trigger>(HTML <input type="image">)也可用于为表单添加图像按钮,只需在 <xf:label> 元素中插入 <img> 元素或者使用 CSS 将图像作为元素的背景即可。

如果正在把某些 HTML 表单升级到 XForms 表单,可以使用 <xf:trigger>(HTML <input type="reset">)增加 Reset 按钮(升级规范可能要求“全部功能”,包括无用的 Reset 按钮)。清单 13 说明了如何创建一个表单复位按钮,但是不要在新表单中使用它:最终用户永远不会有意识地单击 Reset 按钮。

清单 13. 实现无用的历史遗留物:Reset 按钮
<xf:trigger>
    <xf:label>Reset</xf:label>
    <xf:reset ev:event="DOMActivate"/>
</xf:trigger>

<xf:upload>(HTML <intput type="file">)用于实现文件上传。和其他控件相比这个更复杂一点,因为它需要一种特殊的<xf:submission> 方法:form-data-post(如清单 14 所示)。

清单 14. 使用 <xf:submission> 方法上传文件
<xf:model>
   ...
    <xf:submission action="http://localhost/upload-engine"
        method="form-data-post" id="upload"/>
</xf:model>

表单下方的 <xf:upload> 元素看起来类似于 <xf:submit> 或 <xf:input>(如清单 15 所示)。

清单 15. 使用 <xf:upload> 上传文件
<xf:upload ref="upload"><xf:label>Upload a
 file:</xf:label></xf:upload>

另外,还有一些 HTML 中不存在的控件。

<xf:output> 允许在文档中增加一些文本值。比如清单 7 中向数据模型增加了 <results> 元素。虽然用户不能修改它,但是可以通过编辑模型来改变它(特别是如果使用外部 XML 文件中定义的模型的话)。可以使用 <xf:output> 元素向用户显示这些信息(如清单 16 所示)。

清单 16. 使用 <xf:output> 显示模型中的数据
<p>
Your search will return a maximum of
<xf:output ref="results"> matches.
</p>

<xf:range> 为用户显示一个范围选择条(slide)或者适合于获得受约束值的其他控件。比方说,可以用三个 range 让用户输入红/绿/蓝中的一个作为突出显示搜索结果的颜色(如清单 17 所示)。

清单 17. 使用范围输入控件
<p>
Keyword highlight:<br/>
<xf:range ref="r" start="0" end="100" step="1"><xf:label>Red</xf:label></xf:range><br/>
<xf:range ref="g" start="0" end="100" step="1"><xf:label>Green</xf:label></xf:range><br/>
<xf:range ref="b" start="0" end="100" step="1"><xf:label>Blue</xf:label></xf:range>
</p>

现在介绍了各种 XForms 输入控件(和一个输出控件),下面来看看各种不同的提交动作。

基本提交动作

XForms 标准支持通常的 HTML 表单提交方法,但是 HTML 需要 method 和 enctype 来指定提交方法,而 XForms 只需要一个 method

<xf:submission method="form-data-post" action="url"/> 和 HTML 中的 <form method="post" enctype="multipart/form-data">相同,可以按同样的方法在收到 URL 时被处理。

<xf:submission method="get" action="url"/> 和 HTML 中的 <form method="get"> 相同。

<xf:submission method="urlencoded-post" action="url"> 和 HTML 中的 <form method="post" enctype="application/x-www-form-urlencoded"> 相同。

除了和 HTML 兼容的提交方法之外,XForms 还定义了两种新的提交动作,method="post" 和 method="put"

method="post" 动作将表单数据模型实例作为 XML 文档 post 给接收 URL,适用于 XSLT 或者其他 XML 处理技术。客户机不需要制定编码或者转义,服务器上也不需要特殊处理(除了标准 XML 解析以外)。

method="put" 动作将表单数据模型实例作为 XML 文档 put 给目标 URL。如果服务器支持 PUT 方法,并且允许对目标 URL 使用该方法,该 XML 文档将代替目标 URL 上的文件。可利用该方法现场编辑“任何”XML 文档,只需要通过和后来 put 动作要用到的相同的 URL 加载数据模型实例即可。

纯 XML post 和 put 方法是 XForms 目标的一部分,为数据处理带来了一定程度的灵活性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值