You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by aw...@apache.org on 2007/05/09 06:31:33 UTC

svn commit: r536410 - in /myfaces/trinidad/trunk/trinidad: trinidad-api/src/main/java/org/apache/myfaces/trinidad/context/ trinidad-api/src/main/resources/ trinidad-api/src/test/java/org/apache/myfaces/trinidad/context/ trinidad-impl/src/main/java/org/...

Author: awiner
Date: Tue May  8 21:31:32 2007
New Revision: 536410

URL: http://svn.apache.org/viewvc?view=rev&rev=536410
Log:
ADFFACES-391: Client-side validation - enhance to match server-side
- Patch from Danny Robinson: when enabled, client-side validation will 
  not show JS alerts - instead, it'll show (and hide) error messages
  directly in the page content.
- New API: RequestContext.getClientValidation(), and enum class
  RequestContext.ClientValidation for the three supported values
- New configuration option in trinidad-config.xml: <client-validation>

Modified:
    myfaces/trinidad/trunk/trinidad/trinidad-api/src/main/java/org/apache/myfaces/trinidad/context/RequestContext.java
    myfaces/trinidad/trunk/trinidad/trinidad-api/src/main/resources/trinidad-config.xsd
    myfaces/trinidad/trunk/trinidad/trinidad-api/src/test/java/org/apache/myfaces/trinidad/context/MockRequestContext.java
    myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ConfigParser.java
    myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextBean.java
    myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextImpl.java
    myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/FormRenderer.java
    myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/LabelAndMessageRenderer.java
    myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/MessageRenderer.java
    myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/Core.js
    myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts
    myfaces/trinidad/trunk/trinidad/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/MRequestContext.java

Modified: myfaces/trinidad/trunk/trinidad/trinidad-api/src/main/java/org/apache/myfaces/trinidad/context/RequestContext.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad/trinidad-api/src/main/java/org/apache/myfaces/trinidad/context/RequestContext.java?view=diff&rev=536410&r1=536409&r2=536410
==============================================================================
--- myfaces/trinidad/trunk/trinidad/trinidad-api/src/main/java/org/apache/myfaces/trinidad/context/RequestContext.java (original)
+++ myfaces/trinidad/trunk/trinidad/trinidad-api/src/main/java/org/apache/myfaces/trinidad/context/RequestContext.java Tue May  8 21:31:32 2007
@@ -221,7 +221,7 @@
   {
     DEFAULT("default"),
     INACCESSIBLE("inaccessible"),
-    SCREEN_READER("screnReader");
+    SCREEN_READER("screenReader");
     
     Accessibility(String name)
     {
@@ -237,10 +237,36 @@
     private final String _name;
   };
 
+
+  public enum ClientValidation
+  {
+    ALERT("alert"),
+    INLINE("inline"),
+    DISABLED("disabled");
+    
+    ClientValidation(String name)
+    {
+      _name = name;
+    }
+
+    @Override
+    public String toString()
+    {
+      return _name;
+    }
+
+    private final String _name;
+  };
+
   /**
    * Returns the name of the current accessibility mode.
    */
   public abstract Accessibility getAccessibilityMode();
+
+  /**
+   * Returns the name of the current client validation mode.
+   */
+  public abstract ClientValidation getClientValidation();
 
   //
   //  General localization

Modified: myfaces/trinidad/trunk/trinidad/trinidad-api/src/main/resources/trinidad-config.xsd
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad/trinidad-api/src/main/resources/trinidad-config.xsd?view=diff&rev=536410&r1=536409&r2=536410
==============================================================================
--- myfaces/trinidad/trunk/trinidad/trinidad-api/src/main/resources/trinidad-config.xsd (original)
+++ myfaces/trinidad/trunk/trinidad/trinidad-api/src/main/resources/trinidad-config.xsd Tue May  8 21:31:32 2007
@@ -57,11 +57,20 @@
             </documentation>
           </annotation>
         </element> 
+
+        
+        <element name="client-validation" minOccurs="0" maxOccurs="1"
+                 type="config:clientValidationExpressionType">
+          <annotation>
+            <documentation>The &lt;client-validation&gt; element controls how client side validation functions - ALERT (the default) to show Javascript alerts, INLINE (using DHTML to insert messages), or DISABLED (disabling client-side validation).  The requested value may be ignored if not supported on the current platform or renderkit.
+            </documentation>
+          </annotation>
+        </element>
         
         <element name="client-validation-disabled" minOccurs="0" maxOccurs="1"
                  type="config:booleanExpressionType">
           <annotation>
-            <documentation>The &lt;client-validation-disabled&gt; element controls whether client side converters and validators are run.
+            <documentation>The &lt;client-validation-disabled&gt; element controls whether client side converters and validators are run.  (Deprecated:  use client-validation).
             </documentation>
           </annotation>
         </element>
@@ -188,6 +197,14 @@
     </restriction>
   </simpleType>
 
+  <simpleType name="clientValidationType">
+    <restriction base="string">
+      <enumeration value="ALERT"/>
+      <enumeration value="INLINE"/>
+      <enumeration value="DISABLED"/>
+    </restriction>
+  </simpleType>
+
   <simpleType name="stringExpressionType">
     <union memberTypes="string config:expressionType" />
   </simpleType>
@@ -206,6 +223,10 @@
 
   <simpleType name="accessibilityModeExpressionType">
     <union memberTypes="config:accessibilityModeType config:expressionType" />
+  </simpleType>
+
+  <simpleType name="clientValidationExpressionType">
+    <union memberTypes="config:clientValidationType config:expressionType" />
   </simpleType>
 
   <simpleType name="anyURIExpressionType">

Modified: myfaces/trinidad/trunk/trinidad/trinidad-api/src/test/java/org/apache/myfaces/trinidad/context/MockRequestContext.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad/trinidad-api/src/test/java/org/apache/myfaces/trinidad/context/MockRequestContext.java?view=diff&rev=536410&r1=536409&r2=536410
==============================================================================
--- myfaces/trinidad/trunk/trinidad/trinidad-api/src/test/java/org/apache/myfaces/trinidad/context/MockRequestContext.java (original)
+++ myfaces/trinidad/trunk/trinidad/trinidad-api/src/test/java/org/apache/myfaces/trinidad/context/MockRequestContext.java Tue May  8 21:31:32 2007
@@ -118,6 +118,12 @@
   }
 
   @Override
+  public ClientValidation getClientValidation()
+  {
+    return ClientValidation.ALERT;
+  }
+
+  @Override
   public boolean isClientValidationDisabled()
   {
     return false;

Modified: myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ConfigParser.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ConfigParser.java?view=diff&rev=536410&r1=536409&r2=536410
==============================================================================
--- myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ConfigParser.java (original)
+++ myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/config/ConfigParser.java Tue May  8 21:31:32 2007
@@ -30,6 +30,7 @@
 import javax.xml.parsers.SAXParserFactory;
 
 import org.apache.myfaces.trinidad.bean.PropertyKey;
+import org.apache.myfaces.trinidad.context.RequestContext;
 import org.apache.myfaces.trinidad.logging.TrinidadLogger;
 import org.apache.myfaces.trinidad.util.ClassLoaderUtils;
 import org.apache.myfaces.trinidad.webapp.UploadedFileProcessor;
@@ -218,14 +219,40 @@
             {
               value = LocaleUtils.getLocaleForIANAString(_currentText);
             }
+            else if (key.getType().isEnum())
+            {
+              // TODO: warn when value is not OK
+              try
+              {
+                value = Enum.valueOf((Class<? extends Enum>) key.getType(),
+                                     _currentText.trim());
+              }
+              catch (IllegalArgumentException iae)
+              {
+                _LOG.warning("INVALID_ENUM_IN_CONFIG",
+                             new Object[]{_currentText, qName});
+                return;
+              }
+            }
             else
             {
               value = _currentText;
             }
-            if (key == RequestContextBean.REMOTE_DEVICE_REPOSITORY_URI){
-                _applicationMap.put("remote-device-repository-uri",value);
+
+            if (key == RequestContextBean.REMOTE_DEVICE_REPOSITORY_URI)
+            {
+              _applicationMap.put("remote-device-repository-uri",value);
+            }
+            else if (key == RequestContextBean.CLIENT_VALIDATION_DISABLED_KEY)
+            {
+              if (Boolean.TRUE.equals(value))
+                _bean.setProperty(RequestContextBean.CLIENT_VALIDATION_KEY,
+                                  RequestContext.ClientValidation.DISABLED);
+            }
+            else
+            {
+              _bean.setProperty(key, value);
             }
-            _bean.setProperty(key, value);
           }
         }
       }

Modified: myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextBean.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextBean.java?view=diff&rev=536410&r1=536409&r2=536410
==============================================================================
--- myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextBean.java (original)
+++ myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextBean.java Tue May  8 21:31:32 2007
@@ -24,6 +24,8 @@
 import org.apache.myfaces.trinidad.bean.FacesBeanImpl;
 import org.apache.myfaces.trinidad.bean.PropertyKey;
 
+import org.apache.myfaces.trinidad.context.RequestContext;
+
 public class RequestContextBean extends FacesBeanImpl
 {
   static public Type TYPE = new Type();
@@ -33,8 +35,12 @@
                      PropertyKey.CAP_NOT_BOUND);
   static public final PropertyKey DEBUG_OUTPUT_KEY =
     TYPE.registerKey("debug-output", Boolean.class);
+  static public final PropertyKey CLIENT_VALIDATION_KEY =
+    TYPE.registerKey("client-validation", RequestContext.ClientValidation.class);
   static public final PropertyKey CLIENT_VALIDATION_DISABLED_KEY =
-    TYPE.registerKey("client-validation-disabled", Boolean.class);
+    TYPE.registerKey("client-validation-disabled",
+                     Boolean.class,
+                     PropertyKey.CAP_NOT_BOUND);
   static public final PropertyKey OUTPUT_MODE_KEY =
     TYPE.registerKey("output-mode");
   static public final PropertyKey LOOK_AND_FEEL_KEY =

Modified: myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextImpl.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextImpl.java?view=diff&rev=536410&r1=536409&r2=536410
==============================================================================
--- myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextImpl.java (original)
+++ myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/context/RequestContextImpl.java Tue May  8 21:31:32 2007
@@ -219,8 +219,7 @@
   @Override
   public boolean isClientValidationDisabled()
   {
-    return Boolean.TRUE.equals(
-       _bean.getProperty(RequestContextBean.CLIENT_VALIDATION_DISABLED_KEY));
+    return (ClientValidation.DISABLED == getClientValidation());
   }
 
   @Override
@@ -262,6 +261,18 @@
     }
 
     return _ACCESSIBILITY_NAMES.get(name);
+  }
+
+  @Override
+  public ClientValidation getClientValidation()
+  { 
+    ClientValidation clientValidation = (ClientValidation)
+      _bean.getProperty(RequestContextBean.CLIENT_VALIDATION_KEY);
+
+    if (clientValidation == null)
+      return ClientValidation.ALERT;
+
+    return clientValidation;
   }
 
   @Override

Modified: myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/FormRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/FormRenderer.java?view=diff&rev=536410&r1=536409&r2=536410
==============================================================================
--- myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/FormRenderer.java (original)
+++ myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/FormRenderer.java Tue May  8 21:31:32 2007
@@ -496,8 +496,9 @@
     //                 EDITABLEVALUEHOLDER IMMEDIATE INCORRECTLY
     boolean hasImmediateComponent = fData.hasImmediateComponent();
 
-    boolean isClientValidationDisabled =
-      RequestContext.getCurrentInstance().isClientValidationDisabled();
+    RequestContext rc = RequestContext.getCurrentInstance();
+    boolean isClientValidationDisabled = 
+      rc.getClientValidation() == RequestContext.ClientValidation.DISABLED;
 
     if (isClientValidationDisabled || hasImmediateComponent)
     {
@@ -552,24 +553,17 @@
 
 
     //
-    // write the validation function for this form
+    // Write the array of form validators
     //
-    writer.writeText("function _", null);
-    writer.writeText(jsID, null);
-
-    // get the form validators
     List<CoreFormData.ConvertValidate> validatorInfoList =
       fData.getFormValidatorsInfo(false);
-
-    if (validatorInfoList == null)
+    
+    if (validatorInfoList != null)
     {
-      // no validation, so validation always succeeds
-      writer.writeText("Validator(){return true;}", null);
-    }
-    else
-    {
-      writer.writeText("Validator(f,s){var fl = _multiValidate(f,s,[", null);
-
+      writer.writeText("var _", null);
+      writer.writeText(jsID, null);
+      writer.writeText("_Validators=[", null);
+  
       boolean firstFormInfo = true;
 
       for (int j = 0; j < validatorInfoList.size(); j++)
@@ -644,16 +638,37 @@
           }
         }
       }
+  
+      writer.writeText("]];", null);
+    }
+    //
+    // write the validation function for this form
+    //
+    writer.writeText("function _", null);
+    writer.writeText(jsID, null);
 
+    if (validatorInfoList == null)
+    {
+      // no validation, so validation always succeeds
+      writer.writeText("Validator(){return true;}", null);
+    }
+    else
+    {
+      writer.writeText("Validator(f,s){return ", null);
+      
+      if (rc.getClientValidation() == RequestContext.ClientValidation.INLINE)
+        writer.writeText("_validateInline(f,s,_", null);
+      else
+        writer.writeText("_validateAlert(f,s,_", null);
+          
+      writer.writeText(jsID, null);
+      writer.writeText("_Validators,", null);
       Integer globalFormatIndex = fData.addGlobalMessageFormat(arc);
-
-      writer.writeText("]],", null);
       writer.writeText(globalFormatIndex, null);
-      writer.writeText(");if(fl.length>0){_validationAlert('", null);
+      writer.writeText(",\"", null);
       writer.writeText(XhtmlUtils.escapeJS(
-                          arc.getTranslatedString("af_form.SUBMIT_ERRORS")),
-                       null);
-        writer.writeText("'+fl);return false;}else{return true;}}", null);
+          arc.getTranslatedString("af_form.SUBMIT_ERRORS")), null);
+      writer.writeText("\");}", null);
     }
 
     //

Modified: myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/LabelAndMessageRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/LabelAndMessageRenderer.java?view=diff&rev=536410&r1=536409&r2=536410
==============================================================================
--- myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/LabelAndMessageRenderer.java (original)
+++ myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/LabelAndMessageRenderer.java Tue May  8 21:31:32 2007
@@ -32,6 +32,7 @@
 import org.apache.myfaces.trinidad.component.html.HtmlTableLayout;
 import org.apache.myfaces.trinidad.context.FormData;
 import org.apache.myfaces.trinidad.context.RenderingContext;
+import org.apache.myfaces.trinidad.context.RequestContext;
 import org.apache.myfaces.trinidadinternal.renderkit.core.xhtml.table.TableRenderingContext;
 
 
@@ -183,13 +184,16 @@
         fd.addLabel(component.getClientId(context), value);
     }
 
+    RequestContext rc = RequestContext.getCurrentInstance();
+    boolean isInline = (rc.getClientValidation() ==
+                        RequestContext.ClientValidation.INLINE);
     if (isInTable)
     {
       ResponseWriter rw = context.getResponseWriter();
       delegateRenderer(context, arc, component, bean, _labelInTable);
       renderFieldCellContents(context, arc, component, bean);
 
-      if (hasMessage(context, arc, component, bean))
+      if (isInline || hasMessage(context, arc, component, bean))
       {
         rw.startElement("div", component);
         rw.endElement("div");
@@ -264,14 +268,14 @@
       }
       
       _renderFieldCell(context, arc, component, bean, labelExists,
-        needsPanelFormLayout);
+                       needsPanelFormLayout, isInline);
       
       if (!needsPanelFormLayout)
       {
         // End encoding of the non-panelForm-friendly wrappers:
         rw.endElement("tr");
 
-        if (hasMessage(context, arc, component, bean))
+        if (isInline || hasMessage(context, arc, component, bean))
         {
           // =-=AEW PPR PROBLEM!!!  We should always be
           // rendering the "tr", and always rendering an ID, if we ever
@@ -288,7 +292,7 @@
           
           rw.endElement("tr");
         }
-        
+
         if (needsTableTag)
           rw.endElement("table");
       }
@@ -352,7 +356,8 @@
     UIComponent         component,
     FacesBean           bean,
     boolean             labelExists,
-    boolean             needsPanelFormLayout) throws IOException
+    boolean             needsPanelFormLayout,
+    boolean             isInline) throws IOException
   {
     ResponseWriter rw = context.getResponseWriter();
     rw.startElement("td", null);
@@ -371,16 +376,19 @@
 
     // The panelForm places messages below the fields, not on a separate
     // row:
-    if (needsPanelFormLayout && hasMessage(context, arc, component, bean))
+    if (needsPanelFormLayout)
     {
       // =-= mcc PPR PROBLEM!!!  We should always be rendering the "div",
       //     and always rendering an ID, if we ever want it to be PPR
       //     replaceable:
-      rw.startElement("div", null);
-      renderStyleClass(context, arc,
-                       SkinSelectors.AF_COMPONENT_MESSAGE_CELL_STYLE_CLASS);
-      _renderMessageCellContents(context, arc, component, bean);
-      rw.endElement("div");
+      if (isInline || hasMessage(context, arc, component, bean))
+      {
+        rw.startElement("div", null);
+        renderStyleClass(context, arc,
+                         SkinSelectors.AF_COMPONENT_MESSAGE_CELL_STYLE_CLASS);
+        _renderMessageCellContents(context, arc, component, bean);
+        rw.endElement("div");
+      }
     }
 
     // bug 2484841: PDA: TOO MUCH WHITESPACE BETWEEN

Modified: myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/MessageRenderer.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/MessageRenderer.java?view=diff&rev=536410&r1=536409&r2=536410
==============================================================================
--- myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/MessageRenderer.java (original)
+++ myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/renderkit/core/xhtml/MessageRenderer.java Tue May  8 21:31:32 2007
@@ -30,6 +30,7 @@
 import org.apache.myfaces.trinidad.component.core.output.CoreMessage;
 
 import org.apache.myfaces.trinidad.context.RenderingContext;
+import org.apache.myfaces.trinidad.context.RequestContext;
 import org.apache.myfaces.trinidadinternal.util.MessageUtils;
 
 /**
@@ -161,9 +162,7 @@
     // 2. Only message exists
     // 3. Both exist and messageType not error
     else if (hasHelp || hasMessage)
-    {
-      
-
+    {  
       // if there's a help facet the styleclass should not be error
       if (hasHelp)
         styleClass = SkinSelectors.INLINE_INFO_TEXT_STYLE_CLASS;
@@ -183,7 +182,6 @@
       else
         renderStyleClass(context, arc, styleClass);
       
-
       if ( hasHelp )        
       encodeChild(context, help); 
 
@@ -198,7 +196,49 @@
         renderPossiblyFormattedText(context, message);
       }
 
-
+    }
+    
+    // Render a hidden container for client-side messages
+    RequestContext rc = RequestContext.getCurrentInstance();
+    boolean isInline = (rc.getClientValidation() ==
+                        RequestContext.ClientValidation.INLINE);
+    if (isInline)
+    {
+      String forId = getForId(context, component, bean);
+      
+      if (forId != null)
+      {
+        if (hasHelp && hasMessage)
+          writer.startElement(XhtmlConstants.DIV_ELEMENT, null);
+        else 
+        {
+          if (hasHelp || hasMessage)
+          {
+            writer.startElement("br", null);
+            writer.endElement("br");
+          }
+          else
+          {
+            // Add style to outer span
+            renderStyleClass(context, arc, SkinSelectors.INLINE_INFO_TEXT_STYLE_CLASS); 
+          }
+          
+          writer.startElement(XhtmlConstants.SPAN_ELEMENT, null);
+        }
+        
+        writer.writeAttribute(XhtmlConstants.ID_ATTRIBUTE, 
+                              forId + "::msg", null);
+        writer.writeAttribute(XhtmlConstants.STYLE_ATTRIBUTE, 
+                              "display:none;", null);
+        renderStyleClass(context, arc, 
+                         SkinSelectors.INLINE_ERROR_TEXT_STYLE_CLASS);
+        if (hasHelp && hasMessage)
+          writer.endElement(XhtmlConstants.DIV_ELEMENT);
+        else
+        {
+          writer.endElement(XhtmlConstants.SPAN_ELEMENT);
+        }
+      }
     }
 
     if (useDiv)

Modified: myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/Core.js
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/Core.js?view=diff&rev=536410&r1=536409&r2=536410
==============================================================================
--- myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/Core.js (original)
+++ myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/javascript/META-INF/adf/jsLibs/Core.js Tue May  8 21:31:32 2007
@@ -1203,15 +1203,175 @@
   }
 }
 
-function _validationAlert(errorString)
+function _validateAlert(
+  form,
+  source,
+  validators,
+  globalMessageIndex,
+  errorTitle
+  )
 {
+  var failureArray = _multiValidate(form, source,  validators, globalMessageIndex);
+  
+  if (failureArray.length == 0)
+    return;
+    
+  var firstFailure = true;
+  var failureString = errorTitle + '\n';
+
+  for (var j=0; j < failureArray.length; j = j+2)
+  {
+    var currInput = form.elements[failureArray[j]];
+    
+    if (!currInput)
+      continue;
+    
+    failureString += _getLabel(form, currInput) + ": " + failureArray[j+1] + '\n';
+
+    // Move the focus back to the first failed field
+    if (firstFailure)
+    {
+      _setFocus(currInput);
+    
+      firstFailure = false;
+    }
+  }
+
   // Show the error and note the time we finished this validation.
   // Record the validation both before and after the alert so that we
   // halt any validations caused by events triggered along with this
   // one, or by the closing of this alert.
   _recordValidation(true, 0);
-  alert(errorString);
+  alert(failureString);
+  _recordValidation(true, 0);
+  
+  return (failureArray.length == 0);
+}
+
+function _validateInline(
+  form,
+  source,
+  validators,
+  globalMessageIndex,
+  errorTitle
+  )
+{
+  var failureArray = _multiValidate(form, source,  validators, globalMessageIndex);
+  
+  var firstFailure = true;
+
+  // TODO - Check if we really need this with inline validation
+  _recordValidation(true, 0);
+
+  var failureString = "";
+  for (var i = 0; i < validators.length; i += 5)
+  {
+  
+    var currId = validators[i];
+    var foundMsg = false;
+
+    // Get the icon if any
+    var iconElem = document.getElementById(validators[i] + "::icon");
+
+    // If component hasn't got a message element, then skip
+    var msgElem = document.getElementById(validators[i] + "::msg");
+    if (!msgElem)
+      continue;
+      
+    // Clear any existing messages from the component
+    msgElem.innerHTML = "";
+    
+    // Find messages for currId
+    for (var j=0; j < failureArray.length; j = j+2)
+    {
+      if (currId != failureArray[j])
+        continue;
+        
+      var currInput = form.elements[failureArray[j]];
+      if (!currInput)
+        continue;
+
+      // Move the focus back to the first failed field
+      if (firstFailure)
+      {
+        _setFocus(currInput);
+        firstFailure = false;
+      }
+
+      msgElem.innerHTML = failureArray[j+1];
+  
+      foundMsg = true;
+      
+      failureString += currId + "=" + failureArray[j+1] + '\n';
+    }
+    
+    // Decide if we show or hide the message element
+    if (foundMsg)
+    {
+      msgElem.style.display = "inline";
+      if (iconElem)
+        iconElem.style.display = 'inline';
+    }
+    else 
+    {
+      msgElem.style.display = "none";
+      if (iconElem)
+        iconElem.style.display = 'none';
+    }
+
+  }
+
+  // TODO - Check if we really need this with inline validation
   _recordValidation(true, 0);
+
+  return (failureArray.length == 0);
+}
+
+/**
+ * Performs validation on the supplied input element.  If validation fails
+ * the appropriate message will be displayed in the message component for this
+ * input field.
+ * <p>
+ * The simplest usage of this method is from the onblur attribute of the 
+ * input component. e.g. onblur="_validateInput(this);"
+ * <p>
+ * @param input The input element to validate.
+ * @return boolean, false if validation failed, otherwise true. 
+ */
+// TODO: make this a public function only after hanging it on
+// a namespaced object, *and* making it not specific to inline
+// validation
+function _validateInput(input)
+{
+  if (input == (void 0))
+    return true;
+  
+  var form = _getForm(input);
+  if (form == (void 0))
+    return true;
+
+  var validators = _getValidators(form);
+  if (validators == (void 0))
+    return true;
+    
+  var validatorsToRun = new Array();
+
+  for (i=0; i < validators.length; i += 5)
+  {
+    // Find any entries that match this element
+    if (validators[i] == input.id)
+    {
+      validatorsToRun[validatorsToRun.length] = validators[i];
+      validatorsToRun[validatorsToRun.length] = validators[i+1];
+      validatorsToRun[validatorsToRun.length] = validators[i+2];
+      validatorsToRun[validatorsToRun.length] = validators[i+3];
+      validatorsToRun[validatorsToRun.length] = validators[i+4];
+    }
+  }
+
+  // Call inline validation using only the appropriate validators
+  var retVal = _validateInline(form, (void 0), validatorsToRun, 1, (void 0));
+  return retVal;
 }
 
 // Records the time of this validation event.
@@ -2304,6 +2464,8 @@
   globalMessageIndex
   )
 {
+  // 2d Array to hold the id and the associated error for each component
+  var failureArray = new Array();
   var failures = "";
 
   var subforms = window[form.name + "_SF"];
@@ -2343,8 +2505,6 @@
     // get the list of different validations
     var validations = _getValidations(form);
 
-    var firstFailure = true;
-
     // loop through the validations, building up the error string
     for (var i = 0; i < validators.length; i += 5)
     {
@@ -2411,14 +2571,6 @@
       if ( required && ((value == "" ) || (value == null)))
       {
 
-        // move the focus back to the first failed field
-        if (firstFailure)
-        {
-          _setFocus(currInput);
-
-          firstFailure = false;
-        }
-
         // get the formatted error string for the current input and
         // formatIndex
         requiredFormatIndex = validators[i+2];
@@ -2427,6 +2579,9 @@
 
         if (requiredErrorString)
         {
+          failureArray[failureArray.length] = currInput.id;
+          failureArray[failureArray.length] = requiredErrorString;
+
           requiredErrorString = _getGlobalErrorString(currInput, 
                                               globalMessageIndex, 
                                               requiredErrorString,
@@ -2462,20 +2617,15 @@
               catch (e)
               {
                 converterError = true; 
-                // move the focus back to the first failed field
-                if (firstFailure)
-                {
-  
-                  _setFocus(currInput);
-  
-                  firstFailure = false;
-                }
   
                 // get the formatted error string for the current input
                 var errorString1 = e.getFacesMessage().getDetail();
   
                 if (errorString1)
                 {                         
+                  failureArray[failureArray.length] = currInput.id;
+                  failureArray[failureArray.length] = errorString1;
+ 
                   errorString1 = _getGlobalErrorString(currInput, 
                                                        globalMessageIndex, 
                                                        errorString1,
@@ -2508,22 +2658,16 @@
                   validator.validate(value, label, converter);
                 }
                 catch (e)
-                {
-                  // move the focus back to the first failed field
-                  if (firstFailure)
-                  {
-  
-                    _setFocus(currInput);
-  
-                    firstFailure = false;
-                  }
-  
+                {  
                   // get the formatted error string for the current input and
                   // formatIndex
                   var errorString = e.getFacesMessage().getDetail();
   
                   if (errorString)
                   {     
+                    failureArray[failureArray.length] = currInput.id;
+                    failureArray[failureArray.length] = errorString;
+ 
                     errorString = _getGlobalErrorString(currInput, 
                                                         globalMessageIndex, 
                                                         errorString,
@@ -2540,8 +2684,8 @@
 
     _recordValidation((failures.length > 0), 0);
   }
-
-  return failures;
+  
+  return failureArray;
 }
 
 /**
@@ -2915,6 +3059,15 @@
   return window["_" + _getJavascriptId(form.name) + "_Validations"];
 }
 
+/**
+ * Returns the array of form validators.
+ */
+function _getValidators(
+  form
+  )
+{
+  return window["_" + _getJavascriptId(form.name) + "_Validators"];
+}
 
 /**
  * Perform the error validation and return true if there is an error.

Modified: myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts?view=diff&rev=536410&r1=536409&r2=536410
==============================================================================
--- myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts (original)
+++ myfaces/trinidad/trunk/trinidad/trinidad-impl/src/main/xrts/org/apache/myfaces/trinidadinternal/resource/LoggerBundle.xrts Tue May  8 21:31:32 2007
@@ -276,6 +276,9 @@
 <!-- NODESTAMP_FACET_MISSING -->
 <resource key="NODESTAMP_FACET_MISSING">'nodeStamp' facet missing!</resource>
 
+<!-- SINGLE_STEP_MUST_INSIDE_FORM -->
+<resource key="SINGLE_STEP_MUST_INSIDE_FORM">SingleSteps must be used inside of a form</resource>
+
 <!-- FRAMES_MUST_INSIDE_FRAMEBORDERLAYOUTS -->
 <resource key="FRAMES_MUST_INSIDE_FRAMEBORDERLAYOUTS">Frames must appear inside FrameBorderLayouts</resource>
 
@@ -599,5 +602,7 @@
 
 <!-- REQUIRED_TRINIDADFILTER_NOT_INSTALLED -->
 <resource key="REQUIRED_TRINIDADFILTER_NOT_INSTALLED">The TrinidadFilter has not been installed.  Apache Trinidad requires this filter for proper execution.</resource>
+
+<resource key="INVALID_ENUM_IN_CONFIG">The value ''{0}'' is not a legal value for &lt;''{1}''&gt;</resource>
 
 </resources>

Modified: myfaces/trinidad/trunk/trinidad/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/MRequestContext.java
URL: http://svn.apache.org/viewvc/myfaces/trinidad/trunk/trinidad/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/MRequestContext.java?view=diff&rev=536410&r1=536409&r2=536410
==============================================================================
--- myfaces/trinidad/trunk/trinidad/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/MRequestContext.java (original)
+++ myfaces/trinidad/trunk/trinidad/trinidad-impl/src/test/java/org/apache/myfaces/trinidadinternal/renderkit/MRequestContext.java Tue May  8 21:31:32 2007
@@ -157,6 +157,17 @@
   }
 
   @Override
+  public ClientValidation getClientValidation()
+  {
+    return _clientValidation;
+  }
+
+  public void setClientValidation(ClientValidation clientValidation)
+  {
+    _clientValidation = clientValidation;
+  }
+
+  @Override
   public boolean isRightToLeft()
   {
     return _rtl;
@@ -284,6 +295,7 @@
 
   private String _skin;
   private Accessibility _accMode;
+  private ClientValidation _clientValidation = ClientValidation.ALERT;
   private Agent _agent;
   private boolean _rtl = false;
   static private TimeZone _FIXED_TIME_ZONE =