Struts2 <s:doubleselect>级联下拉框 详解析

运行环境:myeclipse8.6+jboss5.1+jvm1.6

先看最后目录结构:

直接上源码:

complexFormTag.jsp:

<%@ page language="java" contentType="text/html; charset=gb2312"pageEncoding="gb2312"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<html>
	<head>
		<title>复杂表单标签使用范例</title>
		<s:head />
	</head>
	<body>
		<h3 align="left">doubleselect标签使用范例</h3>
		<p>
			<s:form name="doubleselectExample">
				<s:doubleselect label="材料" headerValue="" headerKey="0"
					list="itemList" listKey="itemId" listValue="item"
					doubleName="abc" doubleList="materialMap.get(top.itemId)"
					doubleListKey="materialId" doubleListValue="material" />
			</s:form>
		</p>
	</body>
</html>

解析:

若不使用Struts2,则需要结合JavaScript和HTML标签共同开发完成此功能。

doubleselect标签的功能是提供两个有级联关系的下拉框。用户选中第一个下拉框中的某选项,则第二个下拉框中的选项根据第一个下拉框被选中的某选项内容来决定它自己的下拉框选项内容,产生联动效果。

对于代码"materialMap.get(top.itemId)",其中的top返回的是材料类别map集合的value即材料list集合中的材料类对象实例。

最后面会对top更进一步解释。

注意:<s:doubleselect/>标签必须放在<s:form>中,放在普通<form>中会出错,而且s:form必须指定name属性。

另外,希望页面美观的话,希望s:doubleselect标签和左边的字对齐,则指定s:doubleselect属性theme="simple"

希望两个select排成一行(默认是上下行的),则在<s:form></s:form>间加入css样式:

<style> 
    .nobr br{display:none}   
</style>

然后在用<div class="nobr"></div>把<s:doubleselect .. />包起来就可以了!

下面是doubleselect标签的属性列表:

下面通过一张图形象的表示联动关系:

 

对应的组件:

类别1
类别2
类别3
类别4
类别5
类别6
类别7
类别8
类别9
类别10

类别2-->材料1
类别2-->材料2
类别2-->材料3
类别2-->材料4
类别2-->材料5
类别2-->材料6
类别2-->材料7
类别2-->材料8
类别2-->材料9
类别2-->材料10

最后,两个下拉框要联动起来,靠的是“ItemId”与下面"Integer类型变量"的一一对应关系。

<s:doubleselect ...

list="itemList"                                                    listKey="itemId"              listValue="item"

doubleList="materialMap.get(top.itemId)"doubleListKey="materialId"doubleListValue="material" />

注意,上面的两相同的itemId,这里应该必须一致。

complexFormTagAction.java:

package action;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.opensymphony.xwork2.ActionSupport;
import model.*;

public class ComplexFormTagAction extends ActionSupport {
	//级联第一个下拉框数据
	private List<Item> itemList;
	//级联第二个下拉框数据
	private Map<Integer, List<Material>> materialMap;

	public String execute() throws Exception {
		itemList = new ArrayList<Item>();

		//循环新建10个类别
		for (int j = 0; j < 10; j++) {
			Item item = new Item();
			item.setItemId(j + 1);
			item.setItem("类别" + (j + 1));
			itemList.add(item);
		}

		materialMap = new HashMap<Integer, List<Material>>();
		//循环新建每个类别中的10个材料
		for (int j = 0; j < 10; j++) {
			List<Material> materialList = new ArrayList<Material>();
			for (int i = 0; i < 10; i++) {
				Material material = new Material();
				material.setMaterialId(i);
				material.setMaterial("类别" + (j + 1)+"-->"+"材料"+(i + 1));
				materialList.add(material);
			}
			materialMap.put((j + 1), materialList);
		}
		return SUCCESS;
	}

	public Map<Integer, List<Material>> getMaterialMap() {
		return materialMap;
	}

	public void setMaterialMap(Map<Integer, List<Material>> materialMap) {
		this.materialMap = materialMap;
	}

	public List<Item> getItemList() {
		return itemList;
	}

	public void setItemList(List<Item> itemList) {
		this.itemList = itemList;
	}
}

Material.java:

package model;

public class Material implements java.io.Serializable {
	// Fields
	private int materialId;
	private String material;

	public Material() {}

	public int getMaterialId() {
		return this.materialId;
	}

	public void setMaterialId(int materialId) {
		this.materialId = materialId;
	}

	public String getMaterial() {
		return this.material;
	}

	public void setMaterial(String material) {
		this.material = material;
	}
}

Item.java:

package model;

public class Item implements java.io.Serializable {
	private int itemId;
	private String item;	

	public Item() {}

	public int getItemId() {
		return itemId;
	}

	public void setItemId(int itemId) {
		this.itemId = itemId;
	}

	public String getItem() {
		return this.item;
	}

	public void setItem(String item) {
		this.item = item;
	}
}

struts.xml:

<?xml version="1.0" encoding="gb2312"?>

<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
   <constant name="struts.i18n.encoding" value="gb2312"/>
    <package name="OGNLTAG" extends="struts-default">

    <action name="complexFormTag" class="action.ComplexFormTagAction">
	  <result name="success">/jsp/complexFormTag.jsp</result>
	</action>

    </package>
</struts>

运行http://localhost:8080/OGNLTAG/jsp/complexFormTag.action

注:后缀是.action而非.jsp,否则异常:

The requested list key ‘itemList‘ could not be resolved as a collection/array/map/enumeration/iterator type.

因为直接访问jsp页面的话,要先经过struts.xml导航,然后才转到调用Action类处理;这样的话"itemList"就没有完成初始化,故而出现上述异常。若直接“.action”去访问Action类的话,就完成初始化操作了,故而" ‘itemList‘ can be resolved as a collection"。

输出结果:

------------------------------------------------------------------------------

最后通过<s:debug />看一下调试结果中的“值栈”:

Struts ValueStack Debug

Value Stack Contents

注意上图中materialMap和itemList这两个Action类中有且仅有的两实例属性。从上面的图片可以理解doubleList="materialMap.get(top.itemId)"中的top,它的意思是:the value at the top of the stack 。

用语句<s:property value="top" />,会输出:[email protected] 1db6a20

<s:property value="materialMap" />,会输出:{1=[[email protected]],2=[...],...,10=[...] }

(不用"#",也就是直接从“值栈”中取值,此处等效于value="top.materialMap")

<s:property value="itemList" />,会输出:[[email protected],[email protected],.......]

测试<s:property value="top.itemId" />输出为空,是因为itemId这个值是要根据listKey才能确定出来的。

可以上面语句看出:top就是指上面图片中的“Object列”的对象,它有些“Property”,如 texts、materialMap、actionErrors . . .。

list="itemList" listKey="itemId" listValue="item"
doubleName="abc" doubleList="materialMap.get(top.itemId)"

top.itemId:top代表的就是list即"itemList"当前选中的对象, 所以top.itemId对应的就是当前选中的对象Item的ID, materialMap.get(top.itemId)即根据当前选中的对象Item中的ID来取出第二级下拉框的数据集合。

来自:http://blog.csdn.net/itzyjr/article/details/8439586

时间: 2024-10-20 18:08:49

Struts2 <s:doubleselect>级联下拉框 详解析的相关文章

本示例演示如何通过Struts2框架提供的标签,简单地实现【级联下拉框】

1.发布房屋表单页面的级联下拉框如下: 2.     进入发布页面前需要查询下拉框数据,Action代码如下: 3.     房屋发布页面JSP代码如下: <s:doubleselect>标签的属性说明: list:                     一级下拉框的数据来源集合,和Action中集合名称一样 listKey:              一级下拉框数据集合中的实体,作为value的属性名 listValue:           一级下拉框数据集合中实体,作为text的属性名

jquery级联下拉框

$(document).ready(function(){     //找到三个下拉框     var carnameSelect = $(".carname").children("select");     var cartypeSelect = $(".cartype").children("select");     var wheeltypeSelect = $(".wheeltype").chi

JQuery和ASP.NET分别实现级联下拉框效果

在学习JQuery之前知道下拉框的级联效果可以通过asp.net控件实现,现在学习了JQuery,知道了JQuery和select也能实现.我分别举两个小例子说明这两种方法如何实现. 1.用JQuery和select来实现汽车厂商和汽车类型的联动 效果图:       逻辑分析图: html代码: [html] view plain copy <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "

自己编写jQuery插件 之 无限级联下拉框

因为是级联,所以数据必须是树型结构的,我这里的测试数据如下: 看下效果图: 1.>图一: 2.>图二: 3.>图三: 由图可知,下拉框的个数并不是写死的,而是动态加载的.每当下拉框选择改变的时候,会发送一次ajax请求,请求成功返回json格式数据,当返回的数据不为空时(即有子节点时),则会向页面中添加一个下拉框,没有则不添加. 插件的实现代码如下: (function ($) { $.fn.CascadingSelect = function (options) { //默认参数设置

JavaScript实现级联下拉框

<!DOCTYPE html> <html> <head> <meta name="author" content="Yeeku.H.Lee(CrazyIt.org)" /> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title> 级联菜单 </tit

js基于json的级联下拉框

级联下拉列表是项目中常用到的.比如省市县,比如企业性质等,做成一个js通用组件, 在静态页出来后可以直接插入,将数据和html静态页做一个解耦. 贴出来抛砖引玉吧. <html> <script type="text/javascript"> /** 基于json的级联下拉列表,支持初始化 调用eg: var comboselect = ComboSelectFactory(data, 'p1', 'p2', 'p3', 'p4'); 设定下拉列表value,t

ionic angularjs三级级联下拉框显示

1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 2 <html xmlns="http://www.w3.org/1999/xhtml"> 3 <head> 4 <meta http-equiv="

地址下拉框,需要js级联js

function area() { _url = "/ashx/DropDownControl.ashx"; _swType = "GetArea"; _z = ["#province", "#city", "#conty"]; _zo = ["#province > option[value!=-1]", "#city > option[value!=-1]&qu

EXT学习之——Ext下拉框绑定以及级联写法

/*******步骤有四个,缺一不可*********/ function () {xxxxxx = Ext.extend(construct, {InitControl: function () { var _this = this; /*****************步骤一:建数据store ******************/ //一级下拉框数据(此处注意,一定要把store写在combobox控件定义的前面,否则无法加载数据) var moduleStore = new Ext.da