You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@struts.apache.org by dg...@apache.org on 2006/01/11 02:31:45 UTC

svn commit: r367868 - in /struts/shale/trunk/use-cases/src: java/org/apache/shale/usecases/ajax/ java/org/apache/shale/usecases/remoting/ java/org/apache/shale/usecases/view/ web/ web/WEB-INF/ web/ajax/

Author: dgeary
Date: Tue Jan 10 17:31:31 2006
New Revision: 367868

URL: http://svn.apache.org/viewcvs?rev=367868&view=rev
Log:
Added an Ajax example to the usecases application. The example uses Shale's newly refactored remoting capabilities to complete a form: when you select a zip code from a pull-down menu, city and state fields in the form are populated with values that match the zip code.

Added:
    struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/ajax/Address.java
    struts/shale/trunk/use-cases/src/web/ajax/zipCode.jsp
Modified:
    struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/remoting/Business.java
    struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Bundle.properties
    struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Domains.java
    struts/shale/trunk/use-cases/src/web/WEB-INF/faces-config.xml
    struts/shale/trunk/use-cases/src/web/usecases.jsp

Added: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/ajax/Address.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/ajax/Address.java?rev=367868&view=auto
==============================================================================
--- struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/ajax/Address.java (added)
+++ struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/ajax/Address.java Tue Jan 10 17:31:31 2006
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2004-2005 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shale.usecases.ajax;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * <p>Simple address bean with street, city, state, and zipCode properties.</p>
+ *
+ * $Id$
+ */
+public class Address {
+    // -------------------------------------------------------- Static Variables
+
+
+    /**
+     * <p>The <code>Log</code> instance for this class.</p>
+     */
+    private static final Log log = LogFactory.getLog(Address.class);
+
+
+    // -------------------------------------------------------------- Properties
+
+    /**
+     * <p>The street.</p>
+     */
+    private String street = null;
+
+
+    /**
+     * <p>Return the street.</p>
+     */
+    public String getStreet() {
+
+        return this.street;
+
+    }
+
+
+    /**
+     * <p>Set the street.</p>
+     *
+     * @param street The new street street
+     */
+    public void setStreet(String street) {
+
+        this.street = street;
+
+    }
+
+
+    /**
+     * <p>The city.</p>
+     */
+    private String city = null;
+
+
+    /**
+     * <p>Return the city.</p>
+     */
+    public String getCity() {
+
+        return this.city;
+
+    }
+
+
+    /**
+     * <p>Set the city.</p>
+     *
+     * @param city The new city city
+     */
+    public void setCity(String city) {
+
+        this.city = city;
+
+    }
+
+
+    /**
+     * <p>The state.</p>
+     */
+    private String state = null;
+
+
+    /**
+     * <p>Return the state.</p>
+     */
+    public String getState() {
+
+        return this.state;
+
+    }
+
+
+    /**
+     * <p>Set the state.</p>
+     *
+     * @param state The new state state
+     */
+    public void setState(String state) {
+
+        this.state = state;
+
+    }
+
+    /**
+     * <p>The zipCode.</p>
+     */
+    private String zipCode = null;
+
+
+    /**
+     * <p>Return the zipCode.</p>
+     */
+    public String getZipCode() {
+
+        return this.zipCode;
+
+    }
+
+
+    /**
+     * <p>Set the zipCode.</p>
+     *
+     * @param zipCode The new zipCode zipCode
+     */
+    public void setZipCode(String zipCode) {
+
+        this.zipCode = zipCode;
+
+    }
+
+}

Modified: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/remoting/Business.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/remoting/Business.java?rev=367868&r1=367867&r2=367868&view=diff
==============================================================================
--- struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/remoting/Business.java (original)
+++ struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/remoting/Business.java Tue Jan 10 17:31:31 2006
@@ -17,6 +17,8 @@
 package org.apache.shale.usecases.remoting;
 
 import java.io.IOException;
+import java.util.Map;
+
 import javax.faces.context.FacesContext;
 import javax.faces.context.ResponseWriter;
 import javax.faces.model.SelectItem;
@@ -32,9 +34,33 @@
  */
 public class Business extends AbstractFacesBean {
 
-
     // ---------------------------------------------------------- Public Methods
 
+   /**
+    * <p>Generate an XML response from an array of JSF SelectItems. Those
+    *    items represent a city/state pair that matches a zip code. The
+    *    zip code is stored in the <i>zip</i> request parameter. That
+    *    parameter was put in request scope by an Ajax call--see zipCode.jsp
+    *    for more details. When the XML response is complete, the 
+    *    <code>protected</code> method <code>selectItems</code> invokes
+    *    <code>responeComplete()</code> on the Faces context, which ends
+    *    the response.</p>
+    */
+   public void cityAndStateForZip() throws IOException {
+
+       FacesContext context = FacesContext.getCurrentInstance();
+       Map requestParams = context.getExternalContext()
+                                  .getRequestParameterMap();
+       String zip = (String)requestParams.get("zip");
+       Domains domains = (Domains) getBean("domains");
+
+       if (zip != null) {
+         selectItems(context, domains.getCityAndStateItems(zip));
+       }
+       else
+         selectItems(context, domains.getBlankCityAndStateItems());
+
+   }
 
     /**
      * <p>Return the set of reported categories.</p>

Modified: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Bundle.properties
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Bundle.properties?rev=367868&r1=367867&r2=367868&view=diff
==============================================================================
--- struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Bundle.properties (original)
+++ struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Bundle.properties Tue Jan 10 17:31:31 2006
@@ -27,6 +27,14 @@
 ajax.completion.finish=Finish
 ajax.completion.submit=Submit
 
+# Ajax Zip Code Example
+ajax.zip.zipWindowTitle=Ajax with Shale Remoting
+usecases.ajaxZip=Form completion
+ajax.zip.streetPrompt=Street
+ajax.zip.cityPrompt=City
+ajax.zip.statePrompt=State
+ajax.zip.zipPrompt=Zip
+
 # JNDI Test Labels
 jndi.test.title=JNDI Test Title
 jndi.test.expected=Expected:
@@ -106,7 +114,7 @@
 
 # Use Cases Menu Messages
 usecases.categories=List Categories (Remoting)
-usecases.ajax=Ajax Interactions
+usecases.ajax=Ajax Examples
 usecases.completion=Code Completion (Standard JSF Components)
 usecases.edit=Edit User Profile
 usecases.java=Old-Style Remoting Support (Java Based)

Modified: struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Domains.java
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Domains.java?rev=367868&r1=367867&r2=367868&view=diff
==============================================================================
--- struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Domains.java (original)
+++ struts/shale/trunk/use-cases/src/java/org/apache/shale/usecases/view/Domains.java Tue Jan 10 17:31:31 2006
@@ -39,17 +39,58 @@
  * $Id$
  */
 public class Domains {
-    
 
-    // -------------------------------------------------------- Static Variables
+   // -------------------------------------------------------- Constants
+
+     /**
+      * <p>Select items for the zip code pull-down menu</p>
+      */
+    private static final SelectItem[] zipCodeItems = {
+      new SelectItem("pick one"), // TODO: localize
+      new SelectItem("14214"),
+      new SelectItem("80632"),
+      new SelectItem("97402"),     
+    };
+
+    /**
+     * <p>Select items representing legal zip codes</p>
+     */
+    private static final SelectItem[] legalZipCodeItems = {
+       // zipCodeItems[0] is not a legal zip code
+       zipCodeItems[1], // Buffalo
+       zipCodeItems[2], // Greeley
+       zipCodeItems[3]  // Euguene
+    };
+
+    /**
+     * <p>Select items representing City/State pairs corresponding,
+     *    in order, to the items in <code>zipCodeItems</code></p>
+     */
+    private static final SelectItem[][] cityAndStateItems = {
+       { new SelectItem("Buffalo"),  new SelectItem("New York") },
+       { new SelectItem("Greeley"),  new SelectItem("Colorado") },
+       { new SelectItem("Eugene"),   new SelectItem("Oregon")   }
+    }; 
+
+   /**
+    * <p>Select items for a blank city and state. This array is
+    *    used if the user selects an item that's not in the
+    *    <code>legalZipCodeItems</code> array.</p>
+    */
+    private static final SelectItem[] blankCityAndStateItems = { 
+       new SelectItem(""),
+       new SelectItem("")
+    };
 
 
+   // -------------------------------------------------------- Static Variables
+
     /**
      * <p>Localized messages for this class.</p>
      */
     private static Messages messages =
-      new Messages("org.apache.shale.usecases.view.Bundle");
-
+     new Messages("org.apache.shale.usecases.view.Bundle");
+      
 
     // ------------------------------------------------------ Instance Variables
 
@@ -160,7 +201,7 @@
                 stateNames[i] = states[i].getLabel();
             }
             Arrays.sort(stateNames);
-	}
+   }
         return stateNames;
 
     }
@@ -274,5 +315,41 @@
 
 
     }
+
+   /**
+    * <p>Return an array of selection items representing the zip codes
+    * shown in the drop-down menu in <code>zipCode.jsp</code>.</p>
+    *
+    * @param locale <code>Locale</code> used to localize the labels
+    */
+   public SelectItem[] getZipCodeItems() {
+      return zipCodeItems;
+   }
+
+   /**
+    * <p>Return an array of selection items representing the city/state
+    *    pair, given a zip code.</p>
+    *
+    * @param zip <code>String</code> the zip code
+    */
+   public SelectItem[] getCityAndStateItems(String zip) {
+      for(int i=0; i < Domains.legalZipCodeItems.length; ++i) {
+         if(Domains.legalZipCodeItems[i].getLabel().equals(zip))
+            return Domains.cityAndStateItems[i];
+      }
+      return Domains.blankCityAndStateItems;
+   }
+
+   
+   /**
+    * <p>Return an array of selection items, two to be exact, both
+    *    of which have empty strings for labels. Those items are
+    *    used when an illegal value is entered for a zip code.</p>
+    *
+    * @param locale <code>Locale</code> used to localize the labels
+    */
+   public SelectItem[] getBlankCityAndStateItems() {
+      return blankCityAndStateItems;
+   }
 
 }

Modified: struts/shale/trunk/use-cases/src/web/WEB-INF/faces-config.xml
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/WEB-INF/faces-config.xml?rev=367868&r1=367867&r2=367868&view=diff
==============================================================================
--- struts/shale/trunk/use-cases/src/web/WEB-INF/faces-config.xml (original)
+++ struts/shale/trunk/use-cases/src/web/WEB-INF/faces-config.xml Tue Jan 10 17:31:31 2006
@@ -96,6 +96,10 @@
       <from-outcome>ajax$completion</from-outcome>
       <to-view-id>/ajax/completion.jsp</to-view-id>
     </navigation-case>
+    <navigation-case>
+      <from-outcome>ajax$zip</from-outcome>
+      <to-view-id>/ajax/zipCode.jsp</to-view-id>
+    </navigation-case>
   </navigation-rule>
   <navigation-rule>
     <from-view-id>/ajax/completion.jsp</from-view-id>

Added: struts/shale/trunk/use-cases/src/web/ajax/zipCode.jsp
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/ajax/zipCode.jsp?rev=367868&view=auto
==============================================================================
--- struts/shale/trunk/use-cases/src/web/ajax/zipCode.jsp (added)
+++ struts/shale/trunk/use-cases/src/web/ajax/zipCode.jsp Tue Jan 10 17:31:31 2006
@@ -0,0 +1,142 @@
+<%@page contentType="text/html;charset=UTF-8"%>
+<%@ taglib prefix="f" uri="http://java.sun.com/jsf/core" %>
+<%@ taglib prefix="h" uri="http://java.sun.com/jsf/html" %>
+<%@ taglib prefix="s" uri="http://struts.apache.org/shale/core" %>
+
+<%--
+
+ Copyright 2004-2005 The Apache Software Foundation.  
+ 
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+ 
+      http://www.apache.org/licenses/LICENSE-2.0
+ 
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+--%>
+
+<f:view>
+   <%@include file="../messages.jspf"%>
+   <html>
+      <head>
+         <script type="text/javascript" language="Javascript1.1">
+            <!--
+            var req; // XMLHttpRequest
+
+            // zipChanged(zip) is called when a selection is made 
+            // from the zip code menu.
+
+            function zipChanged(zip) {
+               sendRequest("http://localhost:8080/struts-shale-usecases/" +
+                           "dynamic/remoting$business/cityAndStateForZip.faces" +
+                           "?zip=" + escape(zip), 
+                            processZipCodeSelection);
+            }
+
+            // Convenience methods for sending an Ajax request
+
+            function sendRequest(url, handler) {
+               initXHR();
+               req.onreadystatechange = handler;
+               req.open("GET", url, true);
+               req.send(null);
+            }
+
+            function initXHR() {
+               if(window.XMLHttpRequest) {
+                  req = new XMLHttpRequest();
+               }
+               else if(window.ActiveXObject) {
+                  req = new ActiveXObject("Microsoft.XMLHTTP");
+               }
+            }
+
+            // Callback that handles the request after it has been processed
+            // This callback is set in the sendRequest function
+
+            function processZipCodeSelection() {
+               if(req.readyState == 4) {
+                  if(req.status == 200) {
+                     var msg = req.responseText;
+                     var cityStartIndex = msg.indexOf("<value>");
+                     var cityEndIndex = msg.indexOf("</value>");
+                     var city;
+                     var state;
+
+                     if(cityStartIndex != -1 && cityEndIndex != -1) {
+                        cityStartIndex += "<value>".length;
+                        city = msg.substring(cityStartIndex, cityEndIndex);
+                        var therest = msg.substring(cityEndIndex + "</value>".length);
+
+                        var stateStartIndex = therest.indexOf("<value>");
+                        if(stateStartIndex != -1) {
+                           stateStartIndex += "<value>".length;
+                           var stateEndIndex = therest.indexOf("</value>");
+                           if(stateEndIndex != -1) {
+                             var cityElement = window.document
+                                                     .getElementById("ajaxZipForm:city");
+                             var stateElement = window.document
+                                                      .getElementById("ajaxZipForm:state");
+                             cityElement.value = city;
+                             stateElement.value = therest.substring(stateStartIndex, 
+                                                                    stateEndIndex);
+                           }   
+                        }
+                     }
+                  }
+               }
+            }
+         -->
+         </script>
+         <title>
+            <h:outputText value="#{messages['ajax.zip.zipWindowTitle']}"/>
+         </title>
+      </head>
+
+      <body>
+         <h:form id="ajaxZipForm">
+            <h:panelGrid          columns="2">
+               <%-- ZIP --%>
+               <h:outputLabel         for="zip" 
+                                    value="#{messages['ajax.zip.zipPrompt']}"/>
+               <h:panelGroup>
+                  <h:selectOneMenu     id="zip" 
+                                    value="#{ajax$address.zipCode}"
+                                 onchange="zipChanged(this.value);">
+                     <f:selectItems value="#{domains.zipCodeItems}"/>
+                  </h:selectOneMenu>
+               </h:panelGroup>
+
+               <%-- CITY --%>
+               <h:outputLabel         for="city" 
+                                    value="#{messages['ajax.zip.cityPrompt']}"/>
+               <h:panelGroup>
+                  <h:inputText         id="city"
+                                    value="#{ajax$address.city}"
+                               styleClass="input"/>
+               </h:panelGroup>
+
+               <%-- STATE --%>
+               <h:outputLabel        for="state" 
+                                   value="#{messages['ajax.zip.statePrompt']}"/>
+               <h:panelGroup>
+                  <h:inputText        id="state"
+                                   value="#{ajax$address.state}"
+                              styleClass="input"/>
+               </h:panelGroup>
+            </h:panelGrid>
+            <p>
+               <h:commandLink  immediate="true"  
+                                   value="Use cases top-level menu"
+                                  action="usecases$toplevel"/>
+            </p>
+         </h:form>
+      </body>
+   </html>
+</f:view>

Modified: struts/shale/trunk/use-cases/src/web/usecases.jsp
URL: http://svn.apache.org/viewcvs/struts/shale/trunk/use-cases/src/web/usecases.jsp?rev=367868&r1=367867&r2=367868&view=diff
==============================================================================
--- struts/shale/trunk/use-cases/src/web/usecases.jsp (original)
+++ struts/shale/trunk/use-cases/src/web/usecases.jsp Tue Jan 10 17:31:31 2006
@@ -109,6 +109,15 @@
 
   </h:panelGrid>
 
+  <h1><h:outputText      value="#{messages['usecases.ajax']}"/></h1>
+
+  <h:panelGrid        columns="1">
+    <h:commandLink         id="ajaxZip"
+                       action="ajax$zip">
+      <h:outputText value="#{messages['usecases.ajaxZip']}"/>
+    </h:commandLink>
+  </h:panelGrid>
+
   <h1><h:outputText      value="#{messages['usecases.remoting']}"/></h1>
 
   <h:panelGrid        columns="1">



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@struts.apache.org
For additional commands, e-mail: dev-help@struts.apache.org