ajax巨好用,4级级联菜单的解决 (转)

为解决省、市、区、区域4级级联菜单,在网上搜索了大量的级联菜单解决方案,也请教过不少朋友,要么过于复杂,要么过于占内存,未果。

在建议下,悉心读《ajax基础教程》4余遍,方有与ajax相识恨晚之感,唯一的感慨就是好用好用绝对好用。

现在把已经可以正常运行的例子的核心代码分享:
客户端ajax代码如下:
<script type="text/javascript">
        var xmlHttp;
        var domainId;
        var type;
        
        function refreshList(typesource) {
            createXMLHttpRequest();
            type 
=  typesource;
            
if ("p" ==
 type) {
                getSelectedId(
"province_select"
);
            } 
else if("c" ==
 type) {
                getSelectedId(
"city_select"
);
            } 
else if("s" ==
 type) {
                getSelectedId(
"section_select"
);
            } 
            var url 
= "enterpriseManage2.html?method=retrieve&ts=" + new
 Date().getTime();
            var queryStr 
= "domainId=" +
 domainId;
            alert(queryStr);
            xmlHttp.onreadystatechange
=
handleStateChange;
            xmlHttp.open(
"POST"
, url);
            xmlHttp.setRequestHeader(
"Content-Type","application/x-www-form-urlencoded;"
);
            xmlHttp.send(queryStr);
        }
        
        function handleStateChange() {
            
if (xmlHttp.readyState == 4
) {
                
if (xmlHttp.status == 200
) {
                    updateList();
                }
            }
         }
         
         function getSelectedId(elementId) {
             alert(
"elementId: " +
 elementId);
             
//var selectedId = null;

             var options =  document.getElementById(elementId).childNodes;
             var option 
= null
;
             
for (var i = 0, n = options.length; i < n; i++
) {
                 option 
=
 options[i];
                 
if
 (option.selected) {
                     domainId 
=
 option.value;
                     
//return selectedId;

                 }
             }
         }
         
         function updateList() {
             alert(
"type: " +
 type);
             
if ("p" ==
 type) {
                 var select 
= document.getElementById("city_select"
);
                 var options 
= xmlHttp.responseXML.getElementsByTagName("domain");

                 for (var i = 0, n = options.length; i < n; i++ ) {
                     select.appendChild(createElementWithValue(options[i]));
                 }
             } 
else if("c" ==
 type) {
                 var select 
= document.getElementById("section_select"
);
                 var options 
= xmlHttp.responseXML.getElementsByTagName("domain");

                 for (var i = 0, n = options.length; i < n; i++ ) {
                     select.appendChild(createElementWithValue(options[i]));
                 }    
             } 
else if("s" ==
 type) {
                 var select 
= document.getElementById("appointDomain"
);
                 var options 
= xmlHttp.responseXML.getElementsByTagName("domain"
);
                 
for (var i = 0, n = options.length; i < n; i++
) {
                     select.appendChild(createElementWithValue(options[i]));
                 }    
             }
         }

         
         function createElementWithValue(text) {
             var element 
= document.createElement("option" );
             element.setAttribute(
"value", text.getAttribute("id"
));
             var text 
=
 document.createTextNode(text.firstChild.nodeValue);
             element.appendChild(text);
             
return
 element;
         }
        
        function createXMLHttpRequest() {
            
if(window.XMLHttpRequest) {

                    xmlHttp = new  XMLHttpRequest();
                } 
else if (window.ActiveXObject) {

                    try  {
                        xmlHttp 
= new ActiveXObject("Msxml2.XMLHTTP"
);
                    } 
catch
 (e) {
                        
try
 {
                            xmlHttp 
= new ActiveXObject("Microsoft.XMLHTTP"
);
                        } 
catch
 (e) {
                        }
                    }
                }
        }

    
</script>


页面调用处代码如下:
<td align="left" class="list_content" width="75%">
    省
   
<select id="province_select" name="province_select" onchange="refreshList('p');">  
        
<option value="" SELECTED>请选择</option>

            
<%
                java.util.Iterator it 
= ((java.util.List)request.getAttribute("province_options" )).iterator();
               
while
 (it.hasNext()) {
                    Province province 
=
 (Province)it.next();
             
%>

             
<option value=<%=province.getId()%>><%=province.getName()%></option>
             
<%
                 }
             
%>

   
</select>
    市
   
<select id="city_select" name="city_select" onchange="refreshList('c');">      
         <option value="" SELECTED>请选择</option>
   
</select>
    区
   
<select id="section_select" name="section_select" onchange="refreshList('s');">  
        
<option value="" SELECTED>请选择</option>

   
</select>
    区域
   
<select id="appointDomain" name="appointDomain">  
        
<option value="" SELECTED>请选择</option>

   
</select>
</td>


服务器端action(Struts)代码如下:
 1 public  ActionForward retrieve(ActionMapping mapping, ActionForm actionForm,
 2 
            HttpServletRequest request, HttpServletResponse response) {
 3         String domainId = request.getParameter("domainId"
);
 4         DomainFactory factory =
 DomainFactory.getInstance();
 5         Object domain =
 factory.getDomain(domainId);
 6         StringBuffer responseXML = new StringBuffer("<domains>"
);
 7         if(domain instanceof
 Province) {
 8             Province province =
 (Province)domain;
 9             Iterator it =
 province.getCities().iterator();
10             while
 (it.hasNext()) {
11                 City city =
 (City)it.next();
12                 responseXML.append("<domain"
);
13                 responseXML.append(" id='" +
 city.getId());
14                 responseXML.append("'>"
);
15 
                responseXML.append(city.getName());
16                 responseXML.append("</domain>"
);
17 
            }
18         } else if(domain instanceof
 City) {
19             City city =
 (City)domain;
20             Iterator it =
 city.getSections().iterator();
21             while
 (it.hasNext()) {
22                 Section section =
 (Section)it.next();
23                 responseXML.append("<domain"
);
24                 responseXML.append(" id='" +
 section.getId());
25                 responseXML.append("'>"
);
26 
                responseXML.append(section.getName());
27                 responseXML.append("</domain>"
);
28 
            }
29         } else if (domain instanceof
 Section) {
30             Section section =
 (Section)domain;
31             Iterator it =
 section.getRegions().iterator();
32             while
 (it.hasNext()) {
33                 Region region =
 (Region)it.next();
34                 responseXML.append("<domain"
);
35                 responseXML.append(" id='" +
 region.getId());
36                 responseXML.append("'>"
);
37 
                responseXML.append(region.getName());
38                 responseXML.append("</domain>"
);
39 
            }
40 
        } 
41         responseXML.append("</domains>"
);
42         response.setContentType("text/xml"
);
43         try
 {
44             PrintWriter out =
 (PrintWriter)response.getWriter();
45 
            out.write(responseXML.toString());
46 
            System.out.println(responseXML.toString());
47             //out.flush();

48         } catch  (IOException e) {
49             //do nothing

50              e.printStackTrace();
51 
        }
52         return null
;
53     }


附注:这里用jsp或者servlet都可行。今天还看到一个朋友在dearbook上问某书的示例为啥不用Servlet而用JSP,

问题如下:读第*章,发现XMLHttpRequest.open(method,url,true)中的url请求的都是jsp,然后由jsp再调用处理方法,然后再out.print().不能直接发送请求到servlet让servlet处理再out.print()?疑惑...?

我的观点:
jsp的调用和out打印与servlet本质上是一致的;如果采用servlet从理论上更说得过去,但是对于示例未必最佳,毕竟jsp只要放在web容器的某个应用下就ok;如果是servlet则需要配置;对于一本讲述概要而不是深入讨论最佳实践的书,我觉得作者的不足是没有提到其它可行方案或者解释为啥通过这个方式来示例;对于读者来说,应该产生这个疑问,并且该弄明白为啥这么干

声明:
本例子在firefox下完全正常运行;
在IE下运行到红色标记处得到的对象的个数居然是0;严重疑惑中,希望得到朋友们的指点..... 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值