[seam-commits] Seam SVN: r13231 - in examples/trunk/booking-simplified/src/main: webapp and 1 other directory.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Thu Jun 17 19:07:42 EDT 2010


Author: dan.j.allen
Date: 2010-06-17 19:07:42 -0400 (Thu, 17 Jun 2010)
New Revision: 13231

Modified:
   examples/trunk/booking-simplified/src/main/java/org/jboss/seam/faces/component/UIInputContainer.java
   examples/trunk/booking-simplified/src/main/webapp/register.xhtml
Log:
xval ajax


Modified: examples/trunk/booking-simplified/src/main/java/org/jboss/seam/faces/component/UIInputContainer.java
===================================================================
--- examples/trunk/booking-simplified/src/main/java/org/jboss/seam/faces/component/UIInputContainer.java	2010-06-17 23:07:20 UTC (rev 13230)
+++ examples/trunk/booking-simplified/src/main/java/org/jboss/seam/faces/component/UIInputContainer.java	2010-06-17 23:07:42 UTC (rev 13231)
@@ -24,6 +24,7 @@
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -36,7 +37,7 @@
 import javax.faces.component.NamingContainer;
 import javax.faces.component.UIComponent;
 import javax.faces.component.UIComponentBase;
-import javax.faces.component.UIInput;
+import javax.faces.component.UIForm;
 import javax.faces.component.UIMessage;
 import javax.faces.component.UINamingContainer;
 import javax.faces.component.UIViewRoot;
@@ -117,6 +118,10 @@
     */
    public static final String COMPONENT_TYPE = "org.jboss.seam.faces.InputContainer";
 
+   public static final String DYNAMIC_AJAX_BEHAVIOR = "org.jboss.seam.faces.DYNAMIC_AJAX_BEHAVIOR";
+
+   public static final String FORM_TOKEN = "@form";
+
    protected static final String HTML_ID_ATTR_NAME = "id";
    protected static final String HTML_CLASS_ATTR_NAME = "class";
    protected static final String HTML_STYLE_ATTR_NAME = "style";
@@ -267,9 +272,11 @@
       }
 
       // temporary workaround for state saving bug; remove any ClientBehaviors added dynamically
+      // this needs to be less aggressive...need to track exactly what we added
       for (EditableValueHolder i : elements.getInputs())
       {
-         if (i instanceof ClientBehaviorHolder)
+         if (i instanceof ClientBehaviorHolder &&
+            ((UIComponent) i).getAttributes().remove(DYNAMIC_AJAX_BEHAVIOR) != null)
          {
             Map<String, List<ClientBehavior>> b = ((ClientBehaviorHolder) i).getClientBehaviors();
             for (String k : b.keySet())
@@ -336,7 +343,18 @@
    {
       if (elements == null)
       {
-         elements = new InputContainerElements(getId(), getAttributes());
+         UIComponent node = getParent();
+         UIForm form = null;
+         while (node != null)
+         {
+            if (node instanceof UIForm)
+            {
+               form = (UIForm) node;
+               break;
+            }
+            node = node.getParent();
+         }
+         elements = new InputContainerElements(getId(), form != null ? ":" + form.getClientId() : null, getAttributes());
       }
 
       // NOTE we need to walk the tree ignoring rendered attribute because it's
@@ -475,6 +493,7 @@
    public class InputContainerElements
    {
       private String containerId;
+      private String formId;
       private Map<String, Object> attributes;
       private String propertyName;
       private HtmlOutputLabel label;
@@ -483,10 +502,11 @@
       private boolean validationError = false;
       private boolean requiredInput = false;
 
-      public InputContainerElements(final String containerId, final Map<String, Object> attributes)
+      public InputContainerElements(final String containerId, final String formId, final Map<String, Object> attributes)
       {
          this.containerId = containerId;
          this.attributes = attributes;
+         this.formId = formId;
       }
 
       public HtmlOutputLabel getLabel()
@@ -518,13 +538,20 @@
             if (ajaxEvent != null)
             {
                Map<String, List<ClientBehavior>> behaviors = bh.getClientBehaviors();
-               if (!behaviors.containsKey(ajaxEvent))
+               // QUESTION should we clear or honor what is present?
+               if (behaviors.containsKey(ajaxEvent))
                {
-                  AjaxBehavior ajax = new AjaxBehavior();
-                  ajax.setRender(Arrays.asList(containerId));
-                  bh.addClientBehavior(ajaxEvent.toLowerCase(), ajax);
+                  behaviors.get(ajaxEvent).clear();
                }
+               ((UIComponent) input).getAttributes().put(DYNAMIC_AJAX_BEHAVIOR, ajaxEvent);
+               AjaxBehavior ajax = new AjaxBehavior();
+               ajax.setRender(Arrays.asList(containerId));
+               bh.addClientBehavior(ajaxEvent.toLowerCase(), ajax);
             }
+            else
+            {
+               interpolateAjaxTargets(bh);
+            }
          }
          if (input.isRequired() || isRequiredByConstraint(input, validator, context))
          {
@@ -549,6 +576,35 @@
          }
       }
 
+      private void interpolateAjaxTargets(ClientBehaviorHolder bh)
+      {
+         Map<String, List<ClientBehavior>> behaviors = bh.getClientBehaviors();
+         for (List<ClientBehavior> behaviorsForEvent : behaviors.values())
+         {
+            for (ClientBehavior b : behaviorsForEvent)
+            {
+               if (b instanceof AjaxBehavior)
+               {
+                  AjaxBehavior a = (AjaxBehavior) b;
+                  Collection<String> original = a.getExecute();
+                  Collection<String> translated = new ArrayList<String>();
+                  for (String o : original)
+                  {
+                     translated.add(o.replace(FORM_TOKEN, formId));
+                  }
+                  a.setExecute(translated);
+                  original = a.getRender();
+                  translated = new ArrayList<String>();
+                  for (String o : original)
+                  {
+                     translated.add(o.replace(FORM_TOKEN, formId));
+                  }
+                  a.setRender(translated);
+               }
+            }
+         }
+      }
+
       public List<UIMessage> getMessages()
       {
          return messages;

Modified: examples/trunk/booking-simplified/src/main/webapp/register.xhtml
===================================================================
--- examples/trunk/booking-simplified/src/main/webapp/register.xhtml	2010-06-17 23:07:20 UTC (rev 13230)
+++ examples/trunk/booking-simplified/src/main/webapp/register.xhtml	2010-06-17 23:07:42 UTC (rev 13231)
@@ -30,7 +30,8 @@
 
          <h:form id="registrationForm" prependId="false">
             <fieldset>
-
+               <h:outputScript name="jsf.js" library="javax.faces" target="head"/>
+               
                <!-- manually append Ajax behavior -->
                <p:input id="username">
                   <h:inputText id="input" value="#{newUser.username}"
@@ -40,21 +41,32 @@
                </p:input>
 
                <!-- automatically append Ajax behavior -->
-               <p:input id="name" ajax="default">
+               <p:input id="name" ajax="blur">
                   <h:inputText id="input" value="#{newUser.name}"/>
                </p:input>
 
-               <p:input id="email" ajax="default">
+               <p:input id="email" ajax="blur">
                   <h:inputText id="input" value="#{newUser.email}"/>
                </p:input>
 
-               <p:input id="password" ajax="default">
+               <p:input id="password" ajax="blur">
                   <h:inputSecret id="input" value="#{newUser.password}" redisplay="true"/>
                </p:input>
 
-               <p:input id="confirmPassword" ajax="default">
-                  <h:inputSecret id="input" value="#{registrar.confirmPassword}" redisplay="true"/>
+               <p:input id="confirmPassword">
+                  <h:inputSecret id="input" value="#{registrar.confirmPassword}" redisplay="true">
+                     <f:ajax event="blur"
+                             execute="@this @form:password:input @form:passwordCheck"
+                             render="confirmPassword @form:password :messages"/>
+                  </h:inputSecret>
                </p:input>
+
+               <ui:remove><!--
+               <p:input id="confirmPassword">
+                  <h:inputSecret id="input" value="#{registrar.confirmPassword}" redisplay="true">
+                     <f:ajax event="blur" execute="@form" render="@form :messages"/>
+                  </h:inputSecret>
+               </p:input>--></ui:remove>
                
                <div class="buttonBox">
                   <h:commandButton id="register" value="Register" action="#{registrar.register}"/>
@@ -64,7 +76,7 @@
 
             </fieldset>
 
-            <s:validateForm validatorId="confirmPasswordValidator"
+            <s:validateForm id="passwordCheck" validatorId="confirmPasswordValidator"
             	fields="newPassword=password:input confirmPassword=confirmPassword:input"/>
 
          </h:form>



More information about the seam-commits mailing list