如何做一个三级联动的菜单
效果:选择1级菜单,显示2级的对应的菜单,选择2级菜单,显示3级对应的菜单;
重新选择1级,2级3级下拉菜单全部清空;
1.数据准备
2.先用代码生成器生成dto,mapper层代码
代码生成器的使用.....【待补】
只用修改dto层的代码【我们需要对查询出来的结果进行排序,对象排序需要实现Comparable接口】
/** * 使用hibernate validator出现上面的错误, 需要 注意 * * @NotNull 和 @NotEmpty 和@NotBlank 区别【添加该注解主要是做添加菜单的时候做验证--如果只做联动,可以不加该注解】 * * @NotEmpty 用在集合类上面 * @NotBlank 用在String上面 * @NotNull 用在基本类型上 */ @Data public class TbCategory implements Comparable<TbCategory>{ private Long id; @NotBlank(message = "分类名称是必填项") private String name; private Long parentId; private Boolean isParent; @NotNull(message = "排序是必填项") private Integer sort; private List<TbCategory> children;
@Override public int compareTo(TbCategory o) { if (this.sort > o.sort) return 1; if(this.sort < o.sort){ return -1; }else{ return 0; } } }
3.service层的代码[只需一个方法即可]
@Override //重写父类的根据父id查询所有的数据 public List<TbCategory> queryAllByParentId(long pid) { log.info("数据查询成功"); //先实例化一个Example TbCategoryExample example = new TbCategoryExample(); //使用example进行条件查询 TbCategoryExample.Criteria criteria = example.createCriteria(); //通过父id查询 criteria.andParentIdEqualTo(pid); //开始执行查询 List<TbCategory> list = menu.selectByExample(example); //对结果进行排序【排序的前提:必须要实现Comparable接口】 Collections.sort(list); return list; }
4.Controller层的代码
@Controller //spring的四大注解之一,只要添加了该注解的类,程序一运行就会自动加入到IOC容器当中 @Log4j //打日志 public class GoodsController_SpecsParam_add { @Autowired //自动注入 private GoodsService_Menu menu; @RequestMapping("/specsParam/add/getOne") //获取一级菜单 @ResponseBody //将数据转换为JSON格式的数据 public List<TbCategory> getOne(Model model){ List<TbCategory> list = menu.queryAllByParentId(0); model.addAttribute("data",list); return list; } @RequestMapping("/specsParam/add/getTwo") //获取二级菜单 @ResponseBody //将数据转换为JSON格式的数据 public List<TbCategory> getTwo(Model model, Long parentid){ List<TbCategory> list = menu.queryAllByParentId(parentid); model.addAttribute("data",list); return list; } @RequestMapping("/specsParam/add/getThree") //获取三级菜单 @ResponseBody //将数据转换为JSON格式的数据 public List<TbCategory> getThree(Model model, Long parentid){ List<TbCategory> list = menu.queryAllByParentId(parentid); model.addAttribute("data",list); return list; } }
5.jsp页面代码
<tr> <td>所属类目:</td> <td> <select name="" id="one"> <option value="">1级类目</option> </select> <select name="" id="two"> <option value="">2级类目</option> </select> <select name="" id="three"> <option value="">3级类目</option> </select> </td> <td style="color: red;">${error}</td> </tr>
6.JQuery代码
<script type="text/javascript"> $(function () { //进入添加页面,先自动加载一级菜单 $.ajax({ //请求地址 url:'${pageContext.request.contextPath}/specsParam/add/getOne', //请求成功 success:function (data) { console.log(data) if(!data) return var html="" for (var e in data){ html += '<option value='+data[e].id+'>'+data[e].name+'</option>' } $("#one").html("<option value=''>1级类目</option>") $("#one").append(html) //当一级菜单发生改变的时候,要将二级三级菜单清空 $("#one").change(function () { $("#two").html("<option value=''>2级类目</option>") $("#three").html("<option value=''>3级类目</option>") getTwo($(this).val()) }) } }) //根据所选择的一级菜单获取二级菜单 function getTwo(id) { $.ajax({ //请求的地址 url: '${pageContext.request.contextPath}/specsParam/add/getTwo', //选择的一级菜单的id值,传递的必须是一个JSON格式的数据 data: {"parentid":id}, //请求成功 success:function (data) { if (!data) return; var html = ''; for (var e in data){ html += '<option value='+data[e].id+'>'+data[e].name+'</option>'; } $("#two").html("<option value=''>2级类目</option>") $("#two").append(html) //如果二级菜单发生改变,将三级菜单清空 $("#two").change(function () { $("#three").html("<option value=''>3级类目</option>") getThree($(this).val()) }) } }) } //根据选择的二级菜单选择三级菜单 function getThree(id) { $.ajax({ url: '${pageContext.request.contextPath}/specsParam/add/getThree', data: {"parentid":id}, success: function (data) { if (!data) return; var html = ""; for (var e in data){ html += '<option value='+data[e].id+'>'+data[e].name+'</option>'; } //由于测试中,发现越点越多[重复出现],所以,append之前先将原先的数据清空,就不会出现该问题了 $("#three").html("<option value=''>3级类目</option>") $("#three").append(html) } }) } }) </script>
搞定三级菜单联动问题,最终效果如下: