JSP mysql SpringMvc下中国省市县三级联动下拉框

关键词 

  JSP  mysql数据库  SpringMvc  ajax   Controller层  Service层  中国地区  省市县  三级联动  下拉框选择

摘要

  因项目需要,写了一个省市县三级联动下拉框,省市县数据由mysql数据库调用,实现联动查询选择省市县后,将数据返回目标数据表,并且可以查看选择结果。

  功能:项目要求可以新增货编辑商品收件人信息,其中省市县信息可以下拉逐级选择

  基本思路:加载jsp页面时,通过java Controller层和Service层,调用获取全部省份,显示省份下拉框;选择省份后,通过change事件调用ajax,通过java Controller层和Service层,找到目标省份下的所有城市,并将数据返回给前台,市下拉框出现对应城市;选择城市后,通过change事件调用ajax,通过java Controller层和Service层,找到目标城市下的劝募县,并将数据返回给前台,县下拉框出现对应县;选择县后,保存数据,并将数据传回mysql数据表union_shop.sql;同考虑一些可能出现的bug;

  为了突出主题内容,以下只贴出主要代码块,供大家参考,个人认为重点难点在于数据传出传入,以及避免市县重名的情况;欢迎大家相互交流!

 

正文

  效果展示,如图:

  jsp部分:主要进行页面展示,文件名--unionshop_edit.jsp,对应java Controller层提到的mv.setViewName()的路径

 

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
<%
	String path = request.getContextPath();
	String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE html>
<html lang="en">
<head>
<base href="<%=basePath%>">
/*javascript放在这里*/		
</head>
<body>
	<form action="unionshop/rest/save.do" name="Form" id="Form" method="post" enctype="multipart/form-data" onsubmit="return save();">
		<input type="hidden" name="id" id="id" value="${pd.id}"/>">
		<table id="table_report" class="table noline">
			<tr>
           <td style="width:90px;text-align: right;padding-top: 13px;"><em>*</em>所在省:</td> <td>
            //以下显示省份下拉框 <select name="addr_province" class="addr_province" id="addr_province" > <c:if test="${pd.addr_province != null && pd.addr_province != ''}"><option value="${pd.addr_province}" selected="selected">${pd.addr_province}</option></c:if>//数据库有对应数据时(即编辑或查看该条数据),显示对应数据 <c:if test="${pd.addr_province == null || pd.addr_province == ''}"><option value="请选择省份">请选择省份</option></c:if> //数据库没有对应数据时(即新建一个项目数据),显示“请选择省份” //生成全部省份下拉框
              <c:choose> <c:when test="${not empty addr_province}"> <c:forEach items="${addr_province}" var="var" varStatus="vs"> <option value="${var.region_name}" >${var.region_name}</option> </c:forEach> </c:when> </c:choose> </select> </td> <td style="width:90px;text-align: right;padding-top: 13px;"><em>*</em>所在城市:</td> <td>
            //以下显示城市信息 <select name="addr_city" class="addr_city" id="addr_city" > <c:if test="${pd.addr_city != null && pd.addr_city != ''}"><option value="${pd.addr_city}" selected="selected">${pd.addr_city}</option></c:if> <c:if test="${pd.addr_city == null || pd.addr_city == ''}"><option value="请选择城市">请选择城市</option></c:if>
              /*这里对应的城市option标签是由JavaScript动态生成*/ </select> </td> </tr> <tr> <td style="width:90px;text-align: right;padding-top: 13px;"><em>*</em>所在区县:</td> //以下显示县信息 <td> <select name="addr_county" class="addr_county" id="addr_county" > <c:if test="${pd.addr_county != null && pd.addr_county != ''}"><option value="${pd.addr_county}" selected="selected">${pd.addr_county}</option></c:if> <c:if test="${pd.addr_county == null || pd.addr_county == ''}"><option value="请选择县">请选择县</option></c:if>
               /*这里对应的县option标签有JavaScript自动生成*/ </select> </td> <td style="width:90px;text-align: right;padding-top: 13px;"><em>*</em>地址详情:</td> <td><input type="text" name="addr_detail" id="addr_detail" value="${pd.addr_detail}" maxlength="32" placeholder="请输入地址详情" title="地址详情"/></td> </tr> <tr> <td style="text-align: center;" colspan="10"> <button id="saveBtn" class="btn btn-primary" type="submit" style="width:100px">保存</button> //保存提交数据,触发form表头的onsubmit时间
</td> </tr> </table> </div> </form> </body> </html> 

  JavaScript部分:实现数据交互

<script type="text/javascript">
    
    //保存
    function save(){
            //以下是当用户未选择省市县是,提醒用户
            if($("#addr_province").val()==""  || $("#addr_province").val()=="请选择省份"){
                popupTip('addr_province', '请选择省份');
                return false;
            }
            if($("#addr_city").val()==""  || $("#addr_city").val()=="请选择城市"){
                popupTip('addr_city', '请选择城市');
                return false;
            }
            if($("#addr_county").val()==""  || $("#addr_county").val()=="请选择县"){
                popupTip('addr_county', '请选择县');
                return false;
            }            
        return true  //返回TRUE后,提交数据到后台
    }
    
    function popupTip(field, msg){
        $("#"+field).tips({
            side:3,
            msg:msg,
            bg:'#AE81FF',
            time:2
        });
        $("#field").focus();
    }
    
    /* 选择省份,并展示城市 */
    $(".addr_province").change(function(){
        var addr_province=$(this).val();
        if(addr_province=="请选择省份"){   
            $(".addr_city").empty(); 
            $(".addr_country").empty(); 
            return false;
        }
        $(".addr_city").empty(); 
        $(".addr_county").empty(); 
        var ajaxObject={
                url:"unionshop/rest/goSelectCity",
                data:{
                    region_name:addr_province
                    },
                success:function (data) { 
                        var str="<option>请选择城市</option>";
                        for(var i=0;i<data.data.length;i++){
                            str=str+"<option value="+data.data[i].region_name+">"+data.data[i].region_name+"</option>";
                        }
                        $(".addr_city").html(str);
                     }, 
                fail:function(){console.log("fail")},
                error:function(){console.log("error")},
        }
        ajaxPost(ajaxObject);            
    })
    /* 选择城市,并展示县*/
    $(".addr_city").change(function(){
        var addr_city=$(this).val();
        if(addr_city=="请选择城市"){
            alert("请选择城市");    
            $(".addr_county").empty(); 
            return false;
        }
        var addr_province=$(".addr_province").val(); //通过省份 城市双选 确保县范围正确(避免同名市县情况)
        $(".addr_county").empty(); 
        var ajaxObject={
                url:"unionshop/rest/goSelectCounty",
                data:{
                    addr_province:addr_province,
                    region_name:addr_city
                    },
                success:function (data) { 
                        var str="<option>请选择县</option>";
                        for(var i=0;i<data.data.length;i++){
                            str=str+"<option value="+data.data[i].region_name+">"+data.data[i].region_name+"</option>";
                        }
                        $(".addr_county").html(str);     
                         console.log(data.data.length);
                         console.log(data.data[0].region_name);
                     }, 
                fail:function(){console.log("fail")},
                error:function(){console.log("error")},
        }
        ajaxPost(ajaxObject);            
    })
    $(".addr_county").change(function(){
        var addr_county=$(this).val();
        if(addr_county=="请选择县"){
            alert("请选择县");
            return false;
        }
        
    })
    

</script>

   java:controller层,后台接收数据

package com.fh.controller.youbao.information.unionshop;

/*import ……*/ 


@Controller
@RequestMapping(value="/unionshop")
public class UnionShopController extends BaseController {
	
	String menuUrl = "unionshop/list.do"; //菜单地址(权限用)
	@Resource(name="unionshopService")
	private UnionShopService unionshopService;
	
	
	/**
	 * rest新增
	 */
/*	@RequestMapping(value="/rest/save" , method=RequestMethod.POST  ,
			produces="application/json;charset=UTF-8")*/
	@RequestMapping(value="/rest/save")
	@ResponseBody
	public ModelAndView restSave(@RequestParam Map<String, Object> params) throws Exception{
			
		PageData pd = new PageData();
		pd.putAll(params);
	
		//保存数据
		unionshopService.save(pd);
		return list(this.getPage());

	}
	

	
	/**
	 * 通过省份确认城市
	 */
	@RequestMapping(value="/rest/goSelectCity" , method=RequestMethod.POST  ,
			produces="application/json;charset=UTF-8")
	@ResponseBody
	public String goSelectCity(@RequestBody Map<String,String> map) throws Exception{
		PageData pd = new PageData();
		pd.putAll(map);
		pd.put("parent_id", 1);
		//获取省份id
		PageData provinceInfor=unionshopService.confirmByRegionNameAndParentId(pd);
		int province_id=Integer.parseInt(String.valueOf(provinceInfor.get("region_id")));
		
		//获取目标省份下的所有city
		PageData thisProvince = new PageData();
		thisProvince.put("parent_id", province_id);
		List<PageData>	addr_city = unionshopService.findByParentId(thisProvince);
		return ResponseMessageEnum.SUCCESS.appendPageDataListToString(addr_city);  //该步骤将目标省份下 的城市信息转化为String格式传给ajax的success函数的data形参
	}
	
	
	/**
	 * 通过省份,城市确认县城
	 */
	@RequestMapping(value="/rest/goSelectCounty" , method=RequestMethod.POST  ,
			produces="application/json;charset=UTF-8")
	@ResponseBody
	public String goSelectCounty(@RequestBody Map<String,String> map) throws Exception{
			
		//获取省份id
		PageData pd_province = new PageData();
		pd_province.put("parent_id", "1");
		pd_province.put("region_name", String.valueOf(map.get("addr_province")));
		PageData provinceInfor=unionshopService.confirmByRegionNameAndParentId(pd_province);
		int province_id=Integer.parseInt(String.valueOf(provinceInfor.get("region_id")));
		
		//获取城市id
		PageData pd_city= new PageData();
		pd_city.put("parent_id", province_id);
		pd_city.put("region_name", String.valueOf(map.get("region_name")));
		PageData cityInfor=unionshopService.confirmByRegionNameAndParentId(pd_city);
		int city_id=Integer.parseInt(String.valueOf(cityInfor.get("region_id")));
		
		//获取目标城市下的所有县
		PageData thisCity = new PageData();
		thisCity.put("parent_id", city_id);
		List<PageData>	addr_county = unionshopService.findByParentId(thisCity);
		return     ResponseMessageEnum.SUCCESS.appendPageDataListToString(addr_county);  //将目标城市下的县数据返回给ajax
	}

	/**
	 * 去新增页面,跳转到我们上面提到的jsp界面
	 */
	@RequestMapping(value="/goAdd")
	public ModelAndView goAdd(){
		ModelAndView mv = this.getModelAndView();
		PageData pd = new PageData();
		PageData pdlist = new PageData();
		pd = this.getPageData();
		try {
			//获取全部省份数据
			pdlist.put("parent_id", 1);
			List<PageData>	addr_province = unionshopService.findByParentId(pdlist);
			mv.addObject("addr_province",addr_province);
			mv.addObject("pdlist", pdlist);
			
			mv.setViewName("information/unionshop/unionshop_edit");
			mv.addObject("msg", "save");
			mv.addObject("pd", pd);
		} catch (Exception e) {
			logger.error(e.toString(), e);
		}						
		return mv;
	}	
	
	/**
	 * 去编辑页面,跳转到我们前面提到的jsp界面
	 */
	@RequestMapping(value="/goEdit")
	public ModelAndView goEdit(){
		logBefore(logger, "去修改UnionShop页面");
		ModelAndView mv = this.getModelAndView();
		PageData pd = new PageData();
		PageData pdlist = new PageData();
		pd = this.getPageData();
		try {
			//获取全部省份数据
			pdlist.put("parent_id", 1);
			List<PageData>	addr_province = unionshopService.findByParentId(pdlist);
			mv.addObject("addr_province",addr_province);
			mv.addObject("pdlist", pdlist);
			
			pd = unionshopService.findById(pd);	//根据ID读取该条数据,包括省市县
			mv.setViewName("information/unionshop/unionshop_edit");
			mv.addObject("msg", "edit");
			mv.addObject("pd", pd);
		} catch (Exception e) {
			logger.error(e.toString(), e);
		}						
		return mv;
	}				
}

    java:service层

package com.fh.service.information.unionshop;



@Service("unionshopService")
public class UnionShopService {

	@Resource(name = "daoSupport")
	private DaoSupport dao;
	
	/*
	* 新增
	*/
	public void save(PageData pd)throws Exception{
		dao.save("UnionShopMapper.save", pd);
	}
	
	
	/*
	* 修改
	*/
	public void edit(PageData pd)throws Exception{
		dao.update("UnionShopMapper.edit", pd);
	}
	

	
	/*
	*列表
	*/
	public List<PageData> list(Page page)throws Exception{
		return (List<PageData>)dao.findForList("UnionShopMapper.datalistPage", page);
	}
	

	/*
	 *查找省份
	 */
	public List<PageData> findByParentId(PageData pd)throws Exception{
		return (List<PageData>)dao.findForList("UnionShopMapper.findByParentId", pd);
	}
	
	/*
	* 通过id获取数据
	*/
	public PageData findById(PageData pd)throws Exception{
		return (PageData)dao.findForObject("UnionShopMapper.findById", pd);
	}
	/*
	 * 通过省份选择城市
	 */
	public PageData confirmByRegionNameAndParentId(PageData pd)throws Exception{
		return (PageData)dao.findForObject("UnionShopMapper.confirmByRegionNameAndParentId", pd);
	}
	

	
}

    XML:mysql数据操作指令

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="UnionShopMapper">
	
	<!-- 新增-->
	<insert id="save" parameterType="pd">
		insert into union_shop(
			addr_province,
			addr_city,
			addr_county,
			addr_detail

		) values (
			#{addr_province},
			#{addr_city},
			#{addr_county},
			#{addr_detail}

		)
	</insert>

	<!-- 修改 -->
	<update id="edit" parameterType="pd">
		update  union_shop
			set 

				addr_province = #{addr_province},
				addr_city = #{addr_city},
				addr_county = #{addr_county},
				addr_detail = #{addr_detail}
			id = id
			where 
				id = #{id}
	</update>

	<!-- 通过id获取数据 -->
	<select id="findById" parameterType="pd" resultType="pd">
		select * from 
			union_shop
		where 
			id = #{id}
	</select>
	
	<!-- 通过省份选城市 -->
	<select id="confirmByRegionNameAndParentId" parameterType="pd" resultType="pd">
		select * from 
			region
		where 
			region_name = #{region_name} and parent_id=#{parent_id}
	</select>		
</mapper>

  mysql文件:中国省市县全部数据信息,文件名--region.sql链接:https://files.cnblogs.com/files/wobuchifanqie/region-mysql.rar;部分内容如下:

  mysql文件:项目接收选择后的省市县具体数据 ,文件名--union_shop.sql,如图:

 

 结论

  本人新手一枚,对我而言,难点在于数据如何交互,以及处理用户一些奇葩操作(比如重新选择,不选择等情况),主要集中在JavaScript部分;,还有要考虑省市县出现同名的情况

  写于此,2017-04-20-下午;备用

posted on 2017-04-20 17:11  我不吃番茄  阅读(5792)  评论(7编辑  收藏  举报