Struts 2 的 Ajax 支持(四)

 

5.4  tabbedpanel 标签

以下代码都基于 5.2

 

  <sx:tabbedpanel /> 标签在 HTML 页面里面生成类似 Windows 程序的 Tab 页,通过使用 Tab 页,可以在有限的空间里放置更多的内容。

   <sx:tabbedpanel /> 生成 Tab 页的内容既可以是静态的,也可以是动态的 。如果是静态的,则直接指定 Tab 页面的内容;如果是动态的,则可以采用 Ajax 方式来动态加载 Tab 页的内容。

    <sx:tabbedpanel /> 标签生成整个 Tab 框架,而 <sx:tabbedpanel /> 里的 <sx:div /> 子标签则生成单独的 Tab 页,每个 <sx:div /> 子标签生成一个 Tab 页。因为 <sx:div /> 标签本身是一个 ajax 标签,允许内容动态改变,因此,每个 Tab 页的内容可以动态改变。

 

使用 <sx:tabbedpanel /> 标签可以指定如下几个常用属性。

 closeButton : 指定 Tab 页上关闭按钮的位置,可能的值是 tab 和 pane

 selectedTab : 指定加载该页面时选择哪个 Tab 页面,默认选择第一个 Tab 页

 doLayout : 设置 tabbedpanel 是否为显示固定高度,如果该属性设置为 fasle ,则 tabbedpanel 的高度会随 Tab 页大小的改变而改变

 labelposition : 设置 Tab 页面中标签的位置,可以是 top(顶,默认) 、right、bottom、left

 

 

下面的简单实例包含了 2 个 tab,都是静态文本:

/dojo/sx-tabbedpanel1.jsp

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="sx" uri="/struts-dojo-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>tabbled panel示例:简单tabbled panel</title>
<sx:head/>
</head>
<body>
简单Tab页面,doLayout属性设置是否使用固定高度<br/>
<sx:tabbedpanel id="tab1" 	cssStyle="width: 400px; height: 240px;" doLayout="true">
	<sx:div id="left"	label="第一个Tab页" >
		疯狂Java讲义<br/>
		轻量级Java EE企业实战<br/>
		疯狂Ajax讲义<br/>
	</sx:div>
	<sx:div id="middle" label="第二个Tab页">
	<h3>作者简介</h3>
		作者曾任广州电信、广东龙泉科技等公司的技术培训导师,<br/>
		现任新东方IT培训广州中心软件教学总监,并兼任
		广东技术师范学院计算机科学系的兼职副教授。<br/>
		现居在广州,如果读者阅读本书有任何问题,都可以发邮件给我。<br/>
	</sx:div>
</sx:tabbedpanel>
</body>
</html>

 

    如果希望 tab 页面上 增加关闭按钮(当浏览者单击关闭按钮时,将可以关闭指定 tab 页)则可以为 tabbedpanel 标签指定 closeButton 属性,如果同时指定了 labelposition 属性,则还可以设置 tab 中按钮的位置,如下:

 

/dojo/sx-tabbedpanel2.jsp

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="sx" uri="/struts-dojo-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>tabbled panel示例:带关闭按钮的tabbled panel</title>
<sx:head/>
</head>
<body>
设置关闭按钮(通过设置closeButton="pane")<br/>
设置标签位于Tab页的下面(通过设置labelposition="bottom")<br/>
<sx:tabbedpanel	id="tab1" cssStyle="width: 400px; height: 240px;" 
	doLayout="true"	closeButton="pane" labelposition="bottom">
	<sx:div id="left" label="第一个Tab页" >
		疯狂Java讲义<br/>
		轻量级Java EE企业实战<br/>
		疯狂Ajax讲义<br/>
	</sx:div>
	<sx:div id="middle" label="第二个Tab页">
	<h3>作者简介</h3>
		作者曾任广州电信、广东龙泉科技等公司的技术培训导师,<br/>
		现任新东方IT培训广州中心软件教学总监,并兼任
		广东技术师范学院计算机科学系的兼职副教授。<br/>
		现居在广州,如果读者阅读本书有任何问题,都可以发邮件给我。<br/>
	</sx:div>
</sx:tabbedpanel>
</body>
</html>
 

    除此之外,tabbedpanel 也支持在 tab 页中使用动态内容,在 tab 页中使用动态内容有 2 种方式:

● 直接为 tabbedpanel 标签的子标签 <sx:div /> 指定 href 属性

● 在 tabbedpanel 标签的子标签 <sx:div /> 中再次使用 <sx:div /> 子标签。这种方式下,可以实现动态更新 tab 页的部分内容。

   

    实际上,对于 tabbedpanel 的每个 tab 页而言,都只是一个简单的容器,用于包含其他的 HTML 组件,至于该容器中的 HTML 组件则任由开发者自由发挥。

如下:

/dojo/sx-tabbedpanel3.jsp

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="sx" uri="/struts-dojo-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>包含动态内容的Tab页</title>
<sx:head/>
</head>
<body>
<sx:tabbedpanel	id="tabbedpanel" cssStyle="width:520px; height: 240px;"	doLayout="true">
	<!-- 直接指定子div标签的href属性,让该Tab页内容整体改变 -->
	<sx:div id="panel1" label="动态Tab页面一" 	href="ajaxTest.action"/>
	<sx:div id="panel2" label="动态Tab页面二">
		<h2>您最喜欢的图书:</h2>
		<!-- 在子div标签内使用div子标签,让Tab页的部分内容改变 -->
		<sx:div id="panel21" href="ajaxTest.action"	updateFreq="1000"/>
	</sx:div>
	<sx:div id="panel3" label="静态Tab页面">
	<h3>作者简介</h3>
	作者曾任广州电信、广东龙泉科技等公司的技术培训导师,<br/>
	现任新东方IT培训广州中心软件教学总监,并兼任广东技术
	师范学院计算机科学系的兼职副教授。<br/>
	现居在广州,如果读者阅读本书有任何问题,都可以发邮件给我。<br/>
	</sx:div>
	<!-- 包含表单的Tab页面 -->
	<sx:div id="panel4"	label="包含远程表单的Tab页">
		<div id='show' style="border:2px dotted black;width:240px;height:50px">原始静态文本</div>
		<s:form action='showPerson' method='post'>
			<s:textfield name="name" label="姓名"/><br/>
			<s:textfield name="age" label="年龄"/><br/>
			<!-- 指定异步提交表单 -->
			<sx:submit value="提交" targets="show"/>
		</s:form>
	</sx:div>
</sx:tabbedpanel>
</body>
</html>

单击 第 4tab ,可以看到一个异步表单,在该表单中,输入字符串,然后单击“提交”按钮,内容会在上方显示

 

tab 页 可以使用 HTML Struts 2 标签

 

struts.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.2.dtd">
<struts>
	<constant name="struts.custom.i18n.resources" value="messageResource"/>
	<constant name="struts.i18n.encoding" value="GBK"/>	
	<package name="js.dojo" extends="struts-default">
		<action name="random" class="js.dojo.RandomAction">
			<result>/dojo/randomStr.jsp</result>
		</action>
		<!-- 配置ajaxText Action -->
		<action name="ajaxTest" class="js.dojo.AjaxTestAction">
			<result>/dojo/ajaxResult.jsp</result>
		</action>
		<action name="test">
			<result>/dojo/testjs.jsp</result>
		</action>
		<action name="books">
			<result>/dojo/data_zh_CN</result>
		</action>
        <action name="getBooks" class="js.dojo.GetBooksAction">
            <result>/dojo/books.jsp</result>
        </action>
        <action name="showPerson" class="js.dojo.ShowPersonAction">
            <result>/dojo/showPerson.jsp</result>
        </action>
        <action name="getChild" class="js.dojo.GetChildNode">
            <result>/dojo/bookNode.jsp</result>
        </action>
		<action name="">
			<result>.</result>
		</action>
	</package>
</struts>

 

AjaxTestAction.java

package js.dojo;

import com.opensymphony.xwork2.ActionSupport;

public class AjaxTestAction extends ActionSupport {
    private static int counter = 0;
   // 封装请求参数的属性
    private String data;

    public long getServerTime() {
        return System.currentTimeMillis();
    }
    public int getCount() {
        return ++counter;
    }
    // data属性的setter和getter方法
    public void setData(String data) {
        // 将Dojo的请求参数转换成正常字符
        this.data = HTMLDecoder.decode(data);
    }

    public String getData() {
        return "服务器提示:" + this.data;
    }
}

ShowPersonAction.java

package js.dojo;

import com.opensymphony.xwork2.ActionSupport;

public class ShowPersonAction extends ActionSupport {
    private String name;
    private int age;

    // name属性的setter和getter方法
    public void setName(String name) {
        this.name = HTMLDecoder.decode(name);
    }
    public String getName() {
        return this.name;
    }
    // age属性的setter和getter方法
    public void setAge(int age) {
        this.age = age;
    }
    public int getAge() {
        return this.age;
    }
}

HTMLDecoder.java

package js.dojo;

public class HTMLDecoder {
    public static String decode(String str) {
        // 获取字符串中所有数字
        String[] tmp = str.split(";&#|&#|;");
        StringBuffer sb = new StringBuffer("");
        // 处理每个tmp数组中每个字符串元素
        for (int i = 0; i < tmp.length; i++) {
            // 如果该元素是5位数字,将其转换成非西欧字符
            if (tmp[i].matches("\\d{5}")) {
                sb.append((char) Integer.parseInt(tmp[i]));
            }
            // 对于普通字符
            else {
                sb.append(tmp[i]);
            }
        }
        return sb.toString();
    }
}

 /dojo/showPerson.jsp

<%@ page contentType="text/html;charset=GBK" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%
    request.setAttribute("decorator", "none");
    response.setHeader("Cache-Control","no-cache"); //HTTP 1.1
    response.setHeader("Pragma","no-cache"); //HTTP 1.0
    response.setDateHeader ("Expires", 0); //prevents caching at the proxy server
%>
您提交的姓名:<s:property value="name"/><br/>
您提交的年纪:<s:property value="age"/><br/>
 

 /dojo/ajaxResult.jsp

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%
	request.setAttribute("decorator", "none");
	//阻止浏览器缓存
	response.setHeader("Cache-Control","no-cache"); //HTTP 1.1
	response.setHeader("Pragma","no-cache"); //HTTP 1.0
	response.setDateHeader ("Expires", 0); 
%>
服务器计数器: <s:property value="count"/><br/>
当前时间是:<s:property value="serverTime"/><br/>
服务器返回的提示是:<s:property value="data"/>

 index.jsp

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
		 <s:a href="" onclick="newWin('dojo/sx-tabbedpanel1.jsp');" cssStyle="cursor: hand;">sx-tabbedpanel1.jsp</s:a>
		 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
		 <s:a href="" onclick="newWin('dojo/sx-tabbedpanel2.jsp');" cssStyle="cursor: hand;">sx-tabbedpanel2.jsp</s:a>
		 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
		 <s:a href="" onclick="newWin('dojo/sx-tabbedpanel3.jsp');" cssStyle="cursor: hand;">sx-tabbedpanel3.jsp</s:a>
 

 

5.5  datetimepicker 标签

以下代码都基于 5.2


  datetimepicker 标签生成一个日期、时间下拉选择框。

  系统将指定日期、时间输入指定文本框时,必须转换成日期、时间字符串,为了设置该字符串的格式,必须使用日期、时间的格式符。 datetimepicker 支持如下几个格式:

 d : 指定处于当月的第几日

 D : 指定处于当年的第几天

 M : 代表月份。使用 1~2 个 M 代表数字月份。使用 3个 M 代表月份缩写,例如 Jan。 4 个 M 则代表月份全拼

 y : 代表年份。可使用 yy 或 yyyy 的形式

 h : 代表 12 时制的小时

 H : 代表 24 时制的小时

 m : 代表分钟

● s : 代表秒钟

 

使用该标签时,有如下几个常用属性:

 displayFormat : 指定日期的显示格式,例如: dd/MM/yyyy

 displayWeeks : 指定该日历能显示星期数

 endDate : 指定日期集的最后可用日期。 如 2141-10-12,一旦指定了该日期,则后面的日期不可用

 formatLength : 指定日期显示的格式,这些格式值就是 DateFormat 中的格式,该属性支持的值有 long、short、medium、full

 language : 指定日期显示的 Locale,如需要指定简体中文,则 zh_CN

 startDate : 指定日期集的开始可用日期。如 1940-10-10,一旦指定了该日期,则前面的日期不可用

 toggleDuration : 指定日期选择框出现、隐藏的切换时间

 toggleType : 指定日期选择框出现、隐藏的方式,可以选择 plain、wipe、explode、fade

 type : 指定日期选择框的类型,支持的值有 date 和 time ,分别代表日期选择框、时间选择框

 value : 指定当前日期、时间。可使用 today 来表示今天

 weekStartsOn : 指定日期选择框中哪一天才是一周的第一天。周日是 0,周六是 6


dojo/sx-datetimepicker.jsp

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="sx" uri="/struts-dojo-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>使用sx:datetimepicker生成日期选择框</title>
<sx:head/>
</head>
<body>
<h3>使用使用sx:datetimepicker生成日期选择框</h3>
<s:form theme="simple">
	日期选择部件,指定toggleType属性,且指定value="today"<br/>
    <sx:datetimepicker	name="date1" label="购买日期" toggleType="explode" value="today"/>
    <hr/>
	日期选择部件,指定了format属性<br/>
    <sx:datetimepicker	name="date2"	label="购买日期"	displayFormat="yyyy年MM月dd日"/>
    <hr/>
	日期选择部件,指定了weekStartsOn属性<br/>
    <sx:datetimepicker	name="date3" label="购买日期" displayFormat="yyyy年MM月dd日" 	weekStartsOn="2"/>
	<hr/>
	时间选择部件<br/>
	<sx:datetimepicker 	name="start"	label="选择出发时间"	type="time"	value="13:00"/>
</s:form>
</body>
</html>
 

 

5.6  tree 和 treenode

以下代码都基于 5.2

 

 我们可以通过 <sx:tree /> 和 <sx:treenode /> 标签在页面中生成树形结构,其中 <sx:tree/>标签生成一个树形结构,<sx:treenode/>生成一个树节点

对于<sx:tree/><sx:treenode/> 标签,都可指定如下 2 个基本属性:

 label : 指定树节点的标题

 labelposition : 指定树节点的标题位于树节点的哪个位置,该属性支持 left 和 top 2 个属性值

 

下面页面代码使用 <sx:tree><sx:treenode> 标签创建了一颗简单的静态树:

dojo/sx-tree1.jsp

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="sx" uri="/struts-dojo-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>使用sx:tree和sx:treenode标签生成静态树</title>
<sx:head/>
</head>
<body>
<h3>使用sx:tree和sx:treenode标签生成静态树</h3>
<!-- 使用sx:tree生成树 -->
<sx:tree label="计算机图书" 	id="book"	showRootGrid="true" showGrid="true" >
	<!-- 每个sx:treenode生成一个树节点 -->
	<sx:treenode label="李刚" id="yeeku">
		<!-- 使用sx:treenode生成下一级的子节点 -->
		<sx:treenode label="疯狂Java讲义" id="java"/>
		<sx:treenode label="轻量级Java EE企业应用实战" id="jee"/>
		<sx:treenode label="疯狂Ajax讲义" id="ajax" required="true"/>
	</sx:treenode>
	<sx:treenode label="David" id="David">
		<sx:treenode label="JavaScript: The Definitive Guide"	id="javascript"/>
	</sx:treenode>
	<sx:treenode label="Johnson" id="Johnson">
		<sx:treenode id="j2ee"	label="Expert One-on-One J2EE Design and Development"/>
	</sx:treenode>
</sx:tree>
</body>
</html>

  从上面代码中可以看出该树的每个节点前都有一个表示该节点展开/收缩状态的图标,可以通过为 <sx:tree> 标签设置如下 2 个属性来改变这 2 个图标:

 expandIconSrcMinus :指定表示树节点处于展开状态的图标的地址。

 expandIconSrcPlus :指定表示树节点处于收缩状态的图标的地址。

 

为了实现动态加载树节点,必须为 <sx:tree> 标签指定 href 属性,该属性负责为指定节点加载子节点。每当浏览器试图展开某个节点时,系统向 href 指定的 URL 发送异步请求,该请求包含一个请求参数: nodeId ,该参数的值就是该节点的 id 属性值。

服务器应该送回如下格式的响应:

[
   {"id":"李刚","label":"李刚"},
   {"id":"Johnson","label":"Johnson"}
]

上面响应中将生成 2 个子节点,每个节点的 id label 对应上面的 id label

 

dojo/sx-tree2.jsp

 

<%@ page contentType="text/html; charset=GBK" language="java" errorPage="" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<%@ taglib prefix="sx" uri="/struts-dojo-tags" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>使用sx:tree和sx:treenode标签生成动态树</title>
<sx:head/>
</head>
<body>
<h3>使用sx:tree和sx:treenode标签生成动态树</h3>
<sx:tree label="计算机图书" 	id="book"	href="getChild.action"	showRootGrid="true" 	showGrid="true">
	<sx:treenode label="a"/>
</sx:tree>
</body>
</html>

  上面代码定义了一个简单动态树,该树指定了 href="getChild.action" ,这意味着该树将根据 getChild.action 来动态加载子节点。

 

GetChildNode

package js.dojo;

import java.util.ArrayList;
import java.util.List;
import com.opensymphony.xwork2.ActionSupport;

public class GetChildNode extends ActionSupport {
    // 封装nodeId请求参数的属性
    private String nodeId;

    private List<String> books = new ArrayList<String>();

    // nodeId属性的setter和getter方法
    public String getNodeId() {
        return nodeId;
    }

    public void setNodeId(String nodeId) {
        this.nodeId = HTMLDecoder.decode(nodeId);
    }

    // books属性的getter方法
    public List<String> getBooks() {
        return books;
    }

    // 处理用户请求的execute方法
    public String execute() throws Exception {
        System.out.println("-----" + nodeId);
        if (nodeId.equals("book_root")) {
            books.clear();
            books.add("李刚");
            books.add("Johnson");
            books.add("David");
        }
        return SUCCESS;
    }
}
 

 

dojo/bookNode.jsp

<%@ page contentType="text/html;charset=GBK" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
[
<s:iterator value="books">
	{
		"id":"<s:property/>",
		"label":"<s:property/>"
	},
</s:iterator>
]

 

有个很严重的问题: 子节点都被当成“叶子节点”处理,因此无法展开下级节点。而 <sx:treenode > 似乎没有属性指定该节点不是叶子节点。

提示: 可能由于 struts 2.1 已经不再推荐使用 Dojo 插件的缘故,Struts 2.1 Dojo 插件对 <sx:tree><sx:treenode> 2 个标签支持并不理想。如果开发者需要使用 Dojo 的树,可以直接在页面中使用原生 Dojo

 

<s:a href="" onclick="newWin('dojo/sx-tree1.jsp');" cssStyle="cursor: hand;">sx-tree1.jsp</s:a>
		  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
		 <s:a href="" onclick="newWin('dojo/sx-tree2.jsp');" cssStyle="cursor: hand;">sx-tree2.jsp</s:a>
 
<action name="getChild" class="js.dojo.GetChildNode">
            <result>/dojo/bookNode.jsp</result>
        </action>
 

5.7  textarea

以下代码都基于 5.2

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Ajax,struts)