级别: 中级
Thomas Burke, 顾问软件工程师, IBM
2006 年 3 月 13 日
在 WebSphere® Everyplace® Mobile Portal 系列的第 4 部分,我们将创建一个 Portlet,它使用一个包含文本输入字段和提交按钮的简单 XDIME 表单。然后,我们将继续介绍如何创建一个更复杂的包含各种控件的表单。
引言
WebSphere Everyplace Mobile Portal(以下称为 Mobile Portal)扩展了 WebSphere Portal 的功能以便向移动用户传递各种类型的内容,包括应用程序内容。Mobile Portal 的功能之一就是能够将用 XDIME(一种与设备无关的标记)编写的表单转换为适合发出请求的设备的标记。
创建一个简单的表单
大多数应用程序都需要某种形式的用户交互。移动应用程序也一样。大多数 HTML Web 应用程序都使用表单,以便用户能够向应用服务器发送数据。从输入股票代号到填写贷款申请,所有这些应用程序都可以使用表单来完成。HTML 表单已经使用了很长时间,但是它们没有解决需要以与设备无关的方式为移动设备创建表单的问题。然而,为 Mobile Portal 编写的应用程序可以使用 XDIME 来描述表单。使用 XDIME,应用程序开发人员可以描述表单,而不必为每个目标设备创建特定于设备的标记。Mobile Portal 使用相关设备支持的输入方法将表单转换为适合每个设备的标记。
图 1 显示了在 WebSphere Portal 中以 HTML 格式呈现的简单表单的示例。该表单有单个文本输入字段,且带有相关的标签。它还有一个提交按钮,用于将数据送回到 Portlet。
图 1. 简单的 HTML 表单
清单 1 显示了用于以 HTML 格式创建此股票代号表单的标记片段。
清单 1. HTML 格式的示例表单
<FORM
method="POST"
action="<portlet:actionURL/>">
<LABEL
for="<%=TickerPortlet.FORM_TICKER%>">
Ticker Symbol:
</LABEL>
<INPUT
name="<%=TickerPortlet.FORM_TICKER%>"
type="text"/>
<INPUT
name="<%=TickerPortlet.FORM_SUBMIT%>"
type="submit"
value="Get Quote"/>
</FORM>
|
清单 2 显示了 XDIME 格式的相同表单。您可能立即注意到,清单 2 中的表单与清单 1 中的表单惊人的相似。Portlet 与 HTML 表单和 XDIME 表单交互的方式是完全相同的。这是因为表单仅限于门户 MVC 体系结构中的视图。更改视图(将 XDIME 添加到现有的 HTML Portlet)对 Portlet 模型和控制器没有任何影响。
清单 2. XDIME 格式的示例表单
<canvas layoutName="/ticker.mlyt" type="portlet">
<xfform
name="ticker-form"
action="<portlet:actionURL/>"
method="post">
<xftextinput
name="<%=TickerPortlet.FORM_TICKER%>"
type="text"
caption="Ticker Symbol:"
captionPane="p1"
entryPane="p2" />
<xfaction
name="<%=TickerPortlet.FORM_SUBMIT%>"
type="submit"
caption="Get Quote"
captionPane="p3" />
</xfform>
</canvas>
|
清单 1 和清单 2 之间最显著的区别是用于声明表单不同部分的标记。除了标记名称不同之外,XDIME 还引入了将表单的各个部分与 Multi Channel Server (MCS) 布局中的窗格相关联的概念(有关 MCS 布局的更多信息,请参阅本系列前面的文章)。此窗格/字段关联是 Mobile Portal 能够为各种设备生成美观的表单的方式之一。例如,对于带有窄屏幕的设备,它可以将标签放在字段之上,而对于屏幕较宽的设备,则可以将标签放在字段旁边。
Mobile Portal 还提供了一种机制,通过这种机制,可以使用相同的 XDIME 标记为功能丰富的设备生成大表单,而为比较简单的设备生成小表单。例如,在本文的第二部分,我们将创建带有多个控件的表单。对于某些设备,省略表单的某一部分是很容易的,其方法是创建一个特定于设备的布局,该布局省略了表单所使用的一些窗格。
对表单应用布局策略
图 2 和 3 显示了一些示例布局,它们可以通过清单 2 中的 XDIME 片段生成。图 2 中定义的布局是在 MCS 设备层次结构的 Master 级定义的,并作为没有使用图 3 中定义的布局(在设备层次结构的 Handset 级定义的布局)的设备的全包含 (catch-all) 布局。
图 2 显示了包含四个窗格(从 p1 到 p4)的表单区域 ticker-form。p1 用于呈现输入字段的标题,p2 用于呈现输入字段,而 p3 用于呈现提交按钮的标题。请注意,p2 放在 p1 的右边。这使得输入字段出现在使用此布局的设备的标题右边。同时需要注意,p3 位于 p1 下方,这使得提交按钮出现在标题下方。清单 2 中的 XDIME 片段没有使用此布局中的 p4。
图 2. 宽屏幕的布局
图 3 具有相同的表单名称,但窗格是纵向堆放的,而不是放在网格中,这将导致表单纵向呈现。输入字段出现在标题下面,而提交按钮出现在输入字段下面。请注意,p4 出现在图 2 中,但没有出现在图 3 中。如果清单 2 中的 XDIME 片段使用 p4(例如,用于清除字段按钮),则此窗格的目标控件将会呈现在使用图 2 中的布局的设备上,但不会呈现在使用图 3 中的布局的设备上。这是 XDIME 的一个特性,而不是错误情况。
图 3. 窄屏幕的布局
呈现表单
您可以使用设备模拟器来测试 MCS 生成的标记。本系列的第 2 部分描述了如何使用 Firefox 来测试特定设备。图 4 显示了通过 Firefox 浏览器呈现的使用图 2 所示的布局策略的表单(使用来自 PDA 的用户代理字符串)。请注意为何文本编辑字段出现在标题右边,而提交按钮出现在标题下方。
图 4. 在 PDA 模拟器中呈现的 XDIME 表单
图 5 显示了在 Openwave 模拟器中呈现的使用图 3 所示布局的表单。该表单是使用来自 XHTML Handset 的用户代理呈现的。请注意,输入字段出现在标题下方。
图 5. 在 XHTML Handset 模拟器中呈现的表单
图 6 显示了使用图 3 所示布局的表单在用于呈现 WML 的 WAP Handset 中呈现用户代理字符串时的外观。输入字段出现在标题下方,而提交按钮已被移到一个软键位置。
图 6. 在 WAP Handset 模拟器中呈现的表单
创建一个高级表单
您可以从上面的简单示例看出,XDIME 表单很容易创建,但是它们提供了 HTML 表单所无法提供的灵活性和设备无关性。然而,XDIME 支持的控件类型远不止以上简单示例中提供的标题和文本字段。XDIME 也支持菜单列表、复选框和单选按钮等控件。当一个设备不支持某种类型的控件时,Mobile Portal 会寻找该设备所支持的控件来代替指定控件。有关使用表单控件的详细信息,请参阅 WebSphere Everyplace Mobile Portal Enable 5.1 InfoCenter。
清单 3 和 4 分别显示了本文下载部分所提供的高级股票示例中使用的 HTML 和 XDIME 标记。乍一看,用于呈现表单的 XDIME 标记实际上比相应的 HTML 标记要短而且更加简单,这主要是因为 HTML 标记必须指定使表单中的控件对齐的表格元素,而 XDIME 则使用 MCS 布局来指定表单中控件的位置。
清单 3. HTML 格式的高级表单
<TABLE><TR><TD>
<FORM action="<portlet:actionURL/>" method="post">
<TABLE border="0" cellpadding="1" cellspacing="0">
<TR>
<TD valign="top">
<LABEL for="<%=TickerPortlet.FORM_EXCHANGE%>">
Select Exchange:
</LABEL>
</TD>
<TD>
<INPUT name="<%=TickerPortlet.FORM_EXCHANGE%>"
type="radio"
value="<%=TickerPortlet.VALUE_NYSE%>"
checked="checked" >NYSE
</INPUT>
<BR/>
<INPUT name="<%=TickerPortlet.FORM_EXCHANGE%>"
type="radio"
value="<%=TickerPortlet.VALUE_ASE%>" >ASE
</INPUT>
</TD>
</TR>
<TR>
<TD valign="top">
<LABEL for="<%=TickerPortlet.FORM_TICKER%>">
Ticker Symbol:
</LABEL>
</TD>
<TD>
<INPUT name="<%=TickerPortlet.FORM_TICKER%>"
size="20"
type="text"
value="IBM" />
</TD>
</TR>
<TR>
<TD valign="top">
<LABEL for="<%=TickerPortlet.FORM_SPEED%>">
Select Speed:
</LABEL>
</TD>
<TD>
<SELECT name="<%=TickerPortlet.FORM_SPEED%>">
<OPTION value="<%=TickerPortlet.VALUE_REALTIME%>">
Realtime ($2 fee)
</OPTION>
<OPTION value="<%=TickerPortlet.VALUE_15MIN%>"
selected="selected" >
Delayed 15 Minutes
</OPTION>
</SELECT>
</TD>
</TR>
<TR>
<TD valign="top">
<LABEL for="<%=TickerPortlet.FORM_INFO%>">
Show Info:
</LABEL>
</TD>
<TD>
<SELECT multiple="multiple"
name="<%=TickerPortlet.FORM_INFO%>"
size="4">
<OPTION value="<%=TickerPortlet.VALUE_CHART%>">
Chart
</OPTION>
<OPTION value="<%=TickerPortlet.VALUE_COMPANY_INFO%>"
selected="selected" >
Company Info
</OPTION>
<OPTION value="<%=TickerPortlet.VALUE_HEADLINES%>">
Headlines
</OPTION>
<OPTION value="<%=TickerPortlet.VALUE_REPORTS%>"
selected="selected">
Reports
</OPTION>
<OPTION value="<%=TickerPortlet.VALUE_INSIDER%>">
Insider Trading
</OPTION>
</SELECT>
</TD>
</TR>
<TR>
<TD valign="top">
<LABEL for="<%=TickerPortlet.FORM_PORTFOLIO%>">
Other Services:
</LABEL>
</TD>
<TD>
<INPUT name="<%=TickerPortlet.FORM_PORTFOLIO%>"
type="checkbox"
value="<%=TickerPortlet.VALUE_PORTFOLIO_ADD%>"
checked="checked">
Add to portfolio
</INPUT>
</TD>
</TR>
<TR>
<TD valign="top">
<LABEL for="<%=TickerPortlet.FORM_EMAIL%>">
Email this Quote:
</LABEL>
</TD>
<TD>
<INPUT name="<%=TickerPortlet.FORM_EMAIL%>"
size="20"
type="text" />
</TD>
</TR>
<TR>
<TD valign="top">
<LABEL for="<%=TickerPortlet.FORM_MESSAGE%>">
Message:
</LABEL>
</TD>
<TD>
<TEXTAREA cols="20"
name="<%=TickerPortlet.FORM_MESSAGE%>"
rows="3">
</TEXTAREA>
</TD>
</TR>
<TR>
<TD></TD>
<TD>
<LABEL for="<%=TickerPortlet.FORM_ALERTS%>">
Email Alerts:
</LABEL>
<INPUT checked="checked"
name="<%=TickerPortlet.FORM_ALERTS%>"
type="checkbox"
value="1" />
</TD>
</TR>
<TR>
<TD valign="top"></TD>
<TD>
<INPUT name="<%=TickerPortlet.FORM_SUBMIT%>"
type="submit"
value="Get Quote" />
</TD>
</TR>
</TABLE>
<INPUT name="<%=TickerPortlet.FORM_HIDDEN%>"
type="hidden"
value="<%=TickerPortlet.VALUE_HIDDEN%>" />
</FORM>
</TD></TR></TABLE>
|
清单 4. XDIME 格式的高级表单
<canvas layoutName="/ticker.mlyt" theme="/ticker-theme.mthm" type="portlet">
<xfform name="ticker-form" action="<portlet:actionURL/>" method="post">
<xfsiselect name="<%=TickerPortlet.FORM_EXCHANGE%>"
initial="<%=TickerPortlet.VALUE_NYSE%>"
class="radio"
caption="Select Exchange:"
captionPane="p1"
entryPane="p2">
<xfoption value="<%=TickerPortlet.VALUE_NYSE%>"
caption="NYSE" />
<xfoption value="<%=TickerPortlet.VALUE_ASE%>"
caption="ASE" />
</xfsiselect>
<xftextinput name="<%=TickerPortlet.FORM_TICKER%>"
disabled="true"
initial="IBM"
type="text"
caption="Ticker Symbol:"
captionPane="p3"
entryPane="p4" />
<xfsiselect name="<%=TickerPortlet.FORM_SPEED%>"
initial="<%=TickerPortlet.VALUE_15MIN%>"
entryPane="p6"
caption="Select Speed:"
captionPane="p5">
<xfoption value="<%=TickerPortlet.VALUE_REALTIME%>"
caption="Realtime ($2 fee)" />
<xfoption value="<%=TickerPortlet.VALUE_15MIN%>"
caption="Delayed 15 Minutes" />
</xfsiselect>
<xfmuselect name="<%=TickerPortlet.FORM_INFO%>"
caption="Show Info:"
captionPane="p7"
entryPane="p8">
<xfoption value="<%=TickerPortlet.VALUE_CHART%>"
caption="Chart"/>
<xfoption value="<%=TickerPortlet.VALUE_COMPANY_INFO%>"
caption="Company Info" selected="true"/>
<xfoption value="<%=TickerPortlet.VALUE_HEADLINES%>"
caption="Headlines"/>
<xfoption value="<%=TickerPortlet.VALUE_REPORTS%>"
caption="Reports" selected="true"/>
<xfoption value="<%=TickerPortlet.VALUE_INSIDER%>"
caption="Insider Trading"/>
</xfmuselect>
<xfmuselect name="<%=TickerPortlet.FORM_PORTFOLIO%>"
initial="<%=TickerPortlet.VALUE_PORTFOLIO_ADD%>"
caption="Other Services:"
captionPane="p9"
class="check"
entryPane="p10">
<xfoption value="<%=TickerPortlet.VALUE_PORTFOLIO_ADD%>"
selected="true"
caption="Add to portfolio"/>
</xfmuselect>
<xftextinput name="<%=TickerPortlet.FORM_EMAIL%>"
type="text"
caption="Email this Quote:"
captionPane="p11"
entryPane="p12" />
<xftextinput name="<%=TickerPortlet.FORM_MESSAGE%>"
type="text"
class="textarea"
caption="Message:"
captionPane="p13"
entryPane="p14" />
<xfboolean name="<%=TickerPortlet.FORM_ALERTS%>"
initial="1"
caption="Email Alerts"
captionPane="p16"
entryPane="p16"
trueValue="Yes please."
falseValue="I decline." />
<xfaction name="<%=TickerPortlet.FORM_SUBMIT%>"
type="submit"
caption="Get Quote"
captionPane="p18" />
<xfimplicit name="<%=TickerPortlet.FORM_HIDDEN%>"
value="<%=TickerPortlet.VALUE_HIDDEN%>" />
</xfform>
</canvas>
|
图 7、8 和 9 显示了在 PDA、XHTML 和 WAP 模拟器中呈现的高级表单:
图 7. 在 PDA 模拟器中呈现的高级 XDIME 表单示例
图 8. 在 XHTML Handset 模拟器中呈现的高级 XDIME 表单的底部
图 9. 在 WAP Handset 模拟器中呈现的高级 XDIME 表单的底部
对控件使用 MCS 主题
如果您将简单的 XDIME 表单的 <canvas> 标记与高级表单的该标记进行比较,您将注意到高级表单使用了 theme 属性。通过主题,您可以为控件指定特定的行为。例如,xfmuselect 的缺省行为通常呈现为多选列表,但是您可以强制使它呈现为复选框集合。要这样做,请查看下载部分中提供的示例代码并更改以下行:
<% // class="check" %>
将其更改为:
class="check"
其他一些常用的样式属性是:
- Action style 用于指定图像、URL 或按钮的表单动作。
- Action image 用于指定图像(如果 Action Style 设置为 image)。
- Columns 用于指定控件所占的列数。
- Rows 用于指定控件所占的行数。
- Selection list layout 用于指定标题或控件是否出现在窗格的左边沿。只有当一个控件的 captionPane 和 entryPane 相同时,这才有效。
- Selection list style 用于指定列表的呈现类型(例如,如果设备支持复选框,则 controls 强制 xfmuselect 呈现为复选框。)
有关 MCS 主题的详细信息或 MCS 主题样式属性如何改变表单中控件的行为的信息,请参阅 WebSphere Everyplace Mobile Portal Enable 5.1 Information Center。