铁手剑谱

上善若水
数据加载中……
Struts秘籍之第2段:第3.8式:使用JavaScript动态改变选择项

第3.8式. 使用JavaScript动态改变选择项

问题

你希望使用JavaScript 来根据从应用模型中获得的数据来动态设置显示在一个HTML select元素中的条目。

动作要领

使用Struts logic:iterate标签来为不同的选项集创建JavaScript 数组。然后使用JavaScript 的onchange事件句柄来在运行时修改options集。Example 3-8就展示了一个完整的JSP ,在其中JavaScript 数组是使用Struts 标签动态创建的。changeOptions事件句柄函数使用JavaScript数组重设了select控件的选项.

Example 3-8. 使用Struts产生DHTML

 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>

<html>
<head>
    
<title>Apache Struts Web Framework - JavaScript Example</title>
    
<script language="JavaScript">
        
// 为第一组选项创建一个数组
        fooArray = new Array( );
        
<logic:iterate id="fooValue" indexId="ctr" 
                     name
="MyForm"  property="fooList">
            fooArray[
<bean:write name="ctr"/>= 
                
new Option("<bean:write name='fooValue'/>",
                           
"<bean:write name='fooValue'/>",
                           
falsefalse);
        
</logic:iterate>

        
// 为第二组选项创建数组
        barArray = new Array( );
        
<logic:iterate id="barValue" indexId="ctr" 
                     name
="MyForm"  property="barList">
            fooArray[
<bean:write name="ctr"/>= 
                
new Option("<bean:write name='barValue'/>",
                           
"<bean:write name='barValue'/>",
                           
falsefalse);
        
</logic:iterate>

        
function changeOptions(var control) {       
            
// control 是触发的控件
            // baz 是select 控件
            baz = document.MyForm.baz;
            baz.options.length
=0;

            
if (control.value == 'Foo') 
                bazArray 
= fooArray;
            
else
                bazArray 
= barArray;

            
for (i=0; i < bazArray.length; i++)
               baz.options[i] 
= bazArray[i];
        }

    
</script>
</head>
<body>
    
<html:form name="MyForm" action="processMyForm">
        
<html:radio property="fooBar" value="Foo" 
                     onclick
="changeOptions(this);"/> Foo<br/>
        
<html:radio property="fooBar" value="Bar" 
                     onclick
="changeOptions(this);"/> Bar<br/>
        Baz: 
<html:select property="baz">         
             
</html:select>
    
</html:form>
</body>
</html>

 

动作变化

你可以使用Struts 来产生JavaScript,就像用它生成HTML一样。某些开发人员认为JavaScript 简直是"恶魔";实际上,它只是稍微有那么一点坏而已。考虑这个编程原则:如果JavaScript 能使你的应用更好而且用户喜欢,那就用它。但是用它的原则是,仍然将你的应用逻辑保留在你的业务层,而不是放在页面中。Struts 对此有帮助。

用一个具体的例子可以说明这个原则。假定你想要一个用户选择他喜欢的编程语言,并且,据此选择他喜欢的IDE。语言可以通过使用单选按钮来选择,而IDE 将通过下拉列表来选择。如果语言是Java, 那么IDE 下拉列表将显示诸如Eclipse, Net Beans, IDEA, 等等。而如果语言是C#, 则下拉列表显示Visual Studio 和SharpDevelop。

Example 3-9 展示了持有这些数据的action form。

Example 3-9. ActionForm for favorite language/IDE

 

package com.oreilly.strutsckbk;

import org.apache.struts.action.ActionForm;

public final class MyForm extends ActionForm  {
    
    
private static String[] javaIdes = 
        
new String[] {"Eclipse""IDEA""JBuilder"
                       
"JDeveloper""NetBeans"}
;
    
private static String[] csharpIdes = 
        
new String[] {"SharpDevelop""Visual Studio"};
    
    
public String[] getJavaIdes( ) {return javaIdes;}
    
public String[] getCsharpIdes( ) {return csharpIdes;}
    
    
public String getLanguage( ) {
        
return language;
    }

    
    
public void setLanguage(String language) {
        
this.language = language;
    }


    
public String getIde( ) {
        
return ide;
    }

    
public void setIde(String ide) {
        
this.ide = ide;
    }

    
private String language;
    
private String ide;
}

 

Example 3-10 则列出了渲染输入页面的JSP (favorite_language.jsp) 。这个例子和基本动作中的例子有些相似。

Example 3-10. JSP Page using Apache Struts Web Framework-rendered DTHML

 

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<html>
<head>
  
<title>Apache Struts Web Framework - JavaScript Example</title>
  
<script language="JavaScript">
     
// 为第一组选项创建数组
     javaIdesArray = new Array( );
     
<logic:iterate id="ide" indexId="ctr" 
                  name
="MyForm"  property="javaIdes">
          javaIdesArray[
<bean:write name="ctr"/>= 
             
new Option("<bean:write name='ide'/>",
                        
"<bean:write name='ide'/>",
                        
falsefalse);
     
</logic:iterate>

     
// 为第二组选项创建数组
     csharpIdesArray = new Array( );
     
<logic:iterate id="ide" indexId="ctr" 
                  name
="MyForm"  property="csharpIdes">
          csharpIdesArray[
<bean:write name="ctr"/>= 
             
new Option("<bean:write name='ide'/>",
                        
"<bean:write name='ide'/>",
                        
falsefalse);
     
</logic:iterate>

     
function changeOptions(control) {       
       ideControl 
= document.MyForm.ide;
       ideControl.options.length
=0;

       
if (control.value == 'Java') 
         ideArray 
= javaIdesArray;
       
else
         ideArray 
= csharpIdesArray;

       
for (i=0; i < ideArray.length; i++)
           ideControl.options[i] 
= ideArray[i];
     }

  
</script>
</head>
<body>
  
<html:form action="/admin/ViewFavoriteLanguage">
      What's your favorite programming language?
<br/>
      
<html:radio property="language" value="Java" 
                   onclick
="changeOptions(this);"/> Java<br/>
      
<html:radio property="language" value="C-Sharp" 
                   onclick
="changeOptions(this);"/> C-Sharp<br/>
      
<p>What's your favorite development tool?<br/>
      IDE: 
<html:select property="ide"/>
      
</p>
      
<html:submit/>
  
</html:form>
</body>
</html>

 

茜套在head元素中的script块包含了JavaScript。logic:iterate标签遍历JavaBean 属性以创建两个JavaScript 数组:一个针对IDE,另一个针对C# IDE。每一个数组都包含一组Option的JavaScript 对象。一个Option对象表示HTML select控件中的一个选项。这些对象在其构造器重使用了四个参数:用来现实的text 值,表单提交时传递的值,指示该值是否是默认值的一个Boolean值,以及指示其是否是当前选择的Boolean值。

用于修改选项的JavaScript 函数紧跟logic:iterate循环。这个函数是个纯粹的静态JavaScript。触发修改的单选按钮是作为参数传递给这个函数的。如果单选按钮的当前值是那么e select控件则根据表达Java IDE的Option对象组装。否则,控件使用表达C# IDE的Option对象组装。

HTML body 则包含表单,使用Struts html标签来渲染。Struts 标签通过on函数属性来支持JavaScript 的改变监听器。对 radio 按钮来说,onclick监听器可正常工作。传递给这个函数的唯一参数是对HTML radio button的引用。当页面被第一次渲染时,看起来应该是这样:

Figure 3-1. Form using DHTML and Apache Struts Web Framework

clip_image001_0015.gif

 

一旦你点击一个单选按钮,下拉列表中的选项便会根据来自form bean中的数据动态组装。下图显示了点击Java radio button的显示结果:

Figure 3-2. Dynamically rendered drop-down menu

clip_image002_0003.gif

 

类似的,如果你点击C-Sharp radio button,下来列表中的选项也会变化以反映对应的JavaScript 数组中的值。

JSTL 其实也可以用于上述地方代替Struts bean和logic标签。比如,使用JSTL c:forEach和c:out来代替logic:iterate和bean:write。这些标签可以产生相同的效果。

 

javaIdesArray = new Array(  );
<c:forEach var="ide" varStatus="status" 
         items
="${MyForm.javaIdes}">
   javaIdesArray[
<c:out value="${status.index}"/>= 
   
new Option("<c:out value='${ide}'/>",
              
"<c:out value='${ide}'/>",
              
falsefalse);
</c:forEach>

 

JavaScript 变成可能非常令人受挫,特别是那些熟悉强类型和编译时检查的开发人员。但是使用这种客户端动态交互,确实可以改善用户体验特征。

所以, AXAJ如今正在热门,并结合到很多传统技术之上。

相关动作

如果需要业务逻辑来决定动态数据,可参考下一个动作的方法,兴许更好些。

 

posted on 2005-06-08 12:34 铁手 阅读(5865) 评论(4)  编辑  收藏 所属分类: JavaStruts系列

评论

# re: Struts秘籍之第2段:第3.8式:使用JavaScript动态改变选择项 2005-07-20 14:37 小小鸟

<html:form action="/admin/ViewFavoriteLanguage">
铁手兄,找不到上面这个动作啊..
  回复  更多评论    

# re: Struts秘籍之第2段:第3.8式:使用JavaScript动态改变选择项 2005-07-20 15:52 铁手

这部分内容编译自oreiley的Struts cook book,你可以到它的网站去下载源代码。
本系列改编来源自多个各种struts相关的书籍。
  回复  更多评论    

# re: Struts秘籍之第2段:第3.8式:使用JavaScript动态改变选择项 2005-07-28 18:44 CALM

这个Struts秘籍系列是您改编的么?我觉得很好呀,现在1.2版本的入门的文章太少了,希望能继续写下去。
  回复  更多评论    

# Struts 秘籍(CookBook)[TrackBack] 2005-11-12 18:29 阿泠

本系列源改编自O'Reily的Strus Cookbook
[引用提示]阿泠引用了该文章, 地址: http://blog.donews.com/inclear/archive/2005/11/12/624363.aspx
  回复  更多评论    

只有注册用户登录后才能发表评论。


网站导航: