html页面下拉列表中动态添加后台数据(格式化数据,显示出数据的层次感)
效果图:
运行原理和技术:
当页面加载完毕,利用jquery向后台发送ajax请求,去后台拼接<select></select>中的option字符串。让后将字符串响应回来,动态添加到<select>中。其中的字符串中包含了后台的数据。
页面js代码:
1 <script type="text/javascript"> 2 //加载部门 3 function loadSysGroup(){ 4 var groups=document.getElementById("selectObj"); 5 if(groups == null ){ 6 return; 7 } 8 $.ajax({ 9 type:"POST", 10 url:"<%=request.getContextPath() %>"+"/master/sysGroup_getOptions.action", 11 dataType:"json", 12 success:function(data){ 13 var options=data["options"]; 14 groups.innerHTML="<option value='0'>--请选择--</option>"+options; 15 16 } 17 }); 18 } 19 20 //当页面加载完成后,加载部门 21 $(document).ready(function(){ 22 loadSysGroup(); 23 }); 24 </script> 25 26 <li><label>所属部门</label><select id="selectObj" name="sysGroupId"> </select></li>
后台action和sercive方法(省去dao层查数据的方法,主要是体现加工字符串)
1 /**action 层 2 * ajax查询出所有的部门信息 3 * @Title: ajaxQueryGroup 4 * @Description: TODO(这里用一句话描述这个方法的作用) 5 * @return 6 * @return String 返回类型 7 * @author 尚晓飞 8 * @date 2014-9-4 上午11:36:15 9 */ 10 public String ajaxQueryGroup(){ 11 12 try { 13 14 String sbString=sysUserService.findQueryGroup(); 15 jsonObject.put("options", sbString); 16 17 } catch (Exception e) { 18 // TODO: handle exception 19 e.printStackTrace(); 20 return "error"; 21 }finally{ 22 out.print(jsonObject); 23 out.close(); 24 } 25 26 return null; 27 } 28 29 30 /**service层的加工数据 31 * 加载出组 32 * @Title: findQueryGroup 33 * @Description: TODO(这里用一句话描述这个方法的作用) 34 * @author 尚晓飞 35 * @date 2014-9-25 上午11:38:16 36 * @return 37 * @see org.ledger.service.SysUserService#findQueryGroup() 38 */ 39 @Override 40 public String findQueryGroup() { 41 // TODO Auto-generated method stub 42 StringBuffer str=new StringBuffer(); 43 //院属单位institute_unit 非院属单位research_center 44 //第一步拼接院属单位 45 str.append("<optgroup label="院属单位">");//optgroup是页面分类,无值。 46 MyClass myClass=new MyClass(); 47 myClass.handleSb("institute_unit", 0);//算是一个父id 48 str.append(myClass.sb.toString()); 49 str.append("</optgroup>"); 50 51 //第二步拼接非院属单位 52 str.append("<optgroup label="非院属单位">"); 53 MyClass myClass2=new MyClass(); 54 myClass2.handleSb("research_center", 0); 55 str.append(myClass2.sb.toString()); 56 str.append("</optgroup>"); 57 58 return str.toString(); 59 } 60 61 /** 62 * 内部类(加工数据的主要)递归 63 * @ClassName: myClass 64 * @Description: TODO(这里用一句话描述这个类的作用) 65 * @author 尚晓飞 66 * @date 2014-9-25 上午11:46:34 67 *本示例,第一级没有加标示,数据只有两级,如果后台数据有多个级别的话,则会显示层次关系。掌握思想 68 */ 69 class MyClass{ 70 StringBuffer sb=new StringBuffer(); 71 72 //拼接内容 73 public void handleSb(String unitType,Integer num){ 74 //根据父id查询出符合条件的集合(父子关系,在数据库表中,父的主键id 是子的父级id字段的值) 75 List<SysGroup> listGroups=sysGroupService.queryGroupsByType(unitType); 76 //如果不为空,则进行拼接加工字符串 77 if(listGroups!=null&&listGroups.size()>0){ 78 int m=0;//用来记录循环的次数 79 num++;//用来记录运行该方法的次数 80 81 for(int i=0;i<listGroups.size();i++){ 82 sb.append("<option value=""+listGroups.get(i).getSysGroupId()+"">"); 83 84 //决定位置 85 //一次递归说明是一个等级,则需要层次分明,则进行加空格,至于加多少,用递归次数决定,从而显示出层次感 86 for(int j=1;j<num;j++){ 87 sb.append(" "); 88 } 89 90 //决定前边装饰的符号 91 if(num!=1){ 92 if(m<(listGroups.size()-1)){ 93 //说明循环没有到最后一次 94 sb.append(" ┠ "); 95 }else { 96 sb.append(" ┖ "); 97 } 98 }else { 99 sb.append(" "); 100 } 101 102 //添加名字 103 sb.append(listGroups.get(i).getSysGroupName()); 104 sb.append("</option>"); 105 //循环一次了,循环次数的标示自增1 106 m++; 107 108 //递归。用于添加当前组的子组(如果有,则sb会添加,如果没有,该方法运行一下,进入当前层的下一次循环) 109 handleSb(listGroups.get(i).getSysGroupId(), num); 110 } 111 112 } 113 } 114 115 }