[原创于: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>