菜单的三级联动[城市]

如何做一个三级联动的菜单

效果:选择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格式的数据转换为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格式的数据转换为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格式的数据转换为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>

搞定三级菜单联动问题,最终效果如下:

猜你喜欢

转载自www.cnblogs.com/IT_CH/p/12350081.html