页面上的级联菜单的实现,在网上有很多资料,实现起来也相对简单。这里呢,由于我也花了一些时间研究,所以在此跟大家分享一下开发经验。
目前,我认为能够实现菜单联动主要有这么两个思路:
1、页面加载时,每个选择框都要加载数据。当用户对选择框开始选择时,再进行精确定位。这种方式直接使用JavaScript实现很轻松;
2、页面加载时,只显示第一个选择框的所有数据。当用户进行选择后,再去加载第二个选择框的数据。
技术实现有这么几个参考:
1、直接写ajax代码,在页面中直接采用ajax提交的方式;
2、由于项目中使用dwz框架,可以模拟dwz框架中联动菜单的例子进行实现;
3、采用dwr框架,用户选择下拉框后调用后台java类,加载数据。
我这里的实现,采用了第二种实现思路以及dwr框架。
本例开发环境:struts2+Spring+dwr。dwr的环境配置以及与Spring的集成就不说了,大家可以自己搜,也可以在八期童鞋博客里边儿找,这里主要说实现思路。
Demo介绍:根据学院和专业信息查询班级信息。任何一个学院都有多个专业,学院与专业都以下拉框的形式作为查询条件。
实现思路:
1、页面初次加载时,加载学院信息;
2、用户选择查询条件,选择学院时,使用js添加专业信息;
3、用户提交时查询条件时,由于会刷新界面,选择添加会消失,这时需要将学院id,专业id以及页面信息都发送到后台action,在后台重新查询一次,前台重新绑定。
1、html中的主要代码
这里关于专业的绑定信息,页面初次加载时,不会进行绑定。这里进行绑定的作用是进行定位,点击查询后,将专业的id传到后台,将数据重新查一次,保持数据。
<form name="searchForm" rel="pagerForm" οnsubmit="return navTabSearch(this);" action="${contextPath }/classes/queryClassesAction.action" method="post">
<div class="searchBar" >
<table class="searchContent">
<tr>
<td>
<label>学院</label>
<select id="collegeName" name="collegeName" οnchange="getDepartmentByCollegeId()">
<option value="">--请选择学院--</option>
<c:forEach items="${college }" var="college" >
<option id="${college.id }" value="${college.id }" ${college.id eq collegeId ? "selected":"" }>${college.name }</option>
</c:forEach>
</select>
</td>
<td>
<label>专业</label>
<select id="departmentName" name="departmentName" οnchange="getDepartment(this)">
<option value="">--请选择专业--</option>
<c:forEach items="${department }" var="department" >
<option id="${department.id}" value="${department.id }" ${department.id eq departmentId ? "selected":"" }>${department.name }</option>
</c:forEach>
</select>
</td>
</tr>
</table>
</div>
</form>
2、js代码
getDepartmentByCollegeId()方法即为根据学院Id,查询专业信息。选择学院下拉框选择条件时触发。该方法调用后台dwrManager,获取专业信息。
<script type="text/javascript" src="dwr/engine.js"></script>
<script type="text/javascript" src="dwr/util.js"></script>
<script type="text/javascript" src="dwr/interface/departmentService.js"></script>
<script type="text/javascript">
/*
* 根据学院Id得到专业信息
*/
function getDepartmentByCollegeId(){
var college = document.getElementById("collegeName");
collegeId = college.options[college.selectedIndex].value;
var department = document.searchForm.departmentName;
department.options.length=1;
department.options[0] = new Option("--请选择专业--"," ");
//dwr调用后台方法,根据学院Id查询专业信息
departmentService.getDepartmentByCollegeId(
collegeId,
function(datas){
var dataArray = eval(datas);
//依次遍历传回的json每条数据
for (var i = 0; i < dataArray.length; i++) {
//传递参数
department.options[i] = new Option(dataArray[i].name,dataArray[i].id);
}
department.options[0].selected=true;
}
);
}
</script>
3、通过dwr返回json串
下面代码返回类似于这样的串:"[{"id":"123","name":"456"}]"
/**
* @author : lzq
* @group : tgb8
* @Date : 2014-2-18 下午8:31:41
* @Comments : dwr
* @Version : 1.0.0
*/
public class DwrManager {
private IClassesBean classesService;
/**
* @MethodName : getDepartmentByCollegeId
* @Description : 根据学院Id获取专业
* @param collegeId
* @return
*/
public String getDepartmentByCollegeId(String collegeId){
String out = "";
List<Department> departments = classesService.findDepartmentByCollegeId(collegeId);
if(!"".equals(departments) && departments!=null){
// out+="[[\" \", \""
// +"--请选择--"+"\"],";
out= "[{\"id\":\""+" "+"\",\"name\":\""+"--请选择专业--"+"\"},";
// out+= "[";
for(int i=0;i<departments.size();i++){
out+="{\"id\":\""
+departments.get(i).getId()+"\",\"name\":\""
+departments.get(i).getName()+"\"},";
}
out=out.substring(0, out.length()-1)+"]";
}
// outMsg(out);
// String a= "[{\"id\":\"123\",\"name\":\"456\",}]";
return out;
}
public IClassesBean getClassesService ( ) {
return classesService;
}
public void setClassesService ( IClassesBean classesService ) {
this.classesService = classesService;
}
}
4、action中的实现
这里包含private initQueryClasses()、private queryEqualName()和 public queryClasses()三个方法。前两个方法供queryClasses方法调用。
私有方法initQueryClasses(),加载所有学院信息,如果学院Id不为空,则根据学院Id查询对应的专业信息。并将学员信息、专业信息设到request中;
私有方法queryEqualName(),判断如果查询条件不空,则将其穿到后台进行查询。
公有方法queryClasses(),action的查询方法,初始信息,设置查询条件,调用Manager方法并返回查询界面。
/**
* @author : lzq
* @group : tgb8
* @Date : 2014-1-4 下午12:51:33
* @Comments : 班级管理的action
* @Version : 1.0.0
*/
public class ClassesAction extends ActionSupport {
//注入实体
private College college;
private Department department;
private Classes classes;
protected HttpServletRequest request = ServletActionContext.getRequest();
//注入两个选择框的name属性名
private String departmentName;
private String collegeName;
//班级服务
private IClassesBean classesService;
/**
* @MethodName : queryClasses
* @Description : 查询班级
* @return
*/
public String queryClasses()
{
//初始化查询信息
HttpServletRequest requests= initQueryClasses(request);
//等值查询条件
LinkedHashMap<Object, Object> equalFields = queryEqualName();
//查询班级,调用后台方法
PageModel<Classes> pageModel=classesService.queryAllClasses(equalFields);
requests.setAttribute("pageModel", pageModel);
//返回
return "class_list";
}
/**
* @MethodName : queryEqualName
* @Description : 等值查询
* @return
*/
private LinkedHashMap<Object, Object> queryEqualName ( ) {
LinkedHashMap<Object, Object> equalFields=new LinkedHashMap<Object, Object>();
//学院名称
if(!"".equals(college) && college!=null)
{
if(!"".equals(college.getInstitutionId()) && college.getInstitutionId()!=null){
equalFields.put("department.college.collegeId",college.getCollegeId());
}
}
//专业名称
if(!"".equals(departmentName) && departmentName!=null){
equalFields.put("department.id",departmentName);
}
return equalFields;
}
/**
* @MethodName : initQueryClasses
* @Description : 初始化查询条件
* @param request
* @return
*/
private HttpServletRequest initQueryClasses (HttpServletRequest request) {
if(!"".equals(collegeName) && collegeName!=null){
//调用后台方法:根据学院Id查询专业
List<Department> departments = classesService.findDepartmentByCollegeId(collegeName);
request.setAttribute("department", departments);
request.setAttribute("collegeId", collegeName);
}
if(!"".equals(departmentName) && departmentName!=null){
request.setAttribute("departmentName",departmentName);
}
//查询所有学院,并将学院设置到request中
List<College> colleges = classesService.findAllCollege();
request.setAttribute("college",colleges);
return request;
}
/*----------------------------------get/set------------------------------------------------ */
//略
}
以上就是联动及定位的实现思路,如果大家有更好的实现方法,请务必告诉我哈~~
注意:
1、下拉框问题:
可以根据下来框的name属性,获取选择的选项id,所以上面代码中学院id会表示为collegeName和dopartmentName;
2、由于项目中使用dwz框架,如果不适用dwz封装的下拉框,那么<select class="combox" name="name">应改成<select name="name">即去掉class属性,不然就会默认使用dwz的样式,并优先使用dwz的封装的下拉框实现。