闲来无事,做了一个多级地址的demo,模仿了京东的样式:
采用了spring mvc的框架,下面把代码贴上,以后好找:
数据库:
CREATE TABLE IF NOT EXISTS COM_PRO_COUNTRY ( `ID` INT(11) NOT NULL AUTO_INCREMENT,`NAME` VARCHAR (50) NULL,`FULLNAME` VARCHAR (50) NULL,PRIMARY KEY (`ID`)) COLLATE='utf8_bin' ENGINE=InnoDB AUTO_INCREMENT=1;
CREATE TABLE IF NOT EXISTS COM_PRO_PROVINCE ( `ID` INT(11) NOT NULL AUTO_INCREMENT,`NAME` VARCHAR (50) NULL,`FULLNAME` VARCHAR (50) NULL,`COUNTRY` INT (50) NULL,PRIMARY KEY (`ID`)) COLLATE='utf8_bin' ENGINE=InnoDB AUTO_INCREMENT=1;
CREATE TABLE IF NOT EXISTS COM_PRO_CITY ( `ID` INT(11) NOT NULL AUTO_INCREMENT,`NAME` VARCHAR (50) NULL,`FULLNAME` VARCHAR (50) NULL,`PROVINCE` INT (50) NULL,PRIMARY KEY (`ID`)) COLLATE='utf8_bin' ENGINE=InnoDB AUTO_INCREMENT=1;
CREATE TABLE IF NOT EXISTS COM_PRO_DISTRICT ( `ID` INT(11) NOT NULL AUTO_INCREMENT,`NAME` VARCHAR (50) NULL,`FULLNAME` VARCHAR (50) NULL,`CITY` INT (50) NULL,PRIMARY KEY (`ID`)) COLLATE='utf8_bin' ENGINE=InnoDB AUTO_INCREMENT=1;
CREATE TABLE IF NOT EXISTS COM_PRO_ROAD ( `ID` INT(11) NOT NULL AUTO_INCREMENT,`NAME` VARCHAR (50) NULL,`FULLNAME` VARCHAR (50) NULL,`DISTRICT` INT (50) NULL,PRIMARY KEY (`ID`)) COLLATE='utf8_bin' ENGINE=InnoDB AUTO_INCREMENT=1;
可以看出来,有5张表:国家,省市,城市,区,路。京东默认是省,市,区。
Java 代码,主要功能:查询所有国家,根据国家查询所有省市,根据省市查询所有城市,以此类推。
Controller 相关代码:
@RequestMapping(value = "/preAdd.spring", method = RequestMethod.GET)
public ModelAndView preAdd() throws Exception{
ModelAndView mav = new ModelAndView();
String pageUrl = "admin/address/add";
// add other logic.
mav.setViewName(pageUrl);
mav.addObject("addressBean", new AddressBean());
mav.addObject("RoadBeanList", roadService.list());
mav.addObject("CountryBeanList", countryService.list());
return mav;
}
@RequestMapping(value = "/getProvinces.spring", method = RequestMethod.POST)
public @ResponseBody List<ProvinceBean> getProvinces(@RequestParam(value = "id", required = false) Integer id) throws Exception{
return provinceService.list(id);
}
@RequestMapping(value = "/getCitys.spring", method = RequestMethod.POST)
public @ResponseBody List<CityBean> getCitys(@RequestParam(value = "id", required = false) Integer id) throws Exception{
return cityService.list(id);
}
@RequestMapping(value = "/getDistricts.spring", method = RequestMethod.POST)
public @ResponseBody List<DistrictBean> getDistricts(@RequestParam(value = "id", required = false) Integer id) throws Exception{
return districtService.list(id);
}
@RequestMapping(value = "/getRoads.spring", method = RequestMethod.POST)
public @ResponseBody List<RoadBean> getRoads(@RequestParam(value = "id", required = false) Integer id) throws Exception{
return roadService.list(id);
}
Service 的部分代码:
@Override
public List<CountryBean> list() throws ProException {
List<Map<String, Object>> rows = jdbcTemplate.queryForList("SELECT * FROM COM_PRO_COUNTRY");
if (!CommonUtils.isEmptyList(rows)) {
List<CountryBean> beanList = new ArrayList<CountryBean>();
for (Map<String, Object> row : rows) {
CountryBean countryBean = new CountryBean();
countryBean.setId((Integer)row.get("ID"));
countryBean.setName((String)row.get("NAME"));
countryBean.setFullName((String)row.get("FULLNAME"));
beanList.add(countryBean);
}
return beanList;
}
return null;
}
@Override
public List<ProvinceBean> list(int id) throws ProException {
List<Map<String, Object>> rows = jdbcTemplate.queryForList("SELECT * FROM COM_PRO_PROVINCE WHERE COUNTRY = ?", id);
if (!CommonUtils.isEmptyList(rows)) {
List<ProvinceBean> beanList = new ArrayList<ProvinceBean>();
for (Map<String, Object> row : rows) {
ProvinceBean provinceBean = new ProvinceBean();
provinceBean.setId((Integer)row.get("ID"));
provinceBean.setName((String)row.get("NAME"));
provinceBean.setFullName((String)row.get("FULLNAME"));
beanList.add(provinceBean);
}
return beanList;
}
return null;
}
@Override
public List<CityBean> list(int id) throws ProException {
List<Map<String, Object>> rows = jdbcTemplate.queryForList("SELECT * FROM COM_PRO_CITY WHERE PROVINCE =?", id);
if (!CommonUtils.isEmptyList(rows)) {
List<CityBean> beanList = new ArrayList<CityBean>();
for (Map<String, Object> row : rows) {
CityBean cityBean = new CityBean();
cityBean.setId((Integer)row.get("ID"));
cityBean.setName((String)row.get("NAME"));
cityBean.setFullName((String)row.get("FULLNAME"));
beanList.add(cityBean);
}
return beanList;
}
return null;
}
@Override
public List<DistrictBean> list(int id) throws ProException {
List<Map<String, Object>> rows = jdbcTemplate.queryForList("SELECT * FROM COM_PRO_DISTRICT WHERE CITY=?", id);
if (!CommonUtils.isEmptyList(rows)) {
List<DistrictBean> beanList = new ArrayList<DistrictBean>();
for (Map<String, Object> row : rows) {
DistrictBean districtBean = new DistrictBean();
districtBean.setId((Integer)row.get("ID"));
districtBean.setName((String)row.get("NAME"));
districtBean.setFullName((String)row.get("FULLNAME"));
beanList.add(districtBean);
}
return beanList;
}
return null;
}
@Override
public List<RoadBean> list(int id) throws ProException {
List<Map<String, Object>> rows = jdbcTemplate.queryForList("SELECT * FROM COM_PRO_ROAD WHERE DISTRICT=?", id);
if (!CommonUtils.isEmptyList(rows)) {
List<RoadBean> beanList = new ArrayList<RoadBean>();
for (Map<String, Object> row : rows) {
RoadBean roadBean = new RoadBean();
roadBean.setId((Integer)row.get("ID"));
roadBean.setName((String)row.get("NAME"));
roadBean.setFullName((String)row.get("FULLNAME"));
beanList.add(roadBean);
}
return beanList;
}
return null;
}
JSP 相关代码:CSS用到的图片在附件里有.
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ taglib prefix="sec" uri="http://www.springframework.org/security/tags"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>地址</title>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<style type="text/css">
body {
padding-bottom: 40px;
}
.sidebar-nav {
padding: 9px 0;
}
.addressDiv {
display: none;
position: absolute;
border: 1px solid #CECBCE;
width: 390px;
padding: 15px;
background: #fff;
-moz-box-shadow: 0 0 5px #ddd;
-webkit-box-shadow: 0 0 5px #ddd;
box-shadow: 0 0 5px #ddd;
font: 12px/150% Arial, Verdana, "\5b8b\4f53";
}
.stock {
position: relative;
margin-bottom: 10px;
}
.stock .mt .tab {
width: 100%;
height: 25px;
float: left;
border-bottom: 2px solid #edd28b;
overflow: visible;
list-style: none;
margin: 0 0 9px 0px;
}
.stock .mt .tab li {
margin-left: 5px;
float: left;
clear: none;
padding: 0px 5px 5px;
border: 2px solid #CECBCE;
font-style: normal;
border-bottom-color: #edd28b;
}
.stock .mt .tab .curr {
border: 2px solid #edd28b;
border-bottom-color: aliceblue;
}
.stock .mt .tab li a em {
font-style: normal;
}
.clr {
display: block;
overflow: hidden;
clear: both;
height: 0;
line-height: 0;
font-size: 0;
}
.mt {
cursor: default;
}
.stock-line {
margin: 0;
padding: 0;
}
.m,.mt,.mc,.mb,.sm,.smt,.smc,.smb {
overflow: hidden;
zoom: 1;
}
.area-list {
padding-top: 5px;
list-style: none;
float: left;
}
.area-list li {
padding: 2px 0 2px 15px;
width: 50px;
float: left;
clear: none;
}
.close {
position: absolute;
display: inline-block;
width : 14px;
height : 14px;
line-height : 14px;
vertical-align : text-top;
background-image :url("../img/glyphicons-halflings.png");
background-position: -168px -96px;
background-repeat: no-repeat;
}
</style>
</head>
<body>
<input class="input-xlarge focused" id="addressPath" type="text" οnfοcus="openAddressDiv(this)" readonly />
<div id="addressDIV" class="addressDiv">
<div id="stock" class="stock" data-widget="tabs">
<div class="mt">
<ul class="tab">
<li data-index="0" id="addressTab0" class="curr"
data-widget="tab-item" class="display: list-item;"
οnclick="changeTab(0)"><a href="#none"><em>${CountryBeanList[0].name}</em><i></i></a></li>
<li data-index="1" id="addressTab1" data-widget="tab-item"
style="display: none;" class="" οnclick="changeTab(1)"><a
href="#none" class="" title=""><em></em><i></i></a></li>
<li data-index="2" id="addressTab2" data-widget="tab-item"
style="display: none;" class="curr" οnclick="changeTab(2)"><a
href="#none" class="hover" title=""><em></em><i></i></a></li>
<li data-index="3" id="addressTab3" data-widget="tab-item"
style="display: none;" οnclick="changeTab(3)"><a
href="#none" class="" title=""><em></em><i></i></a></li>
<li data-index="4" id="addressTab4" data-widget="tab-item"
style="display: none;" οnclick="changeTab(4)"><a
href="#none" class="" title=""><em></em><i></i></a></li>
</ul>
<div class="stock-line"></div>
</div>
<div class="mc" id="areaList0" data-area="0"
data-widget="tab-content" id="stock_province_item"
style="display: block;">
<ul class="area-list">
<c:forEach var="myItem" items="${CountryBeanList}">
<li><a href="#none" data-value="${myItem.id}"
οnclick="loadProvince('${myItem.id}', '${myItem.name}')">${myItem.name}</a></li>
</c:forEach>
</ul>
</div>
<div class="mc" id="areaList1" data-area="1"
data-widget="tab-content" id="stock_city_item"
style="display: none;">
<ul class="area-list">
</ul>
</div>
<div class="mc" id="areaList2" data-area="2"
data-widget="tab-content" id="stock_area_item"
style="display: none;">
<ul class="area-list">
</ul>
</div>
<div class="mc" id="areaList3" data-area="3"
data-widget="tab-content" id="stock_town_item"
style="display: none;">
<ul class="area-list">
</ul>
</div>
<div class="mc" id="areaList4" data-area="4"
data-widget="tab-content" id="stock_town_item"
style="display: none;">
<ul class="area-list">
</ul>
</div>
</div>
<span class="clr"></span>
<div id="closeAddressDivImg" class="close" οnclick="closeAddressDiv()"></div>
</div>
<script src='../js/address2.js'></script>
</body>
</html>
JS:
var inputElement; function changeTab(id) { clearCSS(); $("#areaList" + id).css("display", ""); $("#addressTab" + id).addClass("curr"); } function loadProvince(id, name) { $("#addressTab0 a em").text(name); clearCSS(); $("#addressTab2").css("display", "none"); $("#addressTab3").css("display", "none"); $("#addressTab4").css("display", "none"); loadProvinces(id); } function doAjaxCall(url, data, suc) { $.ajax({ url : url, type : "POST", data : data, success : suc, error : function(x, e) { alert(e); } }); } function loadProvinces(id) { var data = { id : id }; doAjaxCall("/shop/admin/address/getProvinces.spring", data, loadProvincesSucc); } function loadProvincesSucc(data) { loadSucc(data, 'loadCity', 1); } function loadSucc(data, loadName, index) { var inhtml = ""; for ( var i = 0; i < data.length; i++) { inhtml += "<li><a href='#none' data-value='" + data[i].id + "' οnclick=\"" + loadName + "('" + data[i].id + "','" + data[i].name + "')\">" + data[i].name + "</a></li>"; } $("#areaList" + index + " ul").html(inhtml); $("#areaList" + index).css("display", ""); $("#addressTab" + index).css("display", ""); $("#addressTab" + index).addClass("curr"); $("#addressTab" + index + " a em").text("请选择"); } function loadCity(id, name) { $("#addressTab1 a em").text(name); clearCSS(); $("#addressTab3").css("display", "none"); $("#addressTab4").css("display", "none"); loadCities(id); } function loadCities(id) { var data = { id : id }; doAjaxCall("/shop/admin/address/getCitys.spring", data, loadCitySucc); } function loadCitySucc(data) { loadSucc(data, 'loadDistrict', 2); } function loadDistrict(id, name) { $("#addressTab2 a em").text(name); clearCSS(); $("#addressTab4").css("display", "none"); loadDistricts(id); } function loadDistricts(id) { var data = { id : id }; doAjaxCall("/shop/admin/address/getDistricts.spring", data, loadDistrictSucc); } function loadDistrictSucc(data) { loadSucc(data, 'loadRoad', 3); } function loadRoad(id, name) { $("#addressTab3 a em").text(name); clearCSS(); loadRoads(id); } function loadRoads(id) { var data = { id : id }; doAjaxCall("/shop/admin/address/getRoads.spring", data, loadRoadSucc); } function loadRoadSucc(data) { loadSucc(data, 'submitRoad', 4); } function submitRoad(id, name) { $("#addressTab4 a em").text(name); var addressPath = $("#addressTab0 a em").text() + $("#addressTab1 a em").text() + $("#addressTab2 a em").text() + $("#addressTab3 a em").val() + $("#addressTab4 a em").text(); $(inputElement).val(addressPath); } function clearCSS() { $("#areaList0").css("display", "none"); $("#areaList1").css("display", "none"); $("#areaList2").css("display", "none"); $("#areaList3").css("display", "none"); $("#areaList4").css("display", "none"); $("#addressTab0").removeClass("curr"); $("#addressTab1").removeClass("curr"); $("#addressTab2").removeClass("curr"); $("#addressTab3").removeClass("curr"); $("#addressTab4").removeClass("curr"); } function openAddressDiv(e) { $("#addressDIV").css("left", e.offsetLeft + "px"); $("#addressDIV").css("top", (e.offsetTop + e.offsetHeight) + "px"); $("#addressDIV").fadeIn(); $("#closeAddressDivImg").css("left", ($("#addressDIV").get(0).offsetWidth - 8) +"px"); $("#closeAddressDivImg").css("top", "-7px"); inputElement = e; } function closeAddressDiv() { $("#addressDIV").fadeOut(); }
相关架包:由于架包比较多(spring 3.1.0.RELEASE.jar +jackson 1.8.1.jar),就不上传了,谁想要的可以联系我,我发给你。