You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2008/08/26 23:31:32 UTC
svn commit: r689238 [2/3] - in /tapestry/tapestry5/trunk: src/site/apt/
src/site/apt/cookbook/ src/site/apt/guide/
tapestry-core/src/main/java/org/apache/tapestry5/
tapestry-core/src/main/java/org/apache/tapestry5/corelib/base/
tapestry-core/src/main/j...
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentDefaultProvider.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentDefaultProvider.java?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentDefaultProvider.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/ComponentDefaultProvider.java Tue Aug 26 14:31:30 2008
@@ -59,6 +59,15 @@
* @param resources
* @return the translator, or null
*/
- Translator defaultTranslator(String parameterName, ComponentResources resources);
+ FieldTranslator defaultTranslator(String parameterName, ComponentResources resources);
+ /**
+ * Provides a validator based on the bound parameter type. If the property type of the parameter is not known, then
+ * a no-op validator is returned.
+ *
+ * @param parameterName
+ * @param resources
+ * @return the validator, possibly a no-op validator
+ */
+ FieldValidator defaultValidator(String parameterName, ComponentResources resources);
}
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/FieldTranslatorSource.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/FieldTranslatorSource.java?rev=689238&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/FieldTranslatorSource.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/FieldTranslatorSource.java Tue Aug 26 14:31:30 2008
@@ -0,0 +1,69 @@
+// Copyright 2008 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.tapestry5.services;
+
+import org.apache.tapestry5.ComponentResources;
+import org.apache.tapestry5.Field;
+import org.apache.tapestry5.FieldTranslator;
+import org.apache.tapestry5.Translator;
+import org.apache.tapestry5.ioc.AnnotationProvider;
+import org.apache.tapestry5.ioc.Messages;
+
+import java.util.Locale;
+
+/**
+ * For a particular field, generates the default {@link org.apache.tapestry5.FieldTranslator} for the field.
+ */
+public interface FieldTranslatorSource
+{
+ /**
+ * Common shorthand for {@link #createDefaultTranslator(org.apache.tapestry5.Field, String,
+ * org.apache.tapestry5.ioc.Messages, java.util.Locale, Class, org.apache.tapestry5.ioc.AnnotationProvider)}.
+ *
+ * @param resources of component who owns the parameter
+ * @param parameterName name of parameter used to determine the property type
+ * @return field translator, or null
+ */
+ FieldTranslator createDefaultTranslator(ComponentResources resources, String parameterName);
+
+ /**
+ * Creates a {@link org.apache.tapestry5.FieldTranslator} for the given property, or returns null if one can't be
+ * constructed. The return value is null if the property type is not known, or if there is no {@link
+ * org.apache.tapestry5.Translator} available from the {@link org.apache.tapestry5.services.TranslatorSource} that
+ * is appropriate for the property type.
+ *
+ * @param field for which a translator is needed
+ * @param overrideId id used when looking in the overrideMessages for a message override
+ * @param overrideMessages location to look for overriding messages
+ * @param locale to localize validation messages to
+ * @param propertyType type of property editted by the field, used to select the Translator
+ * @param propertyAnnotations annotations on the property (not currently used)
+ * @return the field translator, or null
+ */
+ FieldTranslator createDefaultTranslator(Field field, String overrideId, Messages overrideMessages, Locale locale,
+ Class propertyType, AnnotationProvider propertyAnnotations);
+
+ /**
+ * Wraps a {@link org.apache.tapestry5.Translator} as a FieldTranslator.
+ */
+ FieldTranslator createTranslator(Field field, String overrideId, Messages overrideMessages, Locale locale,
+ Translator translator);
+
+ /**
+ * Creates a translator (used by the {@link org.apache.tapestry5.BindingConstants#TRANSLATE translate: binding
+ * prefix}).
+ */
+ FieldTranslator createTranslator(ComponentResources componentResources, String translatorName);
+}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/FieldValidatorDefaultSource.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/FieldValidatorDefaultSource.java?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/FieldValidatorDefaultSource.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/FieldValidatorDefaultSource.java Tue Aug 26 14:31:30 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 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.
@@ -14,6 +14,7 @@
package org.apache.tapestry5.services;
+import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.Field;
import org.apache.tapestry5.FieldValidator;
import org.apache.tapestry5.ioc.AnnotationProvider;
@@ -42,4 +43,14 @@
*/
FieldValidator createDefaultValidator(Field field, String overrideId, Messages overrideMessages, Locale locale,
Class propertyType, AnnotationProvider propertyAnnotations);
+
+ /**
+ * A convienience for the full version; assumes that the resources are associated with a {@link
+ * org.apache.tapestry5.Field}.
+ *
+ * @param resources
+ * @param parameterName
+ * @return
+ */
+ FieldValidator createDefaultValidator(ComponentResources resources, String parameterName);
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/PropertyEditContext.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/PropertyEditContext.java?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/PropertyEditContext.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/PropertyEditContext.java Tue Aug 26 14:31:30 2008
@@ -15,8 +15,8 @@
package org.apache.tapestry5.services;
import org.apache.tapestry5.Field;
+import org.apache.tapestry5.FieldTranslator;
import org.apache.tapestry5.FieldValidator;
-import org.apache.tapestry5.Translator;
import org.apache.tapestry5.ioc.AnnotationProvider;
import org.apache.tapestry5.ioc.Messages;
@@ -50,9 +50,10 @@
/**
* Returns the translator appropriate for the field (this is based on the property type).
*
- * @see TranslatorDefaultSource
+ * @param field
+ * @see org.apache.tapestry5.services.TranslatorSource
*/
- Translator getTranslator();
+ FieldTranslator getTranslator(Field field);
/**
* Returns the FieldValidator for the field.
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java Tue Aug 26 14:31:30 2008
@@ -187,6 +187,7 @@
binder.bind(HiddenFieldLocationRules.class, HiddenFieldLocationRulesImpl.class);
binder.bind(PageDocumentGenerator.class, PageDocumentGeneratorImpl.class);
binder.bind(ResponseRenderer.class, ResponseRendererImpl.class);
+ binder.bind(FieldTranslatorSource.class, FieldTranslatorSourceImpl.class);
}
// ========================================================================
@@ -628,16 +629,16 @@
* Contributes the basic set of named translators: <ul> <li>string</li> <li>byte</li> <li>integer</li>
* <li>long</li> <li>float</li> <li>double</li> <li>short</li> </ul>
*/
- public static void contributeTranslatorSource(MappedConfiguration<String, Translator> configuration)
+ public static void contributeTranslatorSource(Configuration<Translator> configuration)
{
- configuration.add("string", new StringTranslator());
- configuration.add("byte", new ByteTranslator());
- configuration.add("integer", new IntegerTranslator());
- configuration.add("long", new LongTranslator());
- configuration.add("float", new FloatTranslator());
- configuration.add("double", new DoubleTranslator());
- configuration.add("short", new ShortTranslator());
+ configuration.add(new StringTranslator());
+ configuration.add(new ByteTranslator());
+ configuration.add(new IntegerTranslator());
+ configuration.add(new LongTranslator());
+ configuration.add(new FloatTranslator());
+ configuration.add(new DoubleTranslator());
+ configuration.add(new ShortTranslator());
}
/**
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TranslatorSource.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TranslatorSource.java?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TranslatorSource.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TranslatorSource.java Tue Aug 26 14:31:30 2008
@@ -17,7 +17,9 @@
import org.apache.tapestry5.Translator;
/**
- * A source for {@link Translator}s, either by name.
+ * A source for {@link Translator}s, either by name or by property type.
+ * <p/>
+ * The configuration for the service is an unordered collection of {@link org.apache.tapestry5.Translator}.
*/
public interface TranslatorSource
{
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/test/TapestryTestCase.java Tue Aug 26 14:31:30 2008
@@ -434,7 +434,6 @@
return result;
}
-
};
expect(transformation.findMethods(EasyMock.isA(MethodFilter.class))).andAnswer(answer);
@@ -575,7 +574,6 @@
protected final void train_getFieldType(ClassTransformation transformation, String fieldName, String type)
{
expect(transformation.getFieldType(fieldName)).andReturn(type).atLeastOnce();
-
}
protected final void train_getId(ComponentResources resources, String id)
@@ -1098,11 +1096,62 @@
protected final void train_isRequired(Field field, boolean required)
{
expect(field.isRequired()).andReturn(required);
-
}
protected final void train_getClientId(ClientElement element, String clientId)
{
expect(element.getClientId()).andReturn(clientId);
}
+
+ protected final FieldTranslator mockFieldTranslator()
+ {
+ return newMock(FieldTranslator.class);
+ }
+
+
+ protected final Translator mockTranslator(String name, Class type)
+ {
+ Translator translator = mockTranslator();
+
+ train_getName(translator, name);
+ train_getType(translator, type);
+
+ return translator;
+ }
+
+ protected final void train_getName(Translator translator, String name)
+ {
+ expect(translator.getName()).andReturn(name).atLeastOnce();
+ }
+
+ protected final void train_getType(Translator translator, Class type)
+ {
+ expect(translator.getType()).andReturn(type).atLeastOnce();
+ }
+
+ protected final void train_createDefaultTranslator(FieldTranslatorSource source, ComponentResources resources,
+ String parameterName, FieldTranslator translator)
+ {
+ expect(source.createDefaultTranslator(resources, parameterName)).andReturn(translator);
+ }
+
+ protected final TranslatorSource mockTranslatorSource()
+ {
+ return newMock(TranslatorSource.class);
+ }
+
+ protected final void train_get(TranslatorSource translatorSource, String name, Translator translator)
+ {
+ expect(translatorSource.get(name)).andReturn(translator).atLeastOnce();
+ }
+
+ protected final void train_getMessageKey(Translator translator, String messageKey)
+ {
+ expect(translator.getMessageKey()).andReturn(messageKey).atLeastOnce();
+ }
+
+ protected final void train_findByType(TranslatorSource ts, Class propertyType, Translator translator)
+ {
+ expect(ts.findByType(propertyType)).andReturn(translator);
+ }
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/datefield.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/datefield.js?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/datefield.js (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/datefield.js Tue Aug 26 14:31:30 2008
@@ -75,8 +75,8 @@
var errorHandler = function(message)
{
- Tapestry.fieldError(this.field, message);
- Tapestry.focus(this.field);
+ this.field.showValidationMessage(message);
+ this.field.activate();
};
this.sendServerRequest(this.parseURL, value, resultHandler, errorHandler);
@@ -120,7 +120,7 @@
this.datePicker.onselect = function()
{
- var input = this.formatDate(this.datePicker.getDate());
+ var input = this.canonicalizeDate(this.datePicker.getDate());
var resultHandler = function(result)
{
@@ -133,16 +133,21 @@
var errorHandler = function(message)
{
- Tapestry.fieldError(this.field, message);
- Tapestry.focus(this.field);
+ this.field.showValidationMessage(message);
+ this.field.activate();
+
this.hidePopup();
- }
+ };
this.sendServerRequest(this.formatURL, input, resultHandler, errorHandler);
}.bind(this);
},
- formatDate : function(date)
+ /**
+ * Reformats the date into a canoncialized format accepted on the server. The format
+ * is equivalent to M/d/yyyy. This format is used regardless of localization.
+ */
+ canonicalizeDate : function(date)
{
if (date == null) return "";
@@ -155,7 +160,7 @@
this.popup.clonePosition(this.field, { offsetTop: this.field.getHeight() + 2 }).setStyle({ width: "", height: "" });
},
- /** Duration used when fading the popup in or out. */
+ /** Duration, in seconds, used when fading the popup in or out. */
FADE_DURATION : .20,
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages.properties?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages.properties Tue Aug 26 14:31:30 2008
@@ -24,11 +24,10 @@
# This is lousy as a default, since the pattern string is meaningless to the user. You should always override
# this.
regexp=%2$s does not match pattern '%1$s'.
+invalid-email='%2$s' is not a valid email address.
# This is where the translator messages go.
-integer-format-exception=The input value '%s' is not parseable as an integer value.
-number-format-exception=The input value '%s' is not parseable as a numeric value.
+integer-format-exception=You must provide an integer value for %s.
+number-format-exception=You must provide a numeric value for %s.
-
-invalid-email='%2$s' is not a valid email address.
\ No newline at end of file
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_da.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_da.properties?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_da.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_da.properties Tue Aug 26 14:31:30 2008
@@ -24,10 +24,7 @@
# This is lousy as a default, since the pattern string is meaningless to the user. You should always override
# this.
regexp=%2$s opfylder ikke mønstret '%1$s'.
+invalid-email=%2$s er ikke en gyldig e-mail-adresse.
# This is where the translator messages go.
-integer-format-exception=Værdien af %s er ikke et gyldigt heltal.
-number-format-exception=Værdien af %s er ikke et gyldigt tal.
-
-invalid-email=%2$s er ikke en gyldig e-mail-adresse.
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_de_DE.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_de_DE.properties?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_de_DE.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_de_DE.properties Tue Aug 26 14:31:30 2008
@@ -27,6 +27,3 @@
# This is where the translator messages go.
-integer-format-exception=Die Eingabe '%s' ist kein Zahlenwert.
-number-format-exception=Die Eingabe '%s' ist kein numerischer Wert.
-
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_fi_FI.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_fi_FI.properties?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_fi_FI.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_fi_FI.properties Tue Aug 26 14:31:30 2008
@@ -24,14 +24,6 @@
# This is lousy as a default, since the pattern string is meaningless to the user. You should always override
# this.
regexp=%2$s ei vastaa merkkijonoa '%1$s'.
-
-# This is where the translator messages go.
-
-integer-format-exception=\"%s\" ei ole kokonaisluku.
-number-format-exception=\"%s\" ei ole numero.
-
invalid-email='%2$s' ei ole s\u00E4hk\u00F6postiosoite.
-# The label/alt text for the icon that is displayed next to each field.
-
-icon-label=[Virhe]
\ No newline at end of file
+# This is where the translator messages go.
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_fr_FR.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_fr_FR.properties?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_fr_FR.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_fr_FR.properties Tue Aug 26 14:31:30 2008
@@ -24,11 +24,7 @@
# This is lousy as a default, since the pattern string is meaningless to the user. You should always override
# this.
regexp=%2$s ne correspond pas a l'expression '%1$s'.
+invalid-email='%2$s' n'est pas une adresse courriel valide.
# This is where the translator messages go.
-integer-format-exception=La valeur entrée '%s' n'est pas un entier.
-number-format-exception=The input value '%s' n'est pas une valeur numérique.
-
-
-invalid-email='%2$s' n'est pas une adresse courriel valide.
\ No newline at end of file
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_hr.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_hr.properties?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_hr.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_hr.properties Tue Aug 26 14:31:30 2008
@@ -24,11 +24,8 @@
# This is lousy as a default, since the pattern string is meaningless to the user. You should always override
# this.
regexp=%2$s je potrebno upisati u sljedeÄem obliku: '%1$s'.
+invalid-email='%2$s' nije valjana e-mail addresa.
# This is where the translator messages go.
-integer-format-exception='%s' nije cijeli broj.
-number-format-exception='%s' nije numeriÄka vrijednost.
-
-invalid-email='%2$s' nije valjana e-mail addresa.
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_it.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_it.properties?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_it.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_it.properties Tue Aug 26 14:31:30 2008
@@ -27,6 +27,3 @@
# This is where the translator messages go.
-integer-format-exception=Il valore di '%s' deve essere un numero intero.
-number-format-exception=Il valore di '%s' deve essere un numero.
-
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_pt_PT.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_pt_PT.properties?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_pt_PT.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_pt_PT.properties Tue Aug 26 14:31:30 2008
@@ -27,6 +27,3 @@
# This is where the translator messages go.
-integer-format-exception=O valor '%s' n\u00e3o \u00e9 um valor inteiro.
-number-format-exception=O valor '%s' n\u00e3o \u00e9 um valor num\u00e9rico.
-
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_ru.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_ru.properties?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_ru.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_ru.properties Tue Aug 26 14:31:30 2008
@@ -24,11 +24,8 @@
# This is lousy as a default, since the pattern string is meaningless to the user. You should always override
# this.
regexp=%2$s не ÑооÑвеÑÑÑвÑÐµÑ ÑÑебÑÐµÐ¼Ð¾Ð¼Ñ ÑÐ°Ð±Ð»Ð¾Ð½Ñ '%1$s'.
+invalid-email='%2$s' недейÑÑвиÑелÑнÑй адÑÐµÑ ÑлекÑÑонной поÑÑÑ.
# This is where the translator messages go.
-integer-format-exception='%s' должно бÑÑÑ ÑелÑм ÑиÑлом.
-number-format-exception='%s' должно бÑÑÑ ÑиÑлом.
-
-invalid-email='%2$s' недейÑÑвиÑелÑнÑй адÑÐµÑ ÑлекÑÑонной поÑÑÑ.
\ No newline at end of file
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_sv_SE.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_sv_SE.properties?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_sv_SE.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_sv_SE.properties Tue Aug 26 14:31:30 2008
@@ -24,10 +24,7 @@
# This is lousy as a default, since the pattern string is meaningless to the user. You should always override
# this.
regexp=%2$s matchar inte m\u00F6nstret '%1$s'.
+invalid-email='%2$s' \u00E4r inte en korrekt formad email-adress.
# This is where the translator messages go.
-integer-format-exception=Angivna v\u00E4rdet '%s' kan inte tolkas som ett heltalsv\u00E4rde.
-number-format-exception=Angivna v\u00E4rdet '%s' kan inte tolkas som ett numeriskt v\u00E4rde.
-
-invalid-email='%2$s' \u00E4r inte en korrekt formad email-adress.
\ No newline at end of file
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_zh_CN.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_zh_CN.properties?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_zh_CN.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/internal/ValidationMessages_zh_CN.properties Tue Aug 26 14:31:30 2008
@@ -21,10 +21,6 @@
min-integer = %2$s\u7684\u6570\u503C\u4E0D\u80FD\u5C0F\u4E8E%1$d\u3002
-minimum-string-length = %2$s\u7684\u5185\u5BB9\u4E0D\u80FD\u5C11\u4E8E%1$s\u5B57\u7B26\u3002
-
-number-format-exception = \u8F93\u5165\u7684'%s'\u4E0D\u662F\u6570\u5B57.
-
# We try to keep these consistent, with the constraint value (if applicable)
# as the first parameter, and the field's label as the second parameter. Occasionally
# we must use specific indexing when that's not the best order.
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js Tue Aug 26 14:31:30 2008
@@ -14,19 +14,37 @@
var Tapestry = {
- /** Event, triggered on a Form element, to spur fields within the form to validate thier input. */
+ /** Event that allows observers to perform cross-form validation after individual
+ * fields have performed their validation. The form element is passed as the
+ * event memo. Observers may set the form's validationError property to true (which
+ * will prevent form submission).
+ */
FORM_VALIDATE_EVENT : "tapestry:formvalidate",
- /** Event, triggered on a Form element, to allow callbacks to perpare for a form submission (this
- * occurs after validation).
+ /** Event fired just before the form submits, to allow observers to make
+ * final preparations for the submission, such as updating hidden form fields.
+ * The form element is passed as the event memo.
*/
FORM_PREPARE_FOR_SUBMIT_EVENT : "tapestry:formprepareforsubmit",
/**
- * Form event fired after prepare.
+ * Form event fired after prepare.
*/
FORM_PROCESS_SUBMIT_EVENT : "tapestry:formprocesssubmit",
+ /** Event, triggered on a field element, to cause observers validate the format of the input, and potentially
+ * reformat it. The field will be passed to observers as the event memo. This event will be followed by
+ * FIELD_VALIDATE_EVENT, if the field's value is non-blank. Observers may invoke Element.showValidationMessage()
+ * to identify that the field is in error (and decorate the field and show a popup error message).
+ */
+ FIELD_FORMAT_EVENT : "tapestry:fieldformat",
+
+ /** Event, triggered on a field element, to cause observers to validate the input. The field will be passed
+ * to observers as the event memo. Observers may invoke Element.showValidationMessage()
+ * to identify that the field is in error (and decorate the field and show a popup error message).
+ */
+ FIELD_VALIDATE_EVENT : "tapestry:fieldvalidate",
+
/** Event, triggered on the document object, which identifies the current focus element. */
FOCUS_CHANGE_EVENT : "tapestry:focuschange",
@@ -36,8 +54,6 @@
/** Time, in seconds, that console messages are visible. */
CONSOLE_DURATION : 60,
- FormEvent : Class.create(),
-
FormEventManager : Class.create(),
FieldEventManager : Class.create(),
@@ -64,7 +80,7 @@
/** Find all elements marked with the "t-invisible" CSS class and hide()s them, so that
* Prototype's visible() method operates correctly. This is invoked when the
* DOM is first loaded, and AGAIN whenever dynamic content is loaded via the Zone
- * mechanism. In addition, adds a focus listener for each form element.
+ * mechanism. In addition, adds a focus listener for each form element.
*/
onDomLoadedCallback : function()
{
@@ -97,14 +113,14 @@
});
},
- // Generalized initialize function for Tapestry, used to help minimize the amount of JavaScript
- // for the page by removing redundancies such as repeated Object and method names. The spec
- // is a hash whose keys are the names of methods of the Tapestry.Initializer object.
- // The value is an array of arrays. The outer arrays represent invocations
- // of the method. The inner array are the parameters for each invocation.
- // As an optimization, the inner value may not be an array but instead
- // a single value.
-
+ /* Generalized initialize function for Tapestry, used to help minimize the amount of JavaScript
+ * for the page by removing redundancies such as repeated Object and method names. The spec
+ * is a hash whose keys are the names of methods of the Tapestry.Initializer object.
+ * The value is an array of arrays. The outer arrays represent invocations
+ * of the method. The inner array are the parameters for each invocation.
+ * As an optimization, the inner value may not be an array but instead
+ * a single value.
+ */
init : function(spec)
{
$H(spec).each(function(pair)
@@ -133,22 +149,38 @@
});
},
+ /** Formats and displays an error message on the console. */
error : function (message, substitutions)
{
Tapestry.updateConsole("t-err", message, substitutions);
},
+ /** Formats and displays a warning on the console. */
warn : function (message, substitutions)
{
Tapestry.updateConsole("t-warn", message, substitutions);
},
+ /** Formats and displays a debug message on the console, if Tapestry.DEBUG_ENABLED is true. */
debug : function (message, substitutions)
{
if (Tapestry.DEBUG_ENABLED)
Tapestry.updateConsole("t-debug", message, substitutions);
},
+ /** Formats a message and updates the console. The console is virtual
+ * when FireBug is not present, the messages float in the upper-left corner
+ * of the page and fade out after a short period. The background color identifies
+ * the severity of the message (red for error, yellow for warnings, grey for debug).
+ * Messages can be clicked, which removes the immediately.
+ *
+ * When FireBug is present, the error(), warn() and debug() methods do not invoke
+ * this; instead those functions are rewritten to write entries into the FireBug console.
+ *
+ * @param className to use for the div element in the console
+ * @param message message template
+ * @param substitutions interpolated into the message (if provided)
+ */
updateConsole : function (className, message, substitutions)
{
if (substitutions != undefined)
@@ -181,23 +213,6 @@
},
- getFormEventManager : function(form)
- {
- form = $(form);
-
- var manager = form.eventManager;
-
- if (manager == undefined)
- manager = new Tapestry.FormEventManager(form);
-
- return manager;
- },
-
- fieldError : function(field, message)
- {
- this.getFieldEventManager(field).addDecorations(message);
- },
-
/**
* Passed the JSON content of a Tapestry partial markup response, extracts
* the script and stylesheet information. JavaScript libraries and stylesheets are loaded,
@@ -216,62 +231,6 @@
Tapestry.onDomLoadedCallback();
},
- // Adds a validator for a field. A FieldEventManager is added, if necessary.
- // The validator will be called only for non-blank values, unless acceptBlank is
- // true (in most cases, acceptBlank is flase). The validator is a function
- // that accepts the current field value as its first parameter, and a
- // Tapestry.FormEvent as its second. It can invoke recordError() on the event
- // if the input is not valid.
-
- addValidator : function(field, acceptBlank, validator)
- {
- this.getFieldEventManager(field).addValidator(acceptBlank, validator);
- },
-
- getFieldEventManager : function(field)
- {
- field = $(field);
-
- var manager = field.fieldEventManager;
-
- if (manager == undefined) manager = new Tapestry.FieldEventManager(field);
-
- return manager;
- },
-
- /**
- * Used with validation to see if an element is visible: i.e., it and all of its containers, up to the
- * containing form, are all visible. Only deeply visible elements are subject to validation.
- */
- isDeepVisible : function(element)
- {
- // This started as a recursively defined method attach to Element, but was converted
- // to a stand-alone as part of TAPESTRY-2424.
-
- var current = $(element);
-
- while (true)
- {
- if (! current.visible()) return false;
-
- if (current.tagName == "FORM") break;
-
- current = $(current.parentNode)
- }
-
- return true;
- },
-
- /** Focuses on a field, selecting its text. */
- focus : function (field)
- {
- field = $(field);
-
- if (field.focus) field.focus();
-
- if (field.select) field.select();
- },
-
/**
* Default function for handling Ajax-related failures.
*/
@@ -346,6 +305,152 @@
};
+Element.addMethods(
+{
+
+ /**
+ * Works upward from the element, checking to see if the element is visible. Returns false
+ * if it finds an invisible container. Returns true if it makes it as far as a (visible) FORM element.
+ *
+ * Note that this only applies to the CSS definition of visible; it doesn't check that the element
+ * is scolled into view.
+ *
+ * @param element to search up from
+ * @return true if visible (and containers visible), false if it or container are not visible
+ */
+ isDeepVisible : function(element)
+ {
+ var current = $(element);
+
+ while (true)
+ {
+ if (! current.visible()) return false;
+
+ if (current.tagName == "FORM") break;
+
+ current = $(current.parentNode)
+ }
+
+ return true;
+ }
+});
+
+Element.addMethods('FORM',
+{
+ /**
+ * Gets or creates the Tapestry.FormEventManager for the form.
+ *
+ * @param form form element
+ */
+ getFormEventManager : function(form)
+ {
+ var manager = form.eventManager;
+
+ if (manager == undefined)
+ manager = new Tapestry.FormEventManager(form);
+
+ return manager;
+ }
+});
+
+Element.addMethods(['INPUT', 'SELECT', 'TEXTAREA'],
+{
+ /**
+ * Invoked on a form element (INPUT, SELECT, etc.), gets or creates the
+ * Tapestry.FieldEventManager for that field.
+ *
+ * @param field field element
+ */
+ getFieldEventManager : function(field)
+ {
+ field = $(field);
+
+ var manager = field.fieldEventManager;
+
+ if (manager == undefined) manager = new Tapestry.FieldEventManager(field);
+
+ return manager;
+ },
+
+ /**
+ * Obtains the Tapestry.FieldEventManager and asks it to show
+ * the validation message. Sets the element's validationError property to true.
+ * @param element
+ * @param message to display
+ */
+ showValidationMessage : function(element, message)
+ {
+ element = $(element);
+
+ element.validationError = true;
+ element.form.validationError = true;
+
+ element.getFieldEventManager().showValidationMessage(message);
+
+ return element;
+ },
+
+ /**
+ * Removes any validation decorations on the field, and
+ * hides the error popup (if any) for the field.
+ */
+ removeDecorations : function(element)
+ {
+ $(element).getFieldEventManager().removeDecorations();
+
+ return element;
+ },
+
+ /** Utility method to add a validator function as an observer as an event.
+ *
+ * @param element element to observe events on
+ * @param eventName name of event to observe
+ * @param validator function passed the field's value
+ */
+ addValidatorAsObserver : function(element, eventName, validator)
+ {
+ element.observe(eventName, function(event)
+ {
+ try
+ {
+ validator.call(this, $F(element));
+ }
+ catch (message)
+ {
+ element.showValidationMessage(message);
+ }
+ });
+
+ return element;
+ },
+
+ /**
+ * Adds a standard validator for the element, an observer of
+ * Tapestry.FIELD_VALIDATE_EVENT. The validator function will be
+ * passed the current field value and should throw an error message if
+ * the field's value is not valid.
+ * @param element field element to validate
+ * @param validator function to be passed the field value
+ */
+ addValidator : function(element, validator)
+ {
+ return element.addValidatorAsObserver(Tapestry.FIELD_VALIDATE_EVENT, validator);
+ },
+
+ /**
+ * Adds a standard validator for the element, an observer of
+ * Tapestry.FIELD_FORMAT_EVENT. The validator function will be
+ * passed the current field value and should throw an error message if
+ * the field's value is not valid.
+ * @param element field element to validate
+ * @param validator function to be passed the field value
+ */
+ addFormatValidator : function(element, validator)
+ {
+ return element.addValidatorAsObserver(Tapestry.FIELD_FORMAT_EVENT, validator);
+ }
+});
+
/** Container of functions that may be invoked by the Tapestry.init() function. */
Tapestry.Initializer = {
@@ -425,7 +530,7 @@
{
// Turn normal form submission off.
- Tapestry.getFormEventManager(element).preventSubmission = true;
+ element.getFormEventManager().preventSubmission = true;
// After the form is validated and prepared, this code will
// process the form submission via an Ajax call. The original submit event
@@ -441,21 +546,22 @@
// Otherwise, assume it's just an ordinary link.
- var handler = function(event)
+ element.observe("click", function(event)
{
Tapestry.ajaxRequest(element.href, successHandler);
Event.stop(event);
- };
-
- element.observe("click", handler);
+ });
},
validate : function (field, specs)
{
field = $(field);
- Tapestry.getFormEventManager(field.form);
+ // Force the creation of the form and field event managers.
+
+ $(field.form).getFormEventManager();
+ $(field).getFieldEventManager();
specs.each(function(spec)
{
@@ -474,6 +580,10 @@
return;
}
+ // Pass the extend field, the provided message, and the constraint object
+ // to the Tapestry.Validator function, so that it can, typically, invoke
+ // field.addValidator().
+
vfunc.call(this, field, message, constraint);
});
},
@@ -524,25 +634,8 @@
}
};
-// New methods added to Element.
-
-Tapestry.ElementAdditions = {
- // This is added to all Elements, but really only applys to form control elements. This method is invoked
- // when a validation error is associated with a field. This gives the field a chance to decorate itself, its label
- // and its icon.
- decorateForValidationError : function(element, message)
- {
- Tapestry.getFieldEventManager(element).addDecorations(message);
- },
-
- removeDecorations : function(element)
- {
- Tapestry.getFieldEventManager(element).removeDecorations();
- }
-};
-
-Element.addMethods(Tapestry.ElementAdditions);
-
+// When FireBug is available, rewrite the error(), warn() and debug()
+// methods to make use of it.
if (window.console)
{
var createlog = function (log)
@@ -563,50 +656,69 @@
// Collection of field based functions related to validation. Each
// function takes a field, a message and an optional constraint value.
+// Some functions are related to Translators and work on the format event,
+// other's are from Validators and work on the validate event.
Tapestry.Validator = {
+
+ INT_REGEXP : /^(\+|-)?\d+$/,
+
+ FLOAT_REGEXP : /^(\+|-)?((\.\d+)|(\d+(\.\d*)?))$/,
+
required : function(field, message)
{
- Tapestry.addValidator(field, true, function(value, event)
+ field.addFormatValidator(function(value)
{
- if (value.strip() == '')
- event.recordError(message);
+ if (value.strip() == '') throw message;
+ });
+ },
+
+ /** Validate that the input is a numeric integer. */
+ integernumber : function(field, message)
+ {
+ field.addFormatValidator(function(value)
+ {
+ if (value != '' && ! value.match(Tapestry.Validator.INT_REGEXP)) throw message;
+ });
+ },
+
+ decimalnumber : function(field, message)
+ {
+ field.addFormatValidator(function(value)
+ {
+ if (value != '' && ! value.match(Tapestry.Validator.FLOAT_REGEXP)) throw message;
});
},
minlength : function(field, message, length)
{
- Tapestry.addValidator(field, false, function(value, event)
+ field.addValidator(function(value)
{
- if (value.length < length)
- event.recordError(message);
+ if (value.length < length) throw message;
});
},
maxlength : function(field, message, maxlength)
{
- Tapestry.addValidator(field, false, function(value, event)
+ field.addValidator(function(value)
{
- if (value.length > maxlength)
- event.recordError(message);
+ if (value.length > maxlength) throw message;
});
},
min : function(field, message, minValue)
{
- Tapestry.addValidator(field, false, function(value, event)
+ field.addValidator(function(value)
{
- if (value < minValue)
- event.recordError(message);
+ if (value < minValue) throw message;
});
},
max : function(field, message, maxValue)
{
- Tapestry.addValidator(field, false, function(value, event)
+ field.addValidator(function(value)
{
- if (value > maxValue)
- event.recordError(message);
+ if (value > maxValue) throw message;
});
},
@@ -614,46 +726,13 @@
{
var regexp = new RegExp(pattern);
- Tapestry.addValidator(field, false, function(value, event)
+ field.addValidator(function(value)
{
- if (! regexp.test(value))
- event.recordError(message);
+ if (! regexp.test(value)) throw message;
});
}
};
-
-// A Tapestry.FormEvent is used when the form sends presubmit and submit events to
-// a FieldEventManager. It allows the associated handlers to indirectly invoke
-// the Form's invalidField() method, and it tracks a result flag (true for success ==
-// no field errors, false if any field errors).
-
-Tapestry.FormEvent.prototype = {
-
- initialize : function(form)
- {
- this.form = $(form);
- this.result = true;
- },
-
- // Invoked by a validator function (which is passed the event) to record an error
- // for the associated field. The event knows the field and form and invoke's
- // the (added) form method invalidField(). Sets the event's result field to false
- // (i.e., don't allow the form to submit), and sets the event's error field to
- // true.
-
- recordError : function(message)
- {
- if (this.focusField == undefined)
- this.focusField = this.field;
-
- this.field.decorateForValidationError(message);
-
- this.result = false;
- this.error = true;
- }
-};
-
Tapestry.ErrorPopup.prototype = {
// If the images associated with the error popup are overridden (by overriding Tapestry's default.css stylesheet),
@@ -672,7 +751,9 @@
this.field = $(field);
this.innerSpan = new Element("span");
- this.outerDiv = $(new Element("div", { 'class' : 't-error-popup' })).update(this.innerSpan).hide();
+ this.outerDiv = $(new Element("div", {
+ 'id' : this.field.id + ":errorpopup",
+ 'class' : 't-error-popup' })).update(this.innerSpan).hide();
var body = $$('BODY').first();
@@ -688,7 +769,7 @@
this.outerDiv.hide();
- Tapestry.focus(this.field);
+ this.field.activate();
Event.stop(event); // Should be domevent.stop(), but that fails under IE
}.bindAsEventListener(this));
@@ -802,41 +883,46 @@
handleSubmit : function(domevent)
{
+ this.form.validationError = false;
+
+ var firstErrorField = null;
+
// Locate elements that have an event manager (and therefore, validations)
// and let those validations execute, which may result in calls to recordError().
- var event = new Tapestry.FormEvent(this.form);
this.form.getElements().each(function(element)
{
if (element.fieldEventManager != undefined)
{
- event.field = element;
- element.fieldEventManager.validateInput(event);
+ // Ask the FEM to validate input for the field, which fires
+ // a number of events.
+ var error = element.fieldEventManager.validateInput();
- if (event.abort) throw $break;
+ if (error && ! firstErrorField)
+ {
+ firstErrorField = element;
+ }
}
});
// Allow observers to validate the form as a whole. The FormEvent will be visible
// as event.memo. The Form will not be submitted if event.result is set to false (it defaults
- // to true).
+ // to true). Still trying to figure out what should get focus from this
+ // kind of event.
- this.form.fire(Tapestry.FORM_VALIDATE_EVENT, event);
+ this.form.fire(Tapestry.FORM_VALIDATE_EVENT, this.form);
- if (! event.result)
+ if (this.form.validationError)
{
- // Calling focus() does not trigger this event, so we do it manually.
- // Defer it long enough for the animations to start.
-
- event.focusField.activate();
-
Event.stop(domevent); // Should be domevent.stop(), but that fails under IE
+ if (firstErrorField) firstErrorField.activate();
+
return;
}
- this.form.fire(Tapestry.FORM_PREPARE_FOR_SUBMIT_EVENT);
+ this.form.fire(Tapestry.FORM_PREPARE_FOR_SUBMIT_EVENT, this.form);
// This flag can be set to prevent the form from submitting normally.
// This is used for some Ajax cases where the form submission must
@@ -862,42 +948,22 @@
initialize : function(field)
{
this.field = $(field);
+ this.field.fieldEventManager = this;
- field.fieldEventManager = this;
-
- this.validators = [ ];
-
- var id = field.id;
+ var id = this.field.id;
this.label = $(id + ':label');
this.icon = $(id + ':icon');
this.field.observe("blur", function()
{
- var event = new Tapestry.FormEvent(this.field.form);
-
- // This prevents the field from taking focus if there is an error.
- event.focusField = this.field;
-
- event.field = this.field;
-
- this.validateInput(event);
+ this.validateInput(false);
}.bindAsEventListener(this));
},
- // Adds a validator. acceptBlank is true if the validator should be invoked regardless of
- // the value. Usually acceptBlank is false, meaning that the validator will be skipped if
- // the field's value is blank. The validator itself is a function that is passed the
- // field's value and the Tapestry.FormEvent object. When a validator invokes event.recordError(),
- // any subsequent validators for that field are skipped.
-
- addValidator : function(acceptBlank, validator)
- {
- this.validators.push([ acceptBlank, validator]);
- },
-
- // Removes decorations on the field and label (the "t-error" CSS class) and makes the icon
- // invisible. A field that has special decoration needs will override this method.
+ /** Removes validation decorations if present. Hides the ErrorPopup,
+ * if it exists.
+ */
removeDecorations : function()
{
this.field.removeClassName("t-error");
@@ -912,11 +978,14 @@
this.errorPopup.hide();
},
- // Adds decorations to the field (including label and icon if present).
- // event - the validation event
- // message - error message
- addDecorations : function(message)
+ /**
+ * Show a validation error message, which will add decorations to the
+ * field and it label, make the icon visible, and raise the
+ * field's Tapestry.ErrorPopup to show the message.
+ * @param message validation message to display
+ */
+ showValidationMessage : function(message)
{
this.field.addClassName("t-error");
@@ -935,40 +1004,41 @@
this.errorPopup.showMessage(message);
},
-
- // Invoked from the Form's onsubmit event handler. Gets the fields value and invokes
- // each validator (unless the value is blank) until a validator returns false. Validators
- // should not modify the field's value.
-
- validateInput : function(event)
+ /**
+ * Invoked when a form is submitted, or when leaving a field, to perform
+ * field validations. Field validations are skipped for disabled fields.
+ * If all validations are succesful, any decorations are removed. If any validation
+ * fails, an error popup is raised for the field, to display the validation
+ * error message.
+ *
+ * @return true if the field has a validation error
+ */
+ validateInput : function()
{
if (this.field.disabled) return;
- if (! Tapestry.isDeepVisible(this.field)) return;
+ if (! this.field.isDeepVisible()) return;
- var value = $F(event.field);
- var isBlank = (value == '');
+ this.field.validationError = false;
- event.error = false;
+ this.field.fire(Tapestry.FIELD_FORMAT_EVENT, this.field);
- this.validators.each(function(tuple)
+ // If Format went ok, perhaps do the other validations.
+
+ if (! this.field.validationError)
{
- var acceptBlank = tuple[0];
- var validator = tuple[1];
+ var value = $F(this.field);
- if (acceptBlank || !isBlank)
- {
+ if (value != '')
+ this.field.fire(Tapestry.FIELD_VALIDATE_EVENT, this.field);
+ }
- validator(value, event);
+ // Lastly, if no validation errors were found, remove the decorations.
- // event.error is set by Tapestry.FormEvent.recordError().
+ if (! this.field.validationError)
+ this.field.removeDecorations();
- if (event.error) throw $break;
- }
- });
-
- if (! event.error)
- this.removeDecorations();
+ return this.field.validationError;
}
};
@@ -1072,7 +1142,7 @@
// On a submission, if the fragment is not visible, then wipe out its
// form submission data, so that no processing or validation occurs on the server.
- if (! Tapestry.isDeepVisible(this.element))
+ if (! this.element.isDeepVisible())
this.hidden.value = "";
}.bind(this));
},
@@ -1116,7 +1186,6 @@
}
};
-
Tapestry.FormInjector.prototype = {
initialize: function(spec)
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/ClientFormatDemo.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/ClientFormatDemo.tml?rev=689238&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/ClientFormatDemo.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/ClientFormatDemo.tml Tue Aug 26 14:31:30 2008
@@ -0,0 +1,5 @@
+<html t:type="border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+ <t:beaneditform object="this"/>
+
+</html>
\ No newline at end of file
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/EventMethodTranslate.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/EventMethodTranslate.tml?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/EventMethodTranslate.tml (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/EventMethodTranslate.tml Tue Aug 26 14:31:30 2008
@@ -1,7 +1,7 @@
<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
<h1>Event Handler Method Translate</h1>
- <t:form>
+ <t:form clientvalidation="false">
<t:errors/>
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/NullStrategyDemo.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/NullStrategyDemo.tml?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/NullStrategyDemo.tml (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/NullStrategyDemo.tml Tue Aug 26 14:31:30 2008
@@ -8,6 +8,7 @@
<t:form>
+ <t:errors/>
<t:textfield t:id="number" nulls="zero"/>
<br/>
<input type="submit" value="Update"/>
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/FieldComponent.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/FieldComponent.java?rev=689238&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/FieldComponent.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/FieldComponent.java Tue Aug 26 14:31:30 2008
@@ -0,0 +1,25 @@
+// Copyright 2008 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.tapestry5;
+
+import org.apache.tapestry5.runtime.Component;
+
+/**
+ * Used in a few places where we need a mock for {@link org.apache.tapestry5.Field} and {@link
+ * org.apache.tapestry5.runtime.Component} simultanesouly.
+ */
+public interface FieldComponent extends Field, Component
+{
+}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/IntegrationTests.java Tue Aug 26 14:31:30 2008
@@ -340,7 +340,7 @@
clickAndWait(SUBMIT);
assertTextPresent("[false]");
- assertTextPresent("The input value 'foo' is not parseable as an integer value.");
+ assertTextPresent("You must provide an integer value for Hours.");
assertAttribute("//input[@id='hours']/@value", "foo");
@@ -2182,4 +2182,22 @@
start("BeanEditor BeanEditContext");
assertTextPresent("Bean class from context is: " + RegistrationData.class.getName());
}
+
+ /**
+ * TAPESTRY-2352
+ */
+ public void client_field_format_validation()
+ {
+ start("Client Format Validation");
+
+ type("amount", "abc");
+ type("quantity", "abc");
+
+ click(SUBMIT);
+
+ waitForCondition("selenium.browserbot.getCurrentWindow().document.getElementById('amount:errorpopup')", "5000");
+
+ assertText("//div[@id='amount:errorpopup']/span", "You must provide a numeric value for Amount.");
+ assertText("//div[@id='quantity:errorpopup']/span", "Provide quantity as a number.");
+ }
}
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ClientFormatDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ClientFormatDemo.java?rev=689238&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ClientFormatDemo.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ClientFormatDemo.java Tue Aug 26 14:31:30 2008
@@ -0,0 +1,32 @@
+// Copyright 2008 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.tapestry5.integration.app1.pages;
+
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.beaneditor.Validate;
+
+/**
+ * Demonstrates client-side field format validation.
+ */
+public class ClientFormatDemo
+{
+ @Property
+ @Validate("required,min=1")
+ private int quantity;
+
+ @Property
+ @Validate("required,min=0")
+ private float amount;
+}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Start.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Start.java?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Start.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Start.java Tue Aug 26 14:31:30 2008
@@ -62,6 +62,8 @@
private static final List<Item> ITEMS = CollectionFactory.newList(
+ new Item("ClientFormatDemo", "Client Format Validation", "Client-side input format validation"),
+
new Item("ShortGrid", "Short Grid",
"Grid where the number of claimed rows is less than the number of actual rows"),
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java Tue Aug 26 14:31:30 2008
@@ -48,7 +48,7 @@
* interface.
*/
@Target(
- { PARAMETER, FIELD })
+ {PARAMETER, FIELD})
@Retention(RUNTIME)
@Documented
public @interface Local
@@ -92,7 +92,7 @@
{
long elapsed = System.nanoTime() - startTime;
- log.info(String.format("Request time: %5.2f s -- %s", elapsed * 10E-9d, request.getPath()));
+ log.info(String.format("Request time: %5.2f s -- %s", elapsed * 10E-10d, request.getPath()));
}
}
};
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/bindings/BindingFactoryTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/bindings/BindingFactoryTest.java?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/bindings/BindingFactoryTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/bindings/BindingFactoryTest.java Tue Aug 26 14:31:30 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 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.
@@ -16,13 +16,13 @@
import org.apache.tapestry5.Binding;
import org.apache.tapestry5.ComponentResources;
-import org.apache.tapestry5.Translator;
+import org.apache.tapestry5.FieldTranslator;
import org.apache.tapestry5.internal.test.InternalBaseTestCase;
import org.apache.tapestry5.ioc.Location;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
import org.apache.tapestry5.ioc.internal.util.TapestryException;
import org.apache.tapestry5.services.BindingFactory;
-import org.apache.tapestry5.services.TranslatorSource;
+import org.apache.tapestry5.services.FieldTranslatorSource;
import org.testng.annotations.Test;
/**
@@ -65,15 +65,15 @@
@Test
public void translate_binding()
{
- Translator translator = mockTranslator();
- TranslatorSource source = newMock(TranslatorSource.class);
+ FieldTranslator translator = mockFieldTranslator();
+ FieldTranslatorSource source = newMock(FieldTranslatorSource.class);
ComponentResources resources = mockComponentResources();
Location l = mockLocation();
String description = "foo bar";
String expression = "mock";
- expect(source.get(expression)).andReturn(translator);
+ expect(source.createTranslator(resources, expression)).andReturn(translator);
replay();
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/bindings/ValidateBindingFactoryTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/bindings/ValidateBindingFactoryTest.java?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/bindings/ValidateBindingFactoryTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/bindings/ValidateBindingFactoryTest.java Tue Aug 26 14:31:30 2008
@@ -16,23 +16,18 @@
import org.apache.tapestry5.Binding;
import org.apache.tapestry5.ComponentResources;
-import org.apache.tapestry5.Field;
+import org.apache.tapestry5.FieldComponent;
import org.apache.tapestry5.FieldValidator;
+import org.apache.tapestry5.internal.test.InternalBaseTestCase;
import org.apache.tapestry5.ioc.Location;
import org.apache.tapestry5.ioc.internal.util.TapestryException;
import org.apache.tapestry5.runtime.Component;
import org.apache.tapestry5.services.BindingFactory;
import org.apache.tapestry5.services.FieldValidatorSource;
-import org.apache.tapestry5.test.TapestryTestCase;
import org.testng.annotations.Test;
-public class ValidateBindingFactoryTest extends TapestryTestCase
+public class ValidateBindingFactoryTest extends InternalBaseTestCase
{
- private interface FieldComponent extends Field, Component
- {
- }
-
- ;
@Test
public void not_a_field()
@@ -72,7 +67,7 @@
FieldValidatorSource source = mockFieldValidatorSource();
ComponentResources container = mockComponentResources();
ComponentResources component = mockComponentResources();
- FieldComponent instance = newMock(FieldComponent.class);
+ FieldComponent instance = mockFieldComponent();
Location l = mockLocation();
FieldValidator validator = mockFieldValidator();
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentDefaultProviderImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentDefaultProviderImplTest.java?rev=689238&r1=689237&r2=689238&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentDefaultProviderImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/ComponentDefaultProviderImplTest.java Tue Aug 26 14:31:30 2008
@@ -17,7 +17,7 @@
import org.apache.tapestry5.Binding;
import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.ComponentResources;
-import org.apache.tapestry5.Translator;
+import org.apache.tapestry5.FieldTranslator;
import org.apache.tapestry5.internal.test.InternalBaseTestCase;
import org.apache.tapestry5.ioc.Messages;
import org.apache.tapestry5.ioc.services.ClassPropertyAdapter;
@@ -26,7 +26,7 @@
import org.apache.tapestry5.runtime.Component;
import org.apache.tapestry5.services.BindingSource;
import org.apache.tapestry5.services.ComponentDefaultProvider;
-import org.apache.tapestry5.services.TranslatorSource;
+import org.apache.tapestry5.services.FieldTranslatorSource;
import org.testng.annotations.Test;
public class ComponentDefaultProviderImplTest extends InternalBaseTestCase
@@ -50,7 +50,7 @@
replay();
- ComponentDefaultProvider provider = new ComponentDefaultProviderImpl(null, null, null, null);
+ ComponentDefaultProvider provider = new ComponentDefaultProviderImpl(null, null, null, null, null);
assertSame(provider.defaultLabel(resources), message);
@@ -74,7 +74,7 @@
replay();
- ComponentDefaultProvider provider = new ComponentDefaultProviderImpl(null, null, null, null);
+ ComponentDefaultProvider provider = new ComponentDefaultProviderImpl(null, null, null, null, null);
assertEquals(provider.defaultLabel(resources), "My Field");
@@ -103,7 +103,7 @@
replay();
ComponentDefaultProvider source = new ComponentDefaultProviderImpl(access, bindingSource, null,
- null);
+ null, null);
assertNull(source.defaultBinding(parameterName, resources));
@@ -145,7 +145,7 @@
replay();
ComponentDefaultProvider source = new ComponentDefaultProviderImpl(access, bindingSource, null,
- null);
+ null, null);
assertSame(source.defaultBinding(parameterName, resources), binding);
@@ -155,14 +155,14 @@
@Test
public void default_translator_property_type_is_null()
{
- TranslatorSource source = mockTranslatorSource();
ComponentResources resources = mockComponentResources();
+ FieldTranslatorSource source = newMock(FieldTranslatorSource.class);
- train_getBoundType(resources, "object", null);
+ train_createDefaultTranslator(source, resources, "object", null);
replay();
- ComponentDefaultProvider provider = new ComponentDefaultProviderImpl(null, null, null, source);
+ ComponentDefaultProvider provider = new ComponentDefaultProviderImpl(null, null, null, source, null);
assertNull(provider.defaultTranslator("object", resources));
@@ -172,21 +172,18 @@
@Test
public void default_translator()
{
- TranslatorSource source = mockTranslatorSource();
ComponentResources resources = mockComponentResources();
- Translator translator = mockTranslator();
+ FieldTranslator translator = mockFieldTranslator();
+ FieldTranslatorSource source = newMock(FieldTranslatorSource.class);
- train_getBoundType(resources, "object", Integer.class);
-
- expect(source.findByType(Integer.class)).andReturn(translator);
+ train_createDefaultTranslator(source, resources, "object", translator);
replay();
- ComponentDefaultProvider provider = new ComponentDefaultProviderImpl(null, null, null, source);
+ ComponentDefaultProvider provider = new ComponentDefaultProviderImpl(null, null, null, source, null);
assertSame(provider.defaultTranslator("object", resources), translator);
verify();
}
-
}
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/FieldTranslatorSourceImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/FieldTranslatorSourceImplTest.java?rev=689238&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/FieldTranslatorSourceImplTest.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/internal/services/FieldTranslatorSourceImplTest.java Tue Aug 26 14:31:30 2008
@@ -0,0 +1,198 @@
+// Copyright 2008 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.tapestry5.internal.services;
+
+import org.apache.tapestry5.*;
+import org.apache.tapestry5.internal.test.InternalBaseTestCase;
+import org.apache.tapestry5.ioc.MessageFormatter;
+import org.apache.tapestry5.ioc.Messages;
+import org.apache.tapestry5.services.FieldTranslatorSource;
+import org.apache.tapestry5.services.FormSupport;
+import org.apache.tapestry5.services.TranslatorSource;
+import org.apache.tapestry5.services.ValidationMessagesSource;
+import org.testng.annotations.Test;
+
+import java.util.Locale;
+import java.util.Map;
+
+/**
+ * Fills in some gaps that are not currently tested by the integration tests.
+ */
+public class FieldTranslatorSourceImplTest extends InternalBaseTestCase
+{
+ @Test
+ public void create_default_property_type_null()
+ {
+ Field field = mockField();
+ Messages messages = mockMessages();
+ Locale locale = Locale.ENGLISH;
+
+ replay();
+
+ FieldTranslatorSource source = new FieldTranslatorSourceImpl(null, null, null);
+
+ assertNull(source.createDefaultTranslator(field, "override", messages, locale, null, null));
+
+ verify();
+ }
+
+ @Test
+ public void create_default_translator_not_found_for_type()
+ {
+ Field field = mockField();
+ Messages messages = mockMessages();
+ Locale locale = Locale.ENGLISH;
+ Class propertyType = Map.class;
+ TranslatorSource ts = mockTranslatorSource();
+
+ train_findByType(ts, propertyType, null);
+
+ replay();
+
+ FieldTranslatorSource source = new FieldTranslatorSourceImpl(ts, null, null);
+
+ assertNull(source.createDefaultTranslator(field, "override", messages, locale, propertyType, null));
+
+ verify();
+ }
+
+ @Test
+ public void create_default_translator_with_name()
+ {
+ Field field = mockField();
+ Messages messages = mockMessages();
+ Locale locale = Locale.ENGLISH;
+ Class propertyType = Map.class;
+ TranslatorSource ts = mockTranslatorSource();
+ ValidationMessagesSource vms = mockValidationMessagesSource();
+ FormSupport fs = mockFormSupport();
+ Translator translator = mockTranslator("maptrans", Map.class);
+ Messages validationMessages = mockMessages();
+ MessageFormatter formatter = mockMessageFormatter();
+ MarkupWriter writer = mockMarkupWriter();
+ String label = "Field Label";
+ String message = "Woops, did it again.";
+
+
+ train_findByType(ts, propertyType, translator);
+ train_contains(messages, "myfield-maptrans-message", false);
+ train_getValidationMessages(vms, locale, validationMessages);
+
+ train_getMessageKey(translator, "mykey");
+ train_getMessageFormatter(validationMessages, "mykey", formatter);
+ train_getLabel(field, label);
+ train_format(formatter, message, label);
+
+ translator.render(field, message, writer, fs);
+
+ replay();
+
+ FieldTranslatorSource source = new FieldTranslatorSourceImpl(ts, vms, fs);
+
+ FieldTranslator ft = source.createDefaultTranslator(field, "myfield", messages, locale, propertyType, null);
+
+ assertEquals(ft.getType(), Map.class);
+
+ ft.render(writer);
+
+ verify();
+ }
+
+ @Test
+ public void create_default_translator_with_override_message()
+ {
+ Field field = mockField();
+ Messages messages = mockMessages();
+ Locale locale = Locale.ENGLISH;
+ Class propertyType = Map.class;
+ TranslatorSource ts = mockTranslatorSource();
+ ValidationMessagesSource vms = mockValidationMessagesSource();
+ FormSupport fs = mockFormSupport();
+ Translator translator = mockTranslator("maptrans", Map.class);
+ MessageFormatter formatter = mockMessageFormatter();
+ MarkupWriter writer = mockMarkupWriter();
+ String label = "My Label";
+ String message = "Formatted Message";
+
+ train_findByType(ts, propertyType, translator);
+ train_contains(messages, "myfield-maptrans-message", true);
+ train_getMessageFormatter(messages, "myfield-maptrans-message", formatter);
+
+ train_getLabel(field, label);
+ train_format(formatter, message, label);
+
+ translator.render(field, message, writer, fs);
+
+ replay();
+
+ FieldTranslatorSource source = new FieldTranslatorSourceImpl(ts, vms, fs);
+
+ FieldTranslator ft = source.createDefaultTranslator(field, "myfield", messages, locale, propertyType, null);
+
+ assertEquals(ft.getType(), Map.class);
+
+ ft.render(writer);
+
+ verify();
+ }
+
+ @Test
+ public void create_translator_from_translator_name()
+ {
+ ComponentResources resources = mockComponentResources();
+ FieldComponent field = mockFieldComponent();
+ Messages messages = mockMessages();
+ Locale locale = Locale.ENGLISH;
+ TranslatorSource ts = mockTranslatorSource();
+ ValidationMessagesSource vms = mockValidationMessagesSource();
+ FormSupport fs = mockFormSupport();
+ Translator translator = mockTranslator("map", Map.class);
+ Messages validationMessages = mockMessages();
+ MessageFormatter formatter = mockMessageFormatter();
+ MarkupWriter writer = mockMarkupWriter();
+ String label = "My Label";
+ String message = "Formatted Message";
+
+ train_getComponent(resources, field);
+ train_getId(resources, "myfield");
+ train_getContainerMessages(resources, messages);
+ train_getLocale(resources, locale);
+
+ train_get(ts, "map", translator);
+ train_contains(messages, "myfield-map-message", false);
+ train_getValidationMessages(vms, locale, validationMessages);
+
+ train_getMessageKey(translator, "mykey");
+ train_getMessageFormatter(validationMessages, "mykey", formatter);
+
+
+ train_getLabel(field, label);
+ train_format(formatter, message, label);
+
+ translator.render(field, message, writer, fs);
+
+ replay();
+
+ FieldTranslatorSource source = new FieldTranslatorSourceImpl(ts, vms, fs);
+
+ FieldTranslator ft = source.createTranslator(resources, "map");
+
+ assertEquals(ft.getType(), Map.class);
+
+ ft.render(writer);
+
+ verify();
+ }
+}