先上效果图,最近项目中出现四级联动,因为花费很长时间去弄这个东西,所以整理一下,方便以后的使用。
对于四级联动,因为开始并没有去弄明白他是怎么回事,开始是在js中定义一个四维数组,然后不停的去遍历这个四维数组,导致变量越来越多,根本没法控制,同时代码的可读性很差。所以现在采用前台根据所选择的id,传到后台,后台返回一个json串,不仅方便解析,而且增加了程序的可读性。
var db = {
实用新型: {
实用新型: {
新型编写: "A,B,C",
新型交底: "A,B,C",
新型材料优化: "A,B,C",
},
},
发明: {
发明: {
发明编写: "A,B,C",
发明交底: "A,B,C",
发明材料优化: "A,B,C",
},
高级发明: {
高级发明: "S",
},
包授权发明: {
包授权发明: "SS",
},
},
外观: {
外观: {
外观设计: "W",
}
}
};
数据处理
对于这个四维数组是不是头皮发麻,不过现在没有关系,我们可以写一个工具类,对其进行相应的转换。
/**
* 转换四级联动的工具类
* @author hxs
* @version 2018-07-21
*/
public class LevelObj {
private String id;
private String name;
public LevelObj(){}
public LevelObj(String id,String name) {
this.name = name;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
在controller中定义几个方法,用来返回相应的json串(id没特殊要求可以随便命名,只要可以得到相应的数据都是可以的)。
@ResponseBody
@RequestMapping(value = "getLevel1")
public Object getLevel1(){
List<LevelObj> list =new ArrayList<LevelObj>();
list.add(new LevelObj("1","实用新型"));
list.add(new LevelObj("2","发明"));
list.add(new LevelObj("3","外观"));
return list;
}
@ResponseBody
@RequestMapping(value = "getLevel2")
public Object getLevel2(String level1){
List<LevelObj> list =new ArrayList<LevelObj>();
if("1".equals(level1)){
list.add(new LevelObj("21","实用新型"));
}else if("2".equals(level1)){
list.add(new LevelObj("22","发明"));
list.add(new LevelObj("23","高级发明"));
list.add(new LevelObj("24","包授权发明"));
} else if("3".equals(level1)){
list.add(new LevelObj("25","外观"));
}
return list;
}
@ResponseBody
@RequestMapping(value = "getLevel3")
public Object getLevel3(String level2){
List<LevelObj> list =new ArrayList<LevelObj>();
if("21".equals(level2)){
list.add(new LevelObj("31","新型编写"));
list.add(new LevelObj("32","新型交底"));
list.add(new LevelObj("33","新型材料优化"));
}else if("22".equals(level2)){
list.add(new LevelObj("34","发明编写"));
list.add(new LevelObj("35","发明交底"));
list.add(new LevelObj("36","发明材料优化"));
}else if("23".equals(level2)){
list.add(new LevelObj("37","高级发明"));
}
else if("24".equals(level2)){
list.add(new LevelObj("38","包授权发明"));
} else if("25".equals(level2)){
list.add(new LevelObj("39","外观设计"));
}
return list;
}
@ResponseBody
@RequestMapping(value = "getLevel4")
public Object getLevel4(String level3){
List<LevelObj> list =new ArrayList<LevelObj>();
if("31".equals(level3) || "32".equals(level3) || "33".equals(level3)
||"34".equals(level3) || "35".equals(level3) || "36".equals(level3)){
list.add(new LevelObj("A","A"));
list.add(new LevelObj("B","B"));
list.add(new LevelObj("C","C"));
}else if("37".equals(level3)){
list.add(new LevelObj("S","S"));
}else if("38".equals(level3)){
list.add(new LevelObj("SS","SS"));
}
else if("39".equals(level3)){
list.add(new LevelObj("W","W"));
}
return list;
}
现在可以通过访问,得到相应的数据了。
前台处理
我的表格数据是通过js拼接成的,因为这样方便批量添加的处理。
/* 案件类型 */
tr.append($("<td></td>").html(
"<select class='input-medium patType' emptyOption='false'
onchange='changeSelect1(this)' style='width: 100px;'>" +
"<option>---请选择---</option>" +
"</select>")
);
/* 编写类型 */
tr.append($("<td></td>").html(
"<select class='input-medium patCustomTypeId' emptyOption='false'
onchange='changeSelect2(this)' style='width: 100px;'>" +
"<option>---请选择---</option>" +
"</select>")
);
/* 详细类型 */
tr.append($("<td></td>").html(
"<select class='input-medium patCustomDetailTypeId' emptyOption='false'
onchange='changeSelect3(this)' style='width: 100px;'>" +
"<option>---请选择---</option>" +
"</select>")
);
/* 价值度 */
tr.append($("<td></td>").html(
"<select class='input-medium value' emptyOption='false'style='width: 100px;'>" +
"<option>---请选择---</option>" +
"</select>")
);
然后表单拼接完成的时候,会通过ajax获取一级菜单
// 一行拼接完毕,加载一级菜单
$.ajax({
url: '${ctx}/hfxt/hfxtOaSalesmanOrder/getLevel1',
data: {},
dataType: 'json',
success: function(result) {
// console.log("result"+result);
$.each(result,function(index,element){
tr.find(".patType").append("<option value='"+element.id+"'>"+element.name+" </option>");
});
}
})
通过一级菜单的选择,触发changeSelect1()方法
function changeSelect1(_this){
console.log($(_this).val());
/* 获取当前select的value值 */
var level1Id =$(_this).val();
/* 通过当前的位置确定整行tr的域,后面的操作都会限定在这个tr域中进行 */
var trObj = $(_this).parent().parent();
$.ajax({
url: '${ctx}/hfxt/hfxtOaCommitPatentOrder/getLevel2',
type: 'POST',
data: {'level1':level1Id},
dataType: "json",
success: function (result) {
console.log(result);
var optionStr ="<option>---请选择---</option>" ;
/* 对返回的结果进行遍历 */
$.each(result,function (index,element) {
// console.log(element);
optionStr = optionStr + "<option value='"+element.id+"' >"+element.name+"</option>";
});
/* 防止每次拼接之后的无限追加 */
trObj.find(".patCustomTypeId").empty();
trObj.find(".patCustomTypeId").append(optionStr);
},
error: function () {
$.jBox("出错!");
}
});
}
后面的几个方法跟这个方法类似,所以我对这个方法进行了一下封装。
/* 编写类型价值度等四级联动 */
function changeSelect(_this,url,level,clazz) {
/* 获取当前select的value值 */
var level1 = $(_this).val();
console.log(level1);
/* ajax请求的参数,根据level的值返回相应的json数据 */
var paraStr=level+"="+level1;
/* 通过当前的位置确定整行tr的域,后面的操作都会限定在这个tr域中进行 */
var trObj = $(_this).parent().parent();
$.ajax({
url: '${ctx}/hfxt/hfxtOaSalesmanOrder/'+url+"?"+paraStr,
type: 'post',
data: {},
dataType: 'json',
success: function(result){
//console.log("url====>"+this.url);
// console.log("result====>"+result);
var optionStr = "<option value=''>---请选择---</option>";
/* 对返回的结果进行遍历 */
$.each(result,function (index,element) {
optionStr += "<option value='"+element.id+"'>"+element.name+"</option>";
});
// $("."+clazz,trObj).empty();
/* 防止每次拼接之后的无限追加 */
trObj.find("."+clazz).empty();
trObj.find("."+clazz).append(optionStr);
}
});
}
所以前面的表单onchange事件也需要修改一下
/* 案件类型 */
tr.append($("<td></td>").html(
"<select class='input-medium patType' emptyOption='false' onchange='changeSelect(this,\"getLevel2\",\"level1\",\"patCustomTypeId\")' style='width: 100px;'>" +
"<option>---请选择---</option>" +
"</select>")
);
/* 编写类型 */
tr.append($("<td></td>").html(
"<select class='input-medium patCustomTypeId' emptyOption='false' onchange='changeSelect(this,\"getLevel3\",\"level2\",\"patCustomDetailTypeId\")' style='width: 100px;'>" +
"<option>---请选择---</option>" +
"</select>")
);
/* 详细类型 */
tr.append($("<td></td>").html(
"<select class='input-medium patCustomDetailTypeId' emptyOption='false' onchange='changeSelect(this,\"getLevel4\",\"level3\",\"value\")' style='width: 100px;'>" +
"<option>---请选择---</option>" +
"</select>")
);
/* 价值度 */
tr.append($("<td></td>").html(
"<select class='input-medium value' emptyOption='false' style='width: 100px;'>" +
"<option>---请选择---</option>" +
"</select>")
);