You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by jk...@apache.org on 2006/07/02 00:20:29 UTC

svn commit: r418513 - in /tapestry/tapestry4/trunk: examples/TimeTracker/src/context/ examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/ framework/src/java/org/apache/tapestry/form/ framework/src/java/org/apache/tapestry/form/validator...

Author: jkuhnert
Date: Sat Jul  1 15:20:28 2006
New Revision: 418513

URL: http://svn.apache.org/viewvc?rev=418513&view=rev
Log:
Added much improved client side date validation 

Added:
    tapestry/tapestry4/trunk/framework/src/js/tapestry/form/datetime.js   (with props)
    tapestry/tapestry4/trunk/framework/src/js/tests/form/
    tapestry/tapestry4/trunk/framework/src/js/tests/form/test_datetime.js   (with props)
    tapestry/tapestry4/trunk/framework/src/js/tests/widget/test_TimePickerDate.js
      - copied unchanged from r418490, tapestry/tapestry4/trunk/framework/src/js/tests/widget/test_datetime.js
Removed:
    tapestry/tapestry4/trunk/framework/src/js/tests/widget/test_datetime.js
Modified:
    tapestry/tapestry4/trunk/examples/TimeTracker/src/context/Home.html
    tapestry/tapestry4/trunk/examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/TaskEntryPage.java
    tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/FormComponentContributorContext.java
    tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/FormComponentContributorContextImpl.java
    tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/validator/Email.java
    tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/validator/Max.java
    tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/validator/MaxDate.java
    tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/json/JSONObject.java
    tapestry/tapestry4/trunk/framework/src/js/tapestry/__package__.js
    tapestry/tapestry4/trunk/framework/src/js/tapestry/form.js
    tapestry/tapestry4/trunk/framework/src/js/tapestry/form/__package__.js
    tapestry/tapestry4/trunk/framework/src/js/tapestry/form/validation.js
    tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/form/validator/TestEmail.java
    tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/form/validator/TestMax.java
    tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/form/validator/TestMaxDate.java

Modified: tapestry/tapestry4/trunk/examples/TimeTracker/src/context/Home.html
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/examples/TimeTracker/src/context/Home.html?rev=418513&r1=418512&r2=418513&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/examples/TimeTracker/src/context/Home.html (original)
+++ tapestry/tapestry4/trunk/examples/TimeTracker/src/context/Home.html Sat Jul  1 15:20:28 2006
@@ -46,6 +46,18 @@
       	<input jwcid="@Submit" value="message:button.add" class="submitButton" action="listener:addTask" />
       </td>
     </tr>
+    
+    <!--
+    <tr>
+    	<td>
+    		<div class="field required">
+    			<input jwcid="emailInput@TextField" value="ognl:email" 
+    					validators="validators:email,required" />
+    		</div>
+    	</td>
+    </tr>
+    -->
+    
     </table>
     </fieldset>
 </form>

Modified: tapestry/tapestry4/trunk/examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/TaskEntryPage.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/TaskEntryPage.java?rev=418513&r1=418512&r2=418513&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/TaskEntryPage.java (original)
+++ tapestry/tapestry4/trunk/examples/TimeTracker/src/java/org/apache/tapestry/timetracker/page/TaskEntryPage.java Sat Jul  1 15:20:28 2006
@@ -59,7 +59,9 @@
     public abstract Project getCurrentProject();
     
     @Component(type = "DropdownDatePicker", id = "datePicker",
-            bindings = {"value=date", "displayName=message:task.start.date"})
+            bindings = {"value=date", 
+            "displayName=message:task.start.date", 
+            "validators=validators:required,maxDate=05/29/2006"})
     public abstract DropdownDatePicker getDatePicker();
     public abstract Date getDate();
     
@@ -84,6 +86,8 @@
     
     @InjectObject("service:timetracker.dao.TaskDao")
     public abstract TaskDao getTaskDao();
+    
+    public abstract String getEmail();
     
     /**
      * Selection model for projects.

Modified: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/FormComponentContributorContext.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/FormComponentContributorContext.java?rev=418513&r1=418512&r2=418513&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/FormComponentContributorContext.java (original)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/FormComponentContributorContext.java Sat Jul  1 15:20:28 2006
@@ -14,6 +14,7 @@
 
 package org.apache.tapestry.form;
 
+import org.apache.tapestry.IComponent;
 import org.apache.tapestry.json.JSONObject;
 
 /**
@@ -45,7 +46,16 @@
      */
 
     void addSubmitHandler(String handler);
-
+    
+    /**
+     * Adds initialization javascript code that will be executed on page/content/etc load.
+     * @param target 
+     *          The component the script is being added for.
+     * @param script
+     *          The javascript code to execute.
+     */
+    void addInitializationScript(IComponent target, String script);
+    
     /**
      * Registers a field for automatic focus. The goal is for the first field that is in error to
      * get focus; failing that, the first required field; failing that, any field.

Modified: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/FormComponentContributorContextImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/FormComponentContributorContextImpl.java?rev=418513&r1=418512&r2=418513&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/FormComponentContributorContextImpl.java (original)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/FormComponentContributorContextImpl.java Sat Jul  1 15:20:28 2006
@@ -19,6 +19,7 @@
 import org.apache.hivemind.ClassResolver;
 import org.apache.hivemind.Resource;
 import org.apache.hivemind.util.ClasspathResource;
+import org.apache.tapestry.IComponent;
 import org.apache.tapestry.IForm;
 import org.apache.tapestry.IRequestCycle;
 import org.apache.tapestry.PageRenderSupport;
@@ -85,7 +86,12 @@
         _pageRenderSupport.addInitializationScript("Tapestry.onsubmit('" + _formId + "', "
                 + submitListener + ");");
     }
-
+    
+    public void addInitializationScript(IComponent target, String script)
+    {
+        _pageRenderSupport.addInitializationScript(target, script);
+    }
+    
     public void registerForFocus(int priority)
     {
         _form.registerForFocus(_field, priority);

Modified: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/validator/Email.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/validator/Email.java?rev=418513&r1=418512&r2=418513&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/validator/Email.java (original)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/validator/Email.java Sat Jul  1 15:20:28 2006
@@ -37,16 +37,16 @@
 public class Email extends BaseValidator
 {
     static final String PATTERN = "^\\w[-._\\w]*\\w@\\w[-._\\w]*\\w\\.\\w{2,6}$";
-
+    
     // TODO: Possible thread safety issue if the validator
     // is shared across threads, because the matcher
     // will be too.
     private RegexpMatcher _matcher = new RegexpMatcher();
-
+    
     public Email()
     {
     }
-
+    
     public Email(String initializer)
     {
         super(initializer);
@@ -74,6 +74,7 @@
     public void renderContribution(IMarkupWriter writer, IRequestCycle cycle,
             FormComponentContributorContext context, IFormComponent field)
     {
+        context.addInitializationScript(field, "dojo.require(\"dojo.validate.web\");");
         
         JSONObject profile = context.getProfile();
         

Modified: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/validator/Max.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/validator/Max.java?rev=418513&r1=418512&r2=418513&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/validator/Max.java (original)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/validator/Max.java Sat Jul  1 15:20:28 2006
@@ -14,12 +14,16 @@
 
 package org.apache.tapestry.form.validator;
 
+import java.text.DecimalFormatSymbols;
+
 import org.apache.tapestry.IMarkupWriter;
 import org.apache.tapestry.IRequestCycle;
-import org.apache.tapestry.TapestryUtils;
 import org.apache.tapestry.form.FormComponentContributorContext;
 import org.apache.tapestry.form.IFormComponent;
 import org.apache.tapestry.form.ValidationMessages;
+import org.apache.tapestry.json.JSONLiteral;
+import org.apache.tapestry.json.JSONObject;
+import org.apache.tapestry.valid.ValidationConstants;
 import org.apache.tapestry.valid.ValidationConstraint;
 import org.apache.tapestry.valid.ValidationStrings;
 import org.apache.tapestry.valid.ValidatorException;
@@ -69,19 +73,24 @@
     public void renderContribution(IMarkupWriter writer, IRequestCycle cycle,
             FormComponentContributorContext context, IFormComponent field)
     {
-        context.includeClasspathScript("/org/apache/tapestry/form/validator/NumberValidator.js");
-
-        String message = TapestryUtils.enquote(buildMessage(context, field));
-
-        StringBuffer buffer = new StringBuffer("function(event) { Tapestry.validate_max_number(event, '");
-        buffer.append(field.getClientId());
-        buffer.append("', ");
-        buffer.append(_max);
-        buffer.append(", ");
-        buffer.append(message);
-        buffer.append("); }");
-
-        context.addSubmitHandler(buffer.toString());
+        JSONObject profile = context.getProfile();
+        
+        if (!profile.has(ValidationConstants.CONSTRAINTS)) {
+            profile.put(ValidationConstants.CONSTRAINTS, new JSONObject());
+        }
+        JSONObject cons = profile.getJSONObject(ValidationConstants.CONSTRAINTS);
+        
+        // TODO: Should find some way to provide this globally and cache.
+        DecimalFormatSymbols symbols = new DecimalFormatSymbols(context.getLocale());
+        
+        cons.put(field.getClientId(), 
+                new JSONLiteral("[dojo.validate.isInRange,{"
+                        + "max:" + _max + ","
+                        + "decimal:" + JSONObject.quote(symbols.getDecimalSeparator())
+                        + "]"));
+        
+        setProfileProperty(field, profile, 
+                ValidationConstants.CONSTRAINTS, buildMessage(context, field));
     }
 
     public void setMax(double max)

Modified: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/validator/MaxDate.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/validator/MaxDate.java?rev=418513&r1=418512&r2=418513&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/validator/MaxDate.java (original)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/form/validator/MaxDate.java Sat Jul  1 15:20:28 2006
@@ -16,8 +16,18 @@
 
 import java.util.Date;
 
+import org.apache.tapestry.IMarkupWriter;
+import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.form.FormComponentContributorContext;
 import org.apache.tapestry.form.IFormComponent;
+import org.apache.tapestry.form.TranslatedField;
 import org.apache.tapestry.form.ValidationMessages;
+import org.apache.tapestry.form.translator.DateTranslator;
+import org.apache.tapestry.form.translator.Translator;
+import org.apache.tapestry.json.JSONLiteral;
+import org.apache.tapestry.json.JSONObject;
+import org.apache.tapestry.util.Strftime;
+import org.apache.tapestry.valid.ValidationConstants;
 import org.apache.tapestry.valid.ValidationConstraint;
 import org.apache.tapestry.valid.ValidationStrings;
 import org.apache.tapestry.valid.ValidatorException;
@@ -45,22 +55,77 @@
             throws ValidatorException
     {
         Date date = (Date) object;
-
+        DateTranslator translator = getFieldTranslator(field);
+        
         if (date.after(_maxDate))
-            throw new ValidatorException(buildMessage(messages, field),
+            throw new ValidatorException(buildMessage(messages, field, translator),
                     ValidationConstraint.TOO_LARGE);
-
+        
     }
-
-    private String buildMessage(ValidationMessages messages, IFormComponent field)
+    
+    private String buildMessage(ValidationMessages messages, IFormComponent field, 
+            DateTranslator translator)
     {
         return messages.formatValidationMessage(
                 getMessage(),
                 ValidationStrings.DATE_TOO_LATE,
                 new Object[]
-                { field.getDisplayName(), _maxDate });
+                { field.getDisplayName(), 
+                    (translator != null) ? 
+                            translator.format(field, messages.getLocale(), _maxDate)
+                            : _maxDate});
     }
-
+    
+    public void renderContribution(IMarkupWriter writer, IRequestCycle cycle,
+            FormComponentContributorContext context, IFormComponent field)
+    {
+        // TODO: This is a little hacky, but validators need to be able to cooperate
+        // with translators during client side validation as well
+        DateTranslator translator = getFieldTranslator(field);
+        if (translator == null)
+            return;
+        
+        JSONObject profile = context.getProfile();
+        
+        context.addInitializationScript(field, "dojo.require(\"tapestry.form.datetime\");");
+        
+        if (!profile.has(ValidationConstants.CONSTRAINTS)) {
+            profile.put(ValidationConstants.CONSTRAINTS, new JSONObject());
+        }
+        JSONObject cons = profile.getJSONObject(ValidationConstants.CONSTRAINTS);
+        
+        cons.put(field.getClientId(), 
+                new JSONLiteral("[tapestry.form.datetime.isValidDate,{"
+                        + "max:" 
+                        + JSONObject.quote(translator.format(field, context.getLocale(), _maxDate))
+                        + ","
+                        + "format:" 
+                        + JSONObject.quote(Strftime.convertToPosixFormat(translator.getPattern()))
+                        + "}]"));
+        
+        setProfileProperty(field, profile, 
+                ValidationConstants.CONSTRAINTS, buildMessage(context, field, translator));
+    }
+    
+    /**
+     * Used to grab the corresponding {@link DateTranslator} for 
+     * the field, if one exists.
+     * @param field
+     * @return The translator, or null if the required translator type 
+     *          doesn't exist.
+     */
+    private DateTranslator getFieldTranslator(IFormComponent field)
+    {
+        if (TranslatedField.class.isAssignableFrom(field.getClass())) {
+            Translator trans = ((TranslatedField)field).getTranslator();
+            if (DateTranslator.class.isInstance(trans)) {
+                return (DateTranslator)trans;
+            }
+        }
+        
+        return null;
+    }
+    
     public void setMaxDate(Date minDate)
     {
         _maxDate = minDate;

Modified: tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/json/JSONObject.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/json/JSONObject.java?rev=418513&r1=418512&r2=418513&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/json/JSONObject.java (original)
+++ tapestry/tapestry4/trunk/framework/src/java/org/apache/tapestry/json/JSONObject.java Sat Jul  1 15:20:28 2006
@@ -639,6 +639,16 @@
     }
 
     /**
+     * @see {{@link #quote(String)}.
+     * @param value
+     * @return
+     */
+    public static String quote(char value)
+    {
+        return quote(new String(new char[]{value}));
+    }
+    
+    /**
      * Produce a string in double quotes with backslash sequences in all the
      * right places.
      * 

Modified: tapestry/tapestry4/trunk/framework/src/js/tapestry/__package__.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/tapestry/__package__.js?rev=418513&r1=418512&r2=418513&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/tapestry/__package__.js (original)
+++ tapestry/tapestry4/trunk/framework/src/js/tapestry/__package__.js Sat Jul  1 15:20:28 2006
@@ -1,6 +1,6 @@
 dojo.kwCompoundRequire({
 	common: [
-		"tapestry.core","tapestry.event"
+		"tapestry.core","tapestry.event","tapestry.form"
 	],
 	browser: ["tapestry.html"]
 });

Modified: tapestry/tapestry4/trunk/framework/src/js/tapestry/form.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/tapestry/form.js?rev=418513&r1=418512&r2=418513&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/tapestry/form.js (original)
+++ tapestry/tapestry4/trunk/framework/src/js/tapestry/form.js Sat Jul  1 15:20:28 2006
@@ -2,7 +2,6 @@
 
 dojo.require("dojo.event");
 dojo.require("dojo.event.browser");
-dojo.require("dojo.validate.web");
 
 dojo.require("tapestry.core");
 

Modified: tapestry/tapestry4/trunk/framework/src/js/tapestry/form/__package__.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/tapestry/form/__package__.js?rev=418513&r1=418512&r2=418513&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/tapestry/form/__package__.js (original)
+++ tapestry/tapestry4/trunk/framework/src/js/tapestry/form/__package__.js Sat Jul  1 15:20:28 2006
@@ -1,6 +1,6 @@
 dojo.kwCompoundRequire({
 	browser: [
-		"tapestry.form.validation"
+		"tapestry.form.validation", "tapestry.form.datetime"
 	]
 });
 dojo.provide("tapestry.form.*");

Added: tapestry/tapestry4/trunk/framework/src/js/tapestry/form/datetime.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/tapestry/form/datetime.js?rev=418513&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/tapestry/form/datetime.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/tapestry/form/datetime.js Sat Jul  1 15:20:28 2006
@@ -0,0 +1,55 @@
+dojo.provide("tapestry.form.datetime");
+
+dojo.require("dojo.validate.datetime");
+dojo.require("dojo.date");
+
+tapestry.form.datetime={
+	
+	/**
+	 * Checks if the specified value is a valid date, according to
+	 * the flags passed in.
+	 * 
+	 * @param value The string value of the date being validated.
+	 * @param flags An object.
+	 * 		flags.format 	A string format pattern that will be used to validate
+	 * 						the incoming value via @link dojo.validate.isValidDate(value, format).
+	 * 		flags.max		A string date value representing the maximum date that can be selected.
+	 * 		flags.min		A string date value representing the minimum date that can be selected.
+	 * @return Boolean. True if valid, false otherwise.
+	 */
+	isValidDate:function(value, flags){
+		// default generic validation if no flags specified
+		if (!flags || typeof flags.format != "string") 
+			return dojo.validate.isValidDate(value);
+		
+		// basic format validation
+		if (!dojo.validate.isValidDate(value, flags.format)) 
+			return false;
+		
+		// parse date value
+		var dateValue=null;
+		try {
+			dateValue = new Date(value);
+		} catch (e) {
+			dojo.log.exception("Error parsing input date.", e, true);
+			return false;
+		}
+		
+		// max date
+		if (typeof flags.max == "string") {
+			var max = new Date(flags.max);
+			if (dojo.date.compare(dateValue, max, dojo.date.compareTypes.DATE) >= 0)
+				return false;
+		}
+		
+		// min date
+		if (typeof flags.min == "string") {
+			var min = new Date(flags.min);
+			if (dojo.date.compare(dateValue, min, dojo.date.compareTypes.DATE) < 0)
+				return false;
+		}
+		
+		return true;
+	}
+		
+}

Propchange: tapestry/tapestry4/trunk/framework/src/js/tapestry/form/datetime.js
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tapestry/tapestry4/trunk/framework/src/js/tapestry/form/validation.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/tapestry/form/validation.js?rev=418513&r1=418512&r2=418513&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/tapestry/form/validation.js (original)
+++ tapestry/tapestry4/trunk/framework/src/js/tapestry/form/validation.js Sat Jul  1 15:20:28 2006
@@ -199,4 +199,4 @@
 						}, node);
 		dialog.show();
 	}
-}
\ No newline at end of file
+}

Added: tapestry/tapestry4/trunk/framework/src/js/tests/form/test_datetime.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/js/tests/form/test_datetime.js?rev=418513&view=auto
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/js/tests/form/test_datetime.js (added)
+++ tapestry/tapestry4/trunk/framework/src/js/tests/form/test_datetime.js Sat Jul  1 15:20:28 2006
@@ -0,0 +1,44 @@
+dojo.setModulePrefix("tapestry", "../tapestry");
+
+dojo.require("dojo.date");
+
+dojo.require("tapestry.*");
+dojo.require("tapestry.test");
+dojo.require("tapestry.form.datetime");
+
+function test_datetime_validDate(){
+	var value = "08/15/1999";
+	jum.assertTrue(value, tapestry.form.datetime.isValidDate(value));
+	
+	value = "12112/12/23434";
+	jum.assertFalse(value, tapestry.form.datetime.isValidDate(value));
+	jum.assertFalse("null value", tapestry.form.datetime.isValidDate());
+}
+
+function test_datetime_maxDate(){
+	var maxValue = "09/28/2020";
+	
+	var value = "08/15/2021";
+	jum.assertTrue(value, tapestry.form.datetime.isValidDate(value, {max:maxValue}));
+	
+	jum.assertFalse(value, tapestry.form.datetime.isValidDate(value, 
+									{max:maxValue, format:"MM/DD/YYYY"}));
+	
+	value = "08/15/2020";
+	jum.assertTrue(value, tapestry.form.datetime.isValidDate(value, 
+									{max:maxValue, format:"MM/DD/YYYY"}));
+}
+
+function test_datetime_minDate(){
+	var minValue = "09/28/2000";
+	
+	var value = "09/27/2000";
+	jum.assertTrue(value, tapestry.form.datetime.isValidDate(value, {min:minValue}));
+	
+	jum.assertFalse(value, tapestry.form.datetime.isValidDate(value, 
+									{min:minValue, format:"MM/DD/YYYY"}));
+	
+	value = "09/28/2000";
+	jum.assertTrue(value, tapestry.form.datetime.isValidDate(value, 
+									{min:minValue, format:"MM/DD/YYYY"}));
+}

Propchange: tapestry/tapestry4/trunk/framework/src/js/tests/form/test_datetime.js
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/form/validator/TestEmail.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/form/validator/TestEmail.java?rev=418513&r1=418512&r2=418513&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/form/validator/TestEmail.java (original)
+++ tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/form/validator/TestEmail.java Sat Jul  1 15:20:28 2006
@@ -111,6 +111,8 @@
         
         IFormComponent field = newField("Fred", "myfield");
         
+        context.addInitializationScript(field, "dojo.require(\"dojo.validate.web\");");
+        
         expect(context.getProfile()).andReturn(json);
         
         trainFormatMessage(context, null, ValidationStrings.INVALID_EMAIL, 
@@ -122,15 +124,9 @@
 
         verify();
         
-        /*
-        assertNotNull(json.get(ValidationConstants.REQUIRED));
-        JSONArray arr = json.getJSONArray(ValidationConstants.REQUIRED);
-        assertEquals("fred", arr.getString(0));
-        
-        assertNotNull(json.get("fred"));
-        JSONObject obj = json.getJSONObject("fred");
-        assertEquals("Default\\Message for Fred.", obj.getString(ValidationConstants.REQUIRED));
-        */
+        assertEquals("{\"myfield\":{\"constraints\":\"default\\\\message\"},"
+                + "\"constraints\":{\"myfield\":[dojo.validate.isEmailAddress,false,true]}}",
+                json.toString());
     }
 
     public void testRenderContributionCustomMessage()
@@ -143,6 +139,8 @@
         
         IFormComponent field = newField("Fred", "barney");
         
+        context.addInitializationScript(field, "dojo.require(\"dojo.validate.web\");");
+        
         expect(context.getProfile()).andReturn(json);
         
         trainFormatMessage(
@@ -156,17 +154,11 @@
         replay();
         
         new Email("message=custom").renderContribution(writer, cycle, context, field);
-
+        
         verify();
         
-        /*
-        assertNotNull(json.get(ValidationConstants.REQUIRED));
-        JSONArray arr = json.getJSONArray(ValidationConstants.REQUIRED);
-        assertEquals("fred", arr.getString(0));
-        
-        assertNotNull(json.get("fred"));
-        JSONObject obj = json.getJSONObject("fred");
-        assertEquals("Default\\Message for Fred.", obj.getString(ValidationConstants.REQUIRED));
-        */
+        assertEquals("{\"constraints\":{\"barney\":[dojo.validate.isEmailAddress,false,true]},"
+                + "\"barney\":{\"constraints\":\"custom message\"}}",
+                json.toString());
     }
 }

Modified: tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/form/validator/TestMax.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/form/validator/TestMax.java?rev=418513&r1=418512&r2=418513&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/form/validator/TestMax.java (original)
+++ tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/form/validator/TestMax.java Sat Jul  1 15:20:28 2006
@@ -14,13 +14,18 @@
 
 package org.apache.tapestry.form.validator;
 
+import static org.easymock.EasyMock.*;
 import static org.testng.AssertJUnit.assertEquals;
 
+import java.text.DecimalFormatSymbols;
+import java.util.Locale;
+
 import org.apache.tapestry.IMarkupWriter;
 import org.apache.tapestry.IRequestCycle;
 import org.apache.tapestry.form.FormComponentContributorContext;
 import org.apache.tapestry.form.IFormComponent;
 import org.apache.tapestry.form.ValidationMessages;
+import org.apache.tapestry.json.JSONObject;
 import org.apache.tapestry.valid.ValidationConstraint;
 import org.apache.tapestry.valid.ValidationStrings;
 import org.apache.tapestry.valid.ValidatorException;
@@ -100,34 +105,52 @@
     {
         IMarkupWriter writer = newWriter();
         IRequestCycle cycle = newCycle();
+        JSONObject json = new JSONObject();
+        
         IFormComponent field = newField("My Field", "myfield");
         
         FormComponentContributorContext context = newMock(FormComponentContributorContext.class);
-
-        context.includeClasspathScript("/org/apache/tapestry/form/validator/NumberValidator.js");
+        
+        Locale locale = Locale.FRANCE;
+        DecimalFormatSymbols symbols = new DecimalFormatSymbols(locale);
+        
+        expect(context.getLocale()).andReturn(locale);
+        
+        expect(context.getProfile()).andReturn(json);
         
         trainFormatMessage(context, null, ValidationStrings.VALUE_TOO_LARGE, new Object[]
         { "My Field", new Double(20) }, "default message");
-
-        context.addSubmitHandler("function(event) { Tapestry.validate_max_number(event, 'myfield', 20.0, 'default message'); }");
-
+        
         replay();
 
         new Max("max=20").renderContribution(writer, cycle, context, field);
 
         verify();
+        
+        assertEquals("{\"myfield\":{\"constraints\":\"default message\"},"
+                + "\"constraints\":{\"myfield\":[dojo.validate.isInRange,{max:20.0,decimal:\""
+                + symbols.getDecimalSeparator() + "\"]}}",
+                json.toString());
     }
-
+    
     public void testRenderContributionCustomMessage()
     {
         IMarkupWriter writer = newWriter();
         IRequestCycle cycle = newCycle();
+        
+        JSONObject json = new JSONObject();
+        
         IFormComponent field = newField("My Field", "myfield");
         
         FormComponentContributorContext context = newMock(FormComponentContributorContext.class);
-
-        context.includeClasspathScript("/org/apache/tapestry/form/validator/NumberValidator.js");
-
+        
+        Locale locale = Locale.FRANCE;
+        DecimalFormatSymbols symbols = new DecimalFormatSymbols(locale);
+        
+        expect(context.getLocale()).andReturn(locale);
+        
+        expect(context.getProfile()).andReturn(json);
+        
         trainFormatMessage(
                 context,
                 "custom",
@@ -136,13 +159,16 @@
                 { "My Field", new Double(20) },
                 "custom\\message");
         
-        context.addSubmitHandler("function(event) { Tapestry.validate_max_number(event, 'myfield', 20.0, 'custom\\\\message'); }");
-
         replay();
-
+        
         new Max("max=20,message=custom").renderContribution(writer, cycle, context, field);
 
         verify();
+        
+        assertEquals("{\"myfield\":{\"constraints\":\"custom\\\\message\"},"
+                + "\"constraints\":{\"myfield\":[dojo.validate.isInRange,{max:20.0,decimal:\""
+                + symbols.getDecimalSeparator() + "\"]}}",
+                json.toString());
     }
 
 }

Modified: tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/form/validator/TestMaxDate.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/form/validator/TestMaxDate.java?rev=418513&r1=418512&r2=418513&view=diff
==============================================================================
--- tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/form/validator/TestMaxDate.java (original)
+++ tapestry/tapestry4/trunk/framework/src/test/org/apache/tapestry/form/validator/TestMaxDate.java Sat Jul  1 15:20:28 2006
@@ -14,15 +14,22 @@
 
 package org.apache.tapestry.form.validator;
 
+import static org.easymock.EasyMock.checkOrder;
+import static org.easymock.EasyMock.expect;
 import static org.testng.AssertJUnit.assertEquals;
 
 import java.util.Date;
+import java.util.Locale;
 
 import org.apache.tapestry.IMarkupWriter;
 import org.apache.tapestry.IRequestCycle;
 import org.apache.tapestry.form.FormComponentContributorContext;
 import org.apache.tapestry.form.IFormComponent;
+import org.apache.tapestry.form.TranslatedField;
 import org.apache.tapestry.form.ValidationMessages;
+import org.apache.tapestry.form.translator.DateTranslator;
+import org.apache.tapestry.json.JSONObject;
+import org.apache.tapestry.util.Strftime;
 import org.apache.tapestry.valid.ValidationConstraint;
 import org.apache.tapestry.valid.ValidationStrings;
 import org.apache.tapestry.valid.ValidatorException;
@@ -38,7 +45,7 @@
 public class TestMaxDate extends BaseValidatorTestCase
 {
     private static final long ONE_DAY = 24 * 60 * 60 * 1000l;
-
+    
     public void testOK() throws Exception
     {
         long now = System.currentTimeMillis();
@@ -126,18 +133,99 @@
 
         verify();
     }
-
-    public void testRenderComponentNoOp()
+    
+    public void testRenderContribution()
     {
         IMarkupWriter writer = newWriter();
         IRequestCycle cycle = newCycle();
-        FormComponentContributorContext context = newContext();
-        IFormComponent field = newField();
-
+        JSONObject json = new JSONObject();
+        
+        TranslatedField field = newMock(TranslatedField.class);
+        checkOrder(field, false);
+        
+        Date maxDate = new Date(System.currentTimeMillis() + ONE_DAY);
+        DateTranslator translator = new DateTranslator();
+        
+        expect(field.getTranslator()).andReturn(translator);
+        
+        expect(field.getClientId()).andReturn("myfield").anyTimes();
+        
+        expect(field.getDisplayName()).andReturn("My Field");
+        
+        FormComponentContributorContext context = newMock(FormComponentContributorContext.class);
+        
+        Locale locale = Locale.ENGLISH;
+        expect(context.getLocale()).andReturn(locale).anyTimes();
+        
+        expect(context.getProfile()).andReturn(json);
+        
+        context.addInitializationScript(field, "dojo.require(\"tapestry.form.datetime\");");
+        
+        String strMax = translator.format(field, locale, maxDate);
+        
+        trainFormatMessage(context, null, ValidationStrings.DATE_TOO_LATE, 
+                new Object[] { "My Field", strMax }, "default message");
+        
         replay();
-
-        new MaxDate().renderContribution(writer, cycle, context, field);
-
+        
+        new MaxDate("maxDate="+strMax).renderContribution(writer, cycle, context, field);
+        
+        verify();
+        
+        assertEquals("{\"myfield\":{\"constraints\":\"default message\"},"
+                + "\"constraints\":{\"myfield\":["
+                + "tapestry.form.datetime.isValidDate,{max:\""
+                + strMax + "\",format:"
+                + JSONObject.quote(Strftime.convertToPosixFormat(translator.getPattern())) 
+                + "}]}}",
+                json.toString());
+    }
+    
+    public void testRenderContributionCustomMessage()
+    {
+        IMarkupWriter writer = newWriter();
+        IRequestCycle cycle = newCycle();
+        JSONObject json = new JSONObject();
+        
+        TranslatedField field = newMock(TranslatedField.class);
+        checkOrder(field, false);
+        
+        Date maxDate = new Date(System.currentTimeMillis() + ONE_DAY);
+        DateTranslator translator = new DateTranslator();
+        
+        expect(field.getTranslator()).andReturn(translator);
+        
+        expect(field.getClientId()).andReturn("myfield").anyTimes();
+        
+        expect(field.getDisplayName()).andReturn("My Field");
+        
+        FormComponentContributorContext context = newMock(FormComponentContributorContext.class);
+        
+        Locale locale = Locale.ENGLISH;
+        expect(context.getLocale()).andReturn(locale).anyTimes();
+        
+        expect(context.getProfile()).andReturn(json);
+        
+        context.addInitializationScript(field, "dojo.require(\"tapestry.form.datetime\");");
+        
+        String strMax = translator.format(field, locale, maxDate);
+        
+        trainFormatMessage(context, "custom", ValidationStrings.DATE_TOO_LATE, 
+                new Object[] { "My Field", strMax }, 
+                "custom\\message");
+        
+        replay();
+        
+        new MaxDate("maxDate=" + strMax + ",message=custom").renderContribution(writer, cycle, context, field);
+        
         verify();
+        
+        assertEquals("{\"myfield\":{\"constraints\":\"custom\\\\message\"},"
+                + "\"constraints\":{\"myfield\":["
+                + "tapestry.form.datetime.isValidDate,{max:\""
+                + strMax + "\",format:"
+                + JSONObject.quote(Strftime.convertToPosixFormat(translator.getPattern())) 
+                + "}]}}",
+                json.toString());
     }
 }