用selectOneMenu标签开发级联下拉选择
岳乡成
环境:jdk1.6.0、jboss-4.2.3.GA、jboss-seam-2.1.1.GA 、My-SQL-5.0.8
一、标签说明
1. 概要
级联下拉选择是最常用的组件之一,它一般是用Ajax来实现的。利用<h:selectOneMenu>,<s:selectItems>,及<a:support>可以很方便的开发级联下拉选择。如下图所示为一个用<h:selectOneMenu>做的级联下拉选择的示例。
级联下拉选择示例
上图中选择省份,可以动态的得到该省的市(地区),如果再选择了市可以动态得到该市的所有县(区)。
2. 标签属性
<h:selectOneMenu>
属性名称 描述
id 组件标识符
value 下拉框当前的值
required 是否是必输项
<s:selectItems>
从一个List、Set、DataModel或者Array中创建一个 List<SelectItem> 。
属性名称 描述
id 组件标识符
value 一个EL表达式,指定支持 List<SelectItem> 的数据
var 定义迭代期间保存当前对象的本地变量的名称
label 渲染 SelectItem 时要使用的标签。可以参考 var 变量
disabled 如果为true,SelectItem 将被取消渲染。可以参考 var 变量
noSelectionLabel 指定(可选)标签放在列表的顶部(如果也指定 required="true",那么选择这个值将导致验证出错)
hideNoSelectionLabel 如果为true,选择一个值时,noSelectionLabel 将被隐藏
<a:support>
Ajax4jsf中的一个标签,该标签的功能是对标准的jsf组件添加Ajax功能支持。
属性名称 描述
id 组件标识符
event 父组件的JavaScript事件属性的名称(onclick、onchange等)
actionlistener 方法绑定,当该组件被Ajax请求激活时,将调用该监听器方法处理该事件。该方法必须为public的并且接受一个AjaxEvent参数,返回void
二、示例开发
1. JSF Web页面
<s:div id="chooseareadiv">
<table class="class_tab1" cellspacing="0" bordercolordark="ffffff" cellpadding="1" bordercolorlight="#C0CFE0" border="1" width="100%">
<tr>
<td width="10%" align="center">
<h:outputLabel id="provincesLabel" value="省份(必须):"></h:outputLabel>
</td>
<td width="15%" align="center">
<h:selectOneMenu id="provincesSel" required="false" value="#{temp.province}">
<s:selectItems noSelectionLabel="-请选择省份-" value="#{locationUtil.provincesList}" var="item" label="#{item.category_name}" itemValue="#{item.category_id}"/>
<a:support event="onchange" actionListener="#{entProfileHome.changeProvince}" reRender="citySel,districtSel"/>
</h:selectOneMenu>
</td>
<td width="20%" align="center">
<h:outputLabel id="cityLabel" value="市(地区)(必须):"></h:outputLabel>
</td>
<td width="15%" align="center">
<h:selectOneMenu id="citySel" required="false" value="#{temp.city}" >
<s:selectItems noSelectionLabel="-请选择城市-" value="#{locationUtil.getCities(entProfileHome.temp.province)}" var="item" label="#{item.category_name}" itemValue="#{item.category_id}"/>
<a:support event="onchange" actionListener="#{entProfileHome.changeCity}" reRender="districtSel"/>
</h:selectOneMenu>
</td>
<td width="15%" align="center">
<h:outputLabel id="districtLabel" value="县(区)(必须):"></h:outputLabel>
</td>
<td width="15%" align="center">
<h:selectOneMenu id="districtSel" required="false" value="#{temp.district}">
<s:selectItems noSelectionLabel="-请选择区-" value="#{locationUtil.getDistricts(entProfileHome.temp.city)}" var="item" label="#{item.category_name}" itemValue="#{item.category_id}"/>
</h:selectOneMenu>
</td>
<td align="center">
<a:commandButton id="addEhrUserButton" value="新建" action="#{Personalinfometion.createEhrUser(entProfileHome.temp.district)}" onclick="if(!validationDistrict()) return false;" reRender="addpersonalinfodiv" />
</td>
</tr>
</table>
</s:div>
以上页面代码中用到三个类(1)temp类,它是用于获取省、市、县下拉列表框的当前选择的值。(2)locationUtil类,它是用于获取省、市、县下拉列表框中所有的内容,及发生了onchange事件后的重新获得市、县下拉列表框的内容。(3)entProfileHome类。它负责当一个下拉框内容该变时清理它下一级下拉列表框的内容。
2. Java类, Session Bean及接口
EntProfile类定义如下:
/**
* <p>WeeklyPlanAction</p>
*
* 版权 (c) 2009
*
* <p>CIB</p>
*
* 文件历史
* 日期 作者 描述
* 2009-06-21 xiangcheng.yue 创建
*
*/
package com.tower.ehr.personalinfo;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
@Name("temp")
@Scope(ScopeType.SESSION)
public class EntProfile{
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getDistrict() {
return district;
}
public void setDistrict(String district) {
this.district = district;
}
private String province;
private String city;
private String district;
}
entProfileHome类定义如下:
/**
* <p>WeeklyPlanAction</p>
*
* 版权 (c) 2009
*
* <p>CIB</p>
*
* 文件历史
* 日期 作者 描述
* 2009-06-21 xiangcheng.yue 创建
*
*/
package com.tower.ehr.personalinfo;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Out;
import org.jboss.seam.framework.EntityHome;
@Name("entProfileHome")
public class EntProfileHome extends EntityHome<EntProfile> {
@In(required=false)
@Out(required=false)
private EntProfile temp;
/**
* 省份被选择修改后的ajax事件动作,清空已关联的市和县区数据
*/
public void changeProvince(){
temp.setCity(null);
temp.setDistrict(null);
}
/**
* 市被选择修改后的ajax事件动作,清空已关联的县区数据
*/
public void changeCity(){
temp.setDistrict(null);
}
public void startEdit(){
temp = new EntProfile();
temp.setProvince(getInstance().getProvince());
temp.setCity(getInstance().getCity());
temp.setDistrict(getInstance().getDistrict());
}
public void updateEdit(){
getInstance().setProvince(temp.getProvince());
getInstance().setCity(temp.getCity());
getInstance().setDistrict(temp.getDistrict());
update();
temp = null;
}
@Override
@Begin
public void create() {
super.create();
}
public EntProfile getTemp() {
return temp;
}
public void setTemp(EntProfile temp) {
this.temp = temp;
}
}
Session bean类personalinfo的接口定义如下:
package com.tower.ehr.personalinfo.Impl;
import java.util.List;
import javax.ejb.Local;
import com.tower.ehr.entitybean.Category;
@Local
public interface LocationUtilImpl {
public List<Category> getProvincesList();
public List<Category> getCities(String province);
public List<Category> getDistricts(String city);
public void init();
public void destroy();
}
Session bean类personalinfo定义如下:
/**
* <p>LocationUtil</p>
*
* 版权 (c) 2009
*
* <p>CIB</p>
*
* 文件历史
* 日期 作者 描述
* 2009-06-01 xiangcheng.yue 创建
*
*/
package com.tower.ehr.personalinfo;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ejb.Remove;
import javax.ejb.Stateful;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Observer;
import org.jboss.seam.annotations.Scope;
import com.tower.ehr.entitybean.Category;
import com.tower.ehr.personalinfo.Impl.LocationUtilImpl;
@Stateful
@Name("locationUtil")
@Scope(ScopeType.SESSION)
/**
* * 创建该类是为了实现personalinfo中的省市县的级联。
*/
public class LocationUtil implements LocationUtilImpl{
/** 省的对象List. */
List<Category> provincesList = new ArrayList<Category>();
/** 由省的名称及所有该省的市的List组成的Map. */
private Map<String, List<Category>> map_cities = new HashMap<String, List<Category>>();
/** 由市的名称及所有该市的县的List组成的Map. */
private Map<String, List<Category>> map_districts = new HashMap<String, List<Category>>();
/** 实例化EntityManager。 */
@PersistenceContext
private EntityManager em;
/**
* 取得所有省份数据
*
* @return
*/
public List<Category> getProvincesList() {
return provincesList;
}
/**
* 根据省取得所有市数据
*
* @param province
* @return
*/
public List<Category> getCities(String province) {
return map_cities.get(province);
}
/**
* 根据市取得所有区县数据
*
* @param city
* @return
*/
public List<Category> getDistricts(String city) {
return map_districts.get(city);
}
/**
* @since 2009-06-01 在应用启动时取省市县的数据。
* @return
* @throws
*/
@Observer("org.jboss.seam.postInitialization")
//@Create
public void init() {
/** 市的对象List. */
List<Category> citiesList = new ArrayList<Category>();
provincesList = getProvinces();
for(int i = 0;i<provincesList.size();i++){
List<Category> cityList = getCitiesByProvincesId(provincesList.get(i).getCategory_id());
if(cityList.size()>0){
map_cities.put(provincesList.get(i).getCategory_id(), cityList);
citiesList.addAll(cityList);
}
}
for(int i = 0;i<citiesList.size();i++){
List<Category> districtsList = getDistrictsByCityId(citiesList.get(i).getCategory_id());
if(districtsList.size()>0){
map_districts.put(citiesList.get(i).getCategory_id(), districtsList);
}
}
}
/**
* @since 2009-06-01
* 得到所有省的list。
* @return List<Category>
* @throws
*/
public List<Category> getProvinces() {
List<Category> results = em.createQuery(
"select td from Category td where td.parent_category_id is null"
).getResultList();
return results;
}
/**
* @since 2009-06-01
* 通过省的Id得到所有市的list。
* @return List<Category>
* @throws
*/
public List<Category> getCitiesByProvincesId(String ProvincesId) {
List<Category> results = em.createQuery(
"select td from Category td where td.parent_category_id = "
+ ProvincesId).getResultList();
return results;
}
/**
* @since 2009-06-01
* 通过市的Id得到所有县的list。
* @return List<Category>
* @throws
*/
public List<Category> getDistrictsByCityId(String CityId) {
List<Category> results = (List<Category>) em.createQuery(
"select td from Category td where td.parent_category_id = "
+ CityId).getResultList();
return results;
}
/**
* @since 2009-06-01
* 效验是否选择了县的下拉框。
* @return boolean
* @throws
*/
public boolean validationDistrict(){
// if(districtId!=null&&districtId!=""){
// return false;
// }
return true;
}
@Remove
public void destroy() {
}
}
4.小结。
利用<h:selectOneMenu>,<s:selectItems>,及<a:support>标签制作级联下拉列表过程非常简单,只需要掌握<h:selectOneMenu>,<s:selectItems>,<a:support>的几个属性及深入理解Map的key-value的属性即可。希望参考本文档的读者能有所收获,谢谢。
分享到:
相关推荐
- 使用`h:selectOneMenu`来创建下拉列表,每个列表都有一个`valueChangeListener`属性,用于监听用户的选择变化。例如,省份列表的`onchange`事件触发`showcity2()`函数,城市列表的`onchange`事件触发`showcity3()...
在这个“seam级联菜单例子”中,我们将深入探讨如何在Seam应用中实现级联选择菜单,这种菜单在用户界面中常见于如国家/地区、省份/城市等层级结构的选择。 级联菜单通常涉及到Ajax技术,它允许部分页面更新而不是...
在JSF(JavaServer Faces)框架中,创建静态页面的三级级联下拉框是一种常见的需求,这通常用于实现用户界面中的数据筛选功能。在这个示例中,我们看到的是一个利用JSF、Java和MyFaces库构建的三级联动下拉菜单。这...
- 使用`h:selectOneMenu`组件创建下拉框,并设置其值绑定为Bean中的属性。 - 添加`valueChangeListener`监听器,以便在选择某一选项时触发事件,更新下一级别的数据。 4. **JSF控制器(Controller)**: - 在...
在JSF(JavaServer Faces)框架中,`<h:selectOneMenu>` 是一个用于创建下拉选择框的组件,而 `<a4j:support>` 是RichFaces库提供的一种Ajax支持的标签,它允许我们实现页面的部分更新,提高用户体验。这篇博客文章...
它通过一套丰富的标签库简化了Web界面的开发过程。 - **JSF标签** 是指JSF提供的用于构建用户界面的HTML标签。这些标签不仅具有HTML标签的基本功能,还集成了JSF框架的功能特性。 #### 二、JSF标签分类 - **JSF标签...
在实际开发中,级联选择常见于如国家-省-市-区-街道这样的多级选择场景。传统实现方式往往需要复杂的 JavaScript 代码和良好的兼容性处理,而 QFaces 的 Linkage 组件则以非侵入式的方式,使得开发者可以轻松实现...
- **selectOneMenu**: 创建一个下拉列表,用户只能选择一个选项。 - **selectManyMenu**: 创建一个下拉列表,用户可以选择多个选项。 - **selectOneRadio**: 创建一组单选按钮。 - **selectManyCheckbox**: 创建一组...
JSF的核心特性之一就是它的标签库,它使得开发人员能够使用直观的XML标签来创建动态和交互式的网页。在这个“JSF标签库快速参考”中,我们将深入探讨JSF标签库的主要组成部分,以及如何有效地使用它们。 首先,JSF...
在开发Web应用时,我们经常会遇到布局问题,尤其是在使用组件库如PrimeNG、Bootstrap等时。"selectOneMenu"是一个常见的下拉选择框组件,在某些情况下,它可能会与其他元素的对齐方式出现不一致,这通常涉及到CSS...
使用JSF的`h:inputText`和`h:commandButton`标签: ```html 登录" /> ``` 在后台,创建一个`LoginController`,处理登录逻辑: ```java @ManagedBean @RequestScoped public class LoginController { ...
robStrategy(String probeStrategy) { this.probeStrategy = probeStrategy; }}(2) 如果下拉列表的内容不是固定的,而是需要从后台动态加载,可以使用标签,它接受一个列表...理解和熟练使用这些标签是JSF开发的关键。
### JSF标签详解 #### 1. 标签入门 ...掌握这些标签的使用方法,对于快速构建功能丰富且用户友好的Web界面至关重要。通过理解不同类型的标签及其属性,开发者可以更加灵活地设计和实现Web应用的前端界面。
级联菜单的前端部分可能就是由JSF的组件实现,例如使用h:selectOneMenu或p:selectOneMenu(PrimeFaces扩展)。 2. **CDI(Contexts and Dependency Injection)**: CDI是Java EE中的依赖注入标准,Seam完全支持CDI...
在JSF(JavaServer Faces)框架中,`h:selectOneMenu` 是一个用于创建下拉选择框的组件。在某些场景下,我们可能需要将这个组件设置为只读或不可编辑状态,以便用户只能查看选项,而不能进行选择。本文将详细讲解...
选择类标签允许用户在一组选项中进行选择,如`<h:selectOneMenu>`(单选下拉菜单)、`<h:selectManyCheckbox>`(多选复选框)和`<h:selectManyListbox>`(多选列表框)。这些标签通常与`<f:selectItem>`或`...
4. **`<h:selectOneMenu>`**: 创建一个下拉菜单供用户选择单个选项。 5. **`<a4j:region>`**: 定义一个区域,其中的内容可以通过Ajax方式进行异步更新。 6. **`<a4j:commandButton>`**: 类似于`<h:commandButton>`,...
- **选择类标签**:分为两部分,如`<h:selectOneMenu>`和`<h:selectManyCheckbox>`,用于单选或多选菜单、列表框等。 - **其它标签**:包括`<h:form>`定义表单,`<h:message>`和`<h:messages>`显示验证错误,以及`...