基于Seam框架实现省、市、区县的联动选择

[原创于:http://happydev.iteye.com]

 

要实现省、市、区县的联动选择有两种方案:

一种是将省市区县的所有数据给到客户端由浏览器用js来控制选择和显示,但数据量太大,会导致页面太大,所以这种方案不可取;

二是用Ajax来实现联动选择,本文给出的就是在Seam框架下的基于ajax省、市、区县的联动选择实现。

 

一、准备好省、市、区县的所有数据,并提供相关访问组件

 

省、市、区县的所有数据见附件。

省、市、区县的访问组件类:

 

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.AutoCreate;
import org.jboss.seam.annotations.Create;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;

@Name("locationUtil")
@Scope(ScopeType.APPLICATION)
@AutoCreate
public class LocationUtil {
	private ArrayList<String> provinces = new ArrayList<String>();
	private Map<String, ArrayList<String>> map_cities = new HashMap<String, ArrayList<String>>();
	private Map<String, ArrayList<String>> map_districts = new HashMap<String, ArrayList<String>>();
	private Map<String, String> map_pid = new HashMap<String, String>();
	private Map<String, String> map_cid = new HashMap<String, String>();
	
	/**
	 * 取得所有省份数据
	 * @return
	 */
	public ArrayList<String> getProvinces(){
		return provinces;
	}
	/**
	 * 根据省取得所有市数据
	 * @param province
	 * @return
	 */
	public ArrayList<String> getCities(String province){
		return map_cities.get(province);
	}
	/**
	 * 根据市取得所有区县数据
	 * @param city
	 * @return
	 */
	public ArrayList<String> getDistricts(String city){
		return map_districts.get(city);
	}
	public Collection<String> getAllCities(){
		return map_cid.values();
	}
	
	@Create
	public void init(){
		SAXReader reader = new SAXReader(); 
		try {
			Document docDistricts = reader.read(this.getClass().getResourceAsStream("Districts.xml"));
			Document docCities = reader.read(this.getClass().getResourceAsStream("Cities.xml"));
			Document docProvinces = reader.read(this.getClass().getResourceAsStream("Provinces.xml"));
			for (Iterator<Element> i = docProvinces.getRootElement().elementIterator("Province"); i.hasNext();) {
				Element e = i.next(); 
				provinces.add(e.getText());
				map_pid.put(e.attributeValue("ID"), e.getText());
			}
			for (Iterator<Element> i = docCities.getRootElement().elementIterator("City"); i.hasNext();) {
				Element e = i.next(); 
				map_cid.put(e.attributeValue("ID"), e.getText());
				String pName = map_pid.get(e.attributeValue("PID"));
				ArrayList<String> list = map_cities.get(pName);
				if (list == null){
					list = new ArrayList<String>();
					map_cities.put(pName, list);
				}
				list.add(e.getText());
			}
			for (Iterator<Element> i = docDistricts.getRootElement().elementIterator("District"); i.hasNext();) {
				Element e = i.next(); 
				String cName = map_cid.get(e.attributeValue("CID"));
				ArrayList<String> list = map_districts.get(cName);
				if (list == null){
					list = new ArrayList<String>();
					map_districts.put(cName, list);
				}
				list.add(e.getText());
			}
		} catch (DocumentException e) {
			e.printStackTrace();
		}
	}
	
	
}

 

 

二、业务层代码

 

@Name("entProfileHome")
public class EntProfileHome extends EntityHome<EntProfile> {

	
	/**
	 * 定义一个临时的数据实体,以免在省、市、区县联动选择时对实际数据造成干扰
	 */
	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;
	}
	

}

 

 

 

三、选择页面

 

			<s:decorate template="/layout/edit.xhtml">
				<ui:define name="label">选择地点</ui:define>
				<h:selectOneMenu required="false" value="#{entProfileHome.temp.province}">
					<s:selectItems noSelectionLabel="-请选择省份-" value="#{locationUtil.provinces}" var="item" label="#{item}" />
					<a4j:support event="onchange" actionListener="#{entProfileHome.changeProvince}" reRender="citySel,districtSel"/>
				</h:selectOneMenu>
				<h:selectOneMenu id="citySel" required="false" value="#{entProfileHome.temp.city}">
					<s:selectItems noSelectionLabel="-请选择城市-" value="#{locationUtil.getCities(entProfileHome.temp.province)}" var="item" label="#{item}" />
					<a4j:support event="onchange" actionListener="#{entProfileHome.changeCity}" reRender="register,districtSel"/>
				</h:selectOneMenu>
				<h:selectOneMenu id="districtSel" required="false" value="#{entProfileHome.temp.district}">
					<s:selectItems noSelectionLabel="-请选择区-" value="#{locationUtil.getDistricts(entProfileHome.temp.city)}" var="item" label="#{item}" />
				</h:selectOneMenu>
			</s:decorate>

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值