Updated Branches: refs/heads/5.4-js-rewrite e067e5519 -> b70bcee47
Re-implement the client-side "required" validator Project: http://git-wip-us.apache.org/repos/asf/tapestry-5/repo Commit: http://git-wip-us.apache.org/repos/asf/tapestry-5/commit/b70bcee4 Tree: http://git-wip-us.apache.org/repos/asf/tapestry-5/tree/b70bcee4 Diff: http://git-wip-us.apache.org/repos/asf/tapestry-5/diff/b70bcee4 Branch: refs/heads/5.4-js-rewrite Commit: b70bcee47f1bf3beeae58b0c9e17352768fad29e Parents: e992792 Author: Howard M. Lewis Ship <hls...@apache.org> Authored: Thu Nov 1 16:35:09 2012 -0700 Committer: Howard M. Lewis Ship <hls...@apache.org> Committed: Thu Nov 1 16:35:09 2012 -0700 ---------------------------------------------------------------------- .../META-INF/modules/core/events.coffee | 50 ++++++++++++--- .../META-INF/modules/core/fields.coffee | 41 +++++++++++- .../META-INF/modules/core/forms.coffee | 9 ++- .../META-INF/modules/core/utils.coffee | 20 ++++++ .../META-INF/modules/core/validation.coffee | 30 +++++++++ .../translator/NumericTranslatorSupportImpl.java | 34 +++++----- .../org/apache/tapestry5/services/FormSupport.java | 31 ++++++--- .../apache/tapestry5/services/TapestryModule.java | 2 +- .../tapestry5/validator/AbstractValidator.java | 8 ++- .../java/org/apache/tapestry5/validator/Email.java | 4 +- .../java/org/apache/tapestry5/validator/Max.java | 4 +- .../org/apache/tapestry5/validator/MaxLength.java | 4 +- .../java/org/apache/tapestry5/validator/Min.java | 4 +- .../org/apache/tapestry5/validator/MinLength.java | 4 +- .../java/org/apache/tapestry5/validator/None.java | 4 +- .../org/apache/tapestry5/validator/Regexp.java | 4 +- .../org/apache/tapestry5/validator/Required.java | 18 ++++- .../apache/tapestry5/validator/RequiredTest.java | 16 +++--- 18 files changed, 215 insertions(+), 72 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b70bcee4/tapestry-core/src/main/coffeescript/META-INF/modules/core/events.coffee ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/coffeescript/META-INF/modules/core/events.coffee b/tapestry-core/src/main/coffeescript/META-INF/modules/core/events.coffee index 2a4b045..89b5290 100644 --- a/tapestry-core/src/main/coffeescript/META-INF/modules/core/events.coffee +++ b/tapestry-core/src/main/coffeescript/META-INF/modules/core/events.coffee @@ -27,18 +27,49 @@ define # Triggered after `validate` (when there are no prior validation exceptions), to allow certain elements # to configure themselves immediately before the form is submitted. This exists primarily for components such - # as FormFragment, which will update a enable or disable a hidden field to match the visibility of the fragment. - # The `core/spi.EventWrapper` for the form element is passed as the memo. + # as FormFragment, which will enable or disable a hidden field to match the visibility of the fragment. + # There is no event memo. prepareForSubmit: "t5:form:prepare-for-submit" + # Events releated to form input fields. Primarily, these events are related to form input validation. + # Validating a field involves three major steps: + # + # * optional - check for a required field that has no value + # * translate - translate a string to another representation, such as `Date`, or a number + # * validate - validate the field against any number of other constraints (such as ranges) + # + # The latter two steps occur only if the field's value is non-blank. A field that is blank but not + # required is considered valid. In each step, if the event listener detects an input validation error, + # it is expected to set the memo's `error`property to true _and_ trigger a `showValidationError' + # event (to present a message specific to the case). field: - # Triggered by the Form on all enclosed elements with the `data-validation` attribute (indicating they are - # interested in participating with user input validation). The memo object passed to the event has an error property - # that can be set to true to indicate a validation error. Individual fields should determine if the field is in - # error and remove or add/update decorations for the validation error (decorations will transition from 5.3 style - # popups to Twitter Bootstrap in the near future). + + # Perform the optionality check. The event memo includes a `value` property. If the field is required + # but the value is blank, then the `error` property should be set to true. + optional: "t5:field:optional" + + # Trigged by the field if there is a field value. The event memo includes the value as the `value` property. + # An event handler may update the event, setting the `translated` property to an alternate formatting, or + # alternate representation (e.g., `Date`, or a number) for the input value. If the input can not be translated, + # then the handler should set the memo's `error` property to true, and trigger a `showValidationError` event. + translate: "t5:field:translate" + + # Triggered by the field if there is a field value, and the `translate` event succeeded. The event memo + # includes a `value' property, and a `translated` property. If any constraints on the field are invalid, + # then the event handler should set the memo's `error` property and trigger a `showValidationError` event. validate: "t5:field:validate" + # Triggered by the form on all enclosed elements with the `data-validation` attribute (indicating they are + # interested in participating with user input validation). The default implementation fires a series of + # events: `optional`, `translate`, `validate`. The latter two are always skipped if the input is blank, or if + # a preceding event set the memo's `error` property to true. If all events complete without setting an error, + # then the `clearValidationError` event is triggered, so remove any validation errors from previous + # validation cycles. + # + # This event is passed a memo object; it should set the memo's `error` property to true if validation failed + # for the field. + inputValidation: "t5:field:input-validation" + # Clears and hides the element used to display validation error messages. There is no memo for # this event. The p.help-block for the field is located (if it exists) and empties and hidden. # The containing .control-group element (if it exists) has its "error" class name removed. @@ -50,13 +81,16 @@ define # then the class "error" will be added. # # The rules for locating the help block: + # # * Search for element with attribute `data-error-block-for` set to the field's `id` attribute # * If not found, find the enclosing .controls or .control-group element # * Search enclosing element for an element with attribute `data-presentation="error"` # * Otherwise, it is not found (but may be created dynamically) - # * If found, set the `data-error-block-for` attribute to the field's `id` (assigning the id if necesssary) + # * If found, set the `data-error-block-for` attribute to the field's `id` (assigning a unique id to the field + # if not already present) # # The rules for creating the help block: + # # * The element is created as `p.help-block` with `data-error-block-for` attribute set to the # field's id. The field will be assigned an id if necesary. # * Normally, the block is inserted after the field http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b70bcee4/tapestry-core/src/main/coffeescript/META-INF/modules/core/fields.coffee ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/coffeescript/META-INF/modules/core/fields.coffee b/tapestry-core/src/main/coffeescript/META-INF/modules/core/fields.coffee index d1cb3d2..141b6de 100644 --- a/tapestry-core/src/main/coffeescript/META-INF/modules/core/fields.coffee +++ b/tapestry-core/src/main/coffeescript/META-INF/modules/core/fields.coffee @@ -16,9 +16,8 @@ # # Module for logic relating to form input fields (input, select, textarea); specifically # presenting validation errors and perfoming input validation when necessary. - -define ["_", "core/events", "core/spi", "core/builder"], - (_, events, spi, builder) -> +define ["_", "core/events", "core/spi", "core/builder", "core/utils", "core/forms"], + (_, events, spi, builder, utils) -> ensureFieldId = (field) -> fieldId = field.attribute "id" @@ -93,6 +92,42 @@ define ["_", "core/events", "core/spi", "core/builder"], # Default registrations: + spi.onDocument events.field.inputValidation, (event, formMemo) -> + + # When not visible to the user, ignore the input validation. Components + # are generally configured so that they do not submit a value to the server + # when not visible ... this is what the core/FormFragment component is responsible + # for. + return unless this.deepVisible() + + failure = false + + memo = value: this.value() + + this.trigger events.field.optional, memo + + if memo.error + failure = true + else + unless utils.isBlank memo.value + this.trigger events.field.translate, memo + + if memo.error + failure = true + else + memo.translated |= memo.value + + this.trigger events.field.validate, memo + + failure |= memo.error + + if failure + formMemo.error = true + else + this.trigger events.field.clearValidationError + + return + spi.onDocument events.field.clearValidationError, -> block = exports.findHelpBlock this http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b70bcee4/tapestry-core/src/main/coffeescript/META-INF/modules/core/forms.coffee ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/coffeescript/META-INF/modules/core/forms.coffee b/tapestry-core/src/main/coffeescript/META-INF/modules/core/forms.coffee index e5e295a..e54cad4 100644 --- a/tapestry-core/src/main/coffeescript/META-INF/modules/core/forms.coffee +++ b/tapestry-core/src/main/coffeescript/META-INF/modules/core/forms.coffee @@ -104,22 +104,23 @@ define ["core/events", "core/spi", "core/builder", "_"], # This will become more relevant shortly, when field validation is modernized: for field in this.find "[data-validation]" - field.trigger events.field.validate, memo + field.trigger events.field.inputValidation, memo # Only do form validation if all individual field validation # was successful. - this.trigger events.form.validate, memo unless memo.error + unless memo.error + this.trigger events.form.validate, memo if memo.error clearSubmittingHidden this + # Cancel the original submit event when there's an error return false # Allow certain types of elements to do last-moment set up. Basically, this is for # FormFragment, or similar, to make their hidden field enabled or disabled to match # their UI's visible/hidden status. This is assumed to work or throw an exception; there # is no memo. - this.trigger events.form.prepareForSubmit, this - + this.trigger events.form.prepareForSubmit # Otherwise, the event is good, there are no validation problems, let the normal processing commence. # Possibly, the document event handler in core/zone will intercept form submission if this http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b70bcee4/tapestry-core/src/main/coffeescript/META-INF/modules/core/utils.coffee ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/coffeescript/META-INF/modules/core/utils.coffee b/tapestry-core/src/main/coffeescript/META-INF/modules/core/utils.coffee new file mode 100644 index 0000000..d4e9905 --- /dev/null +++ b/tapestry-core/src/main/coffeescript/META-INF/modules/core/utils.coffee @@ -0,0 +1,20 @@ +# Copyright 2012 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. + +## core/utils +# +# A few handy functions. +define [], -> + + isBlank: (input) -> input is null or input.trim().length == 0 \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b70bcee4/tapestry-core/src/main/coffeescript/META-INF/modules/core/validation.coffee ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/coffeescript/META-INF/modules/core/validation.coffee b/tapestry-core/src/main/coffeescript/META-INF/modules/core/validation.coffee new file mode 100644 index 0000000..3ff32a5 --- /dev/null +++ b/tapestry-core/src/main/coffeescript/META-INF/modules/core/validation.coffee @@ -0,0 +1,30 @@ +# Copyright 2012 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. + +## core/translator +# +# Support for Tapestry's built-in set of translators and validators. +# +define ["core/spi", "core/events", "core/utils", "core/fields"], + (spi, events, utils) -> + + spi.onDocument events.field.optional, "[data-optionality=required]", (event, memo) -> + + if utils.isBlank memo.value + message = (this.attribute "data-required-message") || "REQUIRED" + this.trigger events.field.showValidationError, { message } + memo.error = true + return false + + configureDecimals: -> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b70bcee4/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericTranslatorSupportImpl.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericTranslatorSupportImpl.java b/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericTranslatorSupportImpl.java index a704023..a8eb771 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericTranslatorSupportImpl.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/internal/translator/NumericTranslatorSupportImpl.java @@ -1,4 +1,4 @@ -// Copyright 2009, 2010 The Apache Software Foundation +// Copyright 2009, 2010, 2012 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,16 +14,6 @@ package org.apache.tapestry5.internal.translator; -import java.math.BigDecimal; -import java.math.BigInteger; -import java.text.DecimalFormat; -import java.text.DecimalFormatSymbols; -import java.text.NumberFormat; -import java.text.ParseException; -import java.util.Locale; -import java.util.Map; -import java.util.Set; - import org.apache.tapestry5.Field; import org.apache.tapestry5.SymbolConstants; import org.apache.tapestry5.ioc.annotations.Symbol; @@ -33,9 +23,18 @@ import org.apache.tapestry5.ioc.services.TypeCoercer; import org.apache.tapestry5.json.JSONObject; import org.apache.tapestry5.services.ClientBehaviorSupport; import org.apache.tapestry5.services.Request; -import org.apache.tapestry5.services.javascript.InitializationPriority; import org.apache.tapestry5.services.javascript.JavaScriptSupport; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; +import java.text.NumberFormat; +import java.text.ParseException; +import java.util.Locale; +import java.util.Map; +import java.util.Set; + public class NumericTranslatorSupportImpl implements NumericTranslatorSupport { private final TypeCoercer typeCoercer; @@ -57,9 +56,9 @@ public class NumericTranslatorSupportImpl implements NumericTranslatorSupport private static final String DECIMAL_FORMAT_SYMBOLS_PROVIDED = "tapestry.decimal-format-symbols-provided"; public NumericTranslatorSupportImpl(TypeCoercer typeCoercer, ThreadLocale threadLocale, Request request, - JavaScriptSupport javascriptSupport, ClientBehaviorSupport clientBehaviorSupport, - @Symbol(SymbolConstants.COMPACT_JSON) - boolean compactJSON) + JavaScriptSupport javascriptSupport, ClientBehaviorSupport clientBehaviorSupport, + @Symbol(SymbolConstants.COMPACT_JSON) + boolean compactJSON) { this.typeCoercer = typeCoercer; this.threadLocale = threadLocale; @@ -69,7 +68,7 @@ public class NumericTranslatorSupportImpl implements NumericTranslatorSupport this.compactJSON = compactJSON; Class[] integerTypes = - { Byte.class, Short.class, Integer.class, Long.class, BigInteger.class }; + {Byte.class, Short.class, Integer.class, Long.class, BigInteger.class}; for (Class c : integerTypes) this.integerTypes.add(c); @@ -80,8 +79,7 @@ public class NumericTranslatorSupportImpl implements NumericTranslatorSupport { if (request.getAttribute(DECIMAL_FORMAT_SYMBOLS_PROVIDED) == null) { - javascriptSupport.addScript(InitializationPriority.IMMEDIATE, "Tapestry.decimalFormatSymbols = %s;", - createJSONDecimalFormatSymbols().toString(compactJSON)); + javascriptSupport.require("core/validation").invoke("configureDecimals").with(createJSONDecimalFormatSymbols()); request.setAttribute(DECIMAL_FORMAT_SYMBOLS_PROVIDED, true); } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b70bcee4/tapestry-core/src/main/java/org/apache/tapestry5/services/FormSupport.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/FormSupport.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/FormSupport.java index 4e8e9f6..ccf029b 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/services/FormSupport.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/FormSupport.java @@ -29,7 +29,8 @@ public interface FormSupport extends ClientElement /** * Allocates a unique (within the form) control name for some enclosed component, based on the component's id. * - * @param id the component's id + * @param id + * the component's id * @return a unique string, usually the component's id, but sometime extended with a unique number or string */ String allocateControlName(String id); @@ -45,8 +46,10 @@ public interface FormSupport extends ClientElement * immediately. This is useful for defining an action that should occur symmetrically in both the render request and * the form submission's action request. * - * @param component component against which to trigger the action - * @param action the action that will be triggered (and passed the component) + * @param component + * component against which to trigger the action + * @param action + * the action that will be triggered (and passed the component) */ <T> void storeAndExecute(T component, ComponentAction<T> action); @@ -57,15 +60,18 @@ public interface FormSupport extends ClientElement * components can not be determined. During a form render, runnables are executed after the body of the form has * rendered. * - * @param command to be executed + * @param command + * to be executed */ void defer(Runnable command); /** * Sets the encoding type for the Form. This should only be set once, and if * - * @param encodingType MIME type indicating type of encoding for the form - * @throws IllegalStateException if the encoding type has already been set to a value different than the supplied + * @param encodingType + * MIME type indicating type of encoding for the form + * @throws IllegalStateException + * if the encoding type has already been set to a value different than the supplied */ void setEncodingType(String encodingType); @@ -73,10 +79,15 @@ public interface FormSupport extends ClientElement * Collects field validation information. A Form may turn off client-side validation, in which case these calls will * be ignored. * - * @param field for which validation is being generated - * @param validationName name of validation method (see Tapestry.Validation in tapestry.js) - * @param message the error message to display if the field is invalid - * @param constraint additional constraint value, or null for validations that don't require a constraint + * @param field + * for which validation is being generated + * @param validationName + * name of validation method (see Tapestry.Validation in tapestry.js) + * @param message + * the error message to display if the field is invalid + * @param constraint + * additional constraint value, or null for validations that don't require a constraint + * @deprecated Deprecated in 5.4 with no exact replacement */ void addValidation(Field field, String validationName, String message, Object constraint); http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b70bcee4/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java b/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java index d3eeb2c..6d5f82c 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java @@ -767,7 +767,7 @@ public final class TapestryModule */ public static void contributeFieldValidatorSource(MappedConfiguration<String, Validator> configuration) { - configuration.add("required", new Required()); + configuration.addInstance("required", Required.class); configuration.add("minlength", new MinLength()); configuration.add("maxlength", new MaxLength()); configuration.add("min", new Min()); http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b70bcee4/tapestry-core/src/main/java/org/apache/tapestry5/validator/AbstractValidator.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/validator/AbstractValidator.java b/tapestry-core/src/main/java/org/apache/tapestry5/validator/AbstractValidator.java index 28ae1cd..3c23fd2 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/validator/AbstractValidator.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/validator/AbstractValidator.java @@ -1,4 +1,4 @@ -// Copyright 2008 The Apache Software Foundation +// Copyright 2008, 2012 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. @@ -15,6 +15,7 @@ package org.apache.tapestry5.validator; import org.apache.tapestry5.Validator; +import org.apache.tapestry5.services.javascript.JavaScriptSupport; /** * Base class for constructing a {@link org.apache.tapestry5.Validator}. @@ -27,11 +28,14 @@ public abstract class AbstractValidator<C, T> implements Validator<C, T> private final String messageKey; - protected AbstractValidator(Class<C> constraintType, Class<T> valueType, String messageKey) + protected final JavaScriptSupport javaScriptSupport; + + protected AbstractValidator(Class<C> constraintType, Class<T> valueType, String messageKey, JavaScriptSupport javaScriptSupport) { this.constraintType = constraintType; this.valueType = valueType; this.messageKey = messageKey; + this.javaScriptSupport = javaScriptSupport; } public final Class<C> getConstraintType() http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b70bcee4/tapestry-core/src/main/java/org/apache/tapestry5/validator/Email.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/validator/Email.java b/tapestry-core/src/main/java/org/apache/tapestry5/validator/Email.java index 25d9698..c4bcb30 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/validator/Email.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/validator/Email.java @@ -1,4 +1,4 @@ -// Copyright 2008 The Apache Software Foundation +// Copyright 2008, 2012 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. @@ -38,7 +38,7 @@ public class Email extends AbstractValidator<Void, String> public Email() { - super(null, String.class, "invalid-email"); + super(null, String.class, "invalid-email", null); } public void render(Field field, Void constraintValue, MessageFormatter formatter, MarkupWriter markupWriter, http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b70bcee4/tapestry-core/src/main/java/org/apache/tapestry5/validator/Max.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/validator/Max.java b/tapestry-core/src/main/java/org/apache/tapestry5/validator/Max.java index c314c80..a07dac4 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/validator/Max.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/validator/Max.java @@ -1,4 +1,4 @@ -// Copyright 2007, 2008 The Apache Software Foundation +// Copyright 2007, 2008, 2012 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. @@ -27,7 +27,7 @@ public class Max extends AbstractValidator<Long, Number> { public Max() { - super(Long.class, Number.class, "max-integer"); + super(Long.class, Number.class, "max-integer", null); } public void validate(Field field, Long constraintValue, MessageFormatter formatter, Number value) http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b70bcee4/tapestry-core/src/main/java/org/apache/tapestry5/validator/MaxLength.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/validator/MaxLength.java b/tapestry-core/src/main/java/org/apache/tapestry5/validator/MaxLength.java index a44ecf6..44e4eae 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/validator/MaxLength.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/validator/MaxLength.java @@ -1,4 +1,4 @@ -// Copyright 2007, 2008 The Apache Software Foundation +// Copyright 2007, 2008, 2012 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. @@ -24,7 +24,7 @@ public final class MaxLength extends AbstractValidator<Integer, String> { public MaxLength() { - super(Integer.class, String.class, "maximum-string-length"); + super(Integer.class, String.class, "maximum-string-length", null); } public void validate(Field field, Integer constraintValue, MessageFormatter formatter, String value) http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b70bcee4/tapestry-core/src/main/java/org/apache/tapestry5/validator/Min.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/validator/Min.java b/tapestry-core/src/main/java/org/apache/tapestry5/validator/Min.java index 8ee7bb5..16b9b47 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/validator/Min.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/validator/Min.java @@ -1,4 +1,4 @@ -// Copyright 2007, 2008 The Apache Software Foundation +// Copyright 2007, 2008, 2012 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. @@ -25,7 +25,7 @@ public class Min extends AbstractValidator<Long, Number> { public Min() { - super(Long.class, Number.class, "min-integer"); + super(Long.class, Number.class, "min-integer", null); } public void validate(Field field, Long constraintValue, MessageFormatter formatter, Number value) http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b70bcee4/tapestry-core/src/main/java/org/apache/tapestry5/validator/MinLength.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/validator/MinLength.java b/tapestry-core/src/main/java/org/apache/tapestry5/validator/MinLength.java index c18a7cd..8ae6c3c 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/validator/MinLength.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/validator/MinLength.java @@ -1,4 +1,4 @@ -// Copyright 2007, 2008 The Apache Software Foundation +// Copyright 2007, 2008, 2012 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. @@ -27,7 +27,7 @@ public final class MinLength extends AbstractValidator<Integer, String> { public MinLength() { - super(Integer.class, String.class, "minimum-string-length"); + super(Integer.class, String.class, "minimum-string-length", null); } public void validate(Field field, Integer constraintValue, MessageFormatter formatter, String value) http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b70bcee4/tapestry-core/src/main/java/org/apache/tapestry5/validator/None.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/validator/None.java b/tapestry-core/src/main/java/org/apache/tapestry5/validator/None.java index d7f7c75..49644a3 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/validator/None.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/validator/None.java @@ -1,4 +1,4 @@ -// Copyright 2010 The Apache Software Foundation +// Copyright 2010, 2012 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. @@ -24,7 +24,7 @@ public class None extends AbstractValidator<Void, Object> { public None() { - super(null, Object.class, "required"); + super(null, Object.class, "required", null); } /** Does nothing. */ http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b70bcee4/tapestry-core/src/main/java/org/apache/tapestry5/validator/Regexp.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/validator/Regexp.java b/tapestry-core/src/main/java/org/apache/tapestry5/validator/Regexp.java index 495ad43..3d28d69 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/validator/Regexp.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/validator/Regexp.java @@ -1,4 +1,4 @@ -// Copyright 2007, 2008 The Apache Software Foundation +// Copyright 2007, 2008, 2012 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. @@ -27,7 +27,7 @@ public class Regexp extends AbstractValidator<Pattern, String> { public Regexp() { - super(Pattern.class, String.class, "regexp"); + super(Pattern.class, String.class, "regexp", null); } private String buildMessage(MessageFormatter formatter, Field field, Pattern constraintValue) http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b70bcee4/tapestry-core/src/main/java/org/apache/tapestry5/validator/Required.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/main/java/org/apache/tapestry5/validator/Required.java b/tapestry-core/src/main/java/org/apache/tapestry5/validator/Required.java index d21e5f6..bf1cd34 100644 --- a/tapestry-core/src/main/java/org/apache/tapestry5/validator/Required.java +++ b/tapestry-core/src/main/java/org/apache/tapestry5/validator/Required.java @@ -1,4 +1,4 @@ -// Copyright 2006, 2007, 2008 The Apache Software Foundation +// Copyright 2006, 2007, 2008, 2012 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. @@ -20,15 +20,16 @@ import org.apache.tapestry5.ValidationException; import org.apache.tapestry5.ioc.MessageFormatter; import org.apache.tapestry5.ioc.internal.util.InternalUtils; import org.apache.tapestry5.services.FormSupport; +import org.apache.tapestry5.services.javascript.JavaScriptSupport; /** * A validator that enforces that the value is not null and not the empty string. This validator is not configurable. */ public final class Required extends AbstractValidator<Void, Object> { - public Required() + public Required(JavaScriptSupport javaScriptSupport) { - super(null, Object.class, "required"); + super(null, Object.class, "required", javaScriptSupport); } public void validate(Field field, Void constraintValue, MessageFormatter formatter, Object value) @@ -54,6 +55,15 @@ public final class Required extends AbstractValidator<Void, Object> public void render(Field field, Void constraintValue, MessageFormatter formatter, MarkupWriter writer, FormSupport formSupport) { - formSupport.addValidation(field, "required", buildMessage(formatter, field), null); + + if (formSupport.isClientValidationEnabled()) + { + javaScriptSupport.require("core/validation"); + + writer.getElement().attributes( + "data-validation", "true", + "data-optionality", "required", + "data-required-message", buildMessage(formatter, field)); + } } } http://git-wip-us.apache.org/repos/asf/tapestry-5/blob/b70bcee4/tapestry-core/src/test/java/org/apache/tapestry5/validator/RequiredTest.java ---------------------------------------------------------------------- diff --git a/tapestry-core/src/test/java/org/apache/tapestry5/validator/RequiredTest.java b/tapestry-core/src/test/java/org/apache/tapestry5/validator/RequiredTest.java index ef337e5..7794a97 100644 --- a/tapestry-core/src/test/java/org/apache/tapestry5/validator/RequiredTest.java +++ b/tapestry-core/src/test/java/org/apache/tapestry5/validator/RequiredTest.java @@ -1,4 +1,4 @@ -// Copyright 2006, 2007 The Apache Software Foundation +// Copyright 2006, 2007, 2012 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,14 +14,14 @@ package org.apache.tapestry5.validator; -import java.util.Arrays; - import org.apache.tapestry5.Field; import org.apache.tapestry5.ValidationException; import org.apache.tapestry5.ioc.MessageFormatter; import org.apache.tapestry5.test.TapestryTestCase; import org.testng.annotations.Test; +import java.util.Arrays; + public class RequiredTest extends TapestryTestCase { @Test @@ -36,7 +36,7 @@ public class RequiredTest extends TapestryTestCase try { - new Required().validate(field, null, formatter, null); + new Required(null).validate(field, null, formatter, null); unreachable(); } catch (ValidationException ex) @@ -59,7 +59,7 @@ public class RequiredTest extends TapestryTestCase try { - new Required().validate(field, null, formatter, ""); + new Required(null).validate(field, null, formatter, ""); unreachable(); } catch (ValidationException ex) @@ -82,7 +82,7 @@ public class RequiredTest extends TapestryTestCase try { - new Required().validate(field, null, formatter, Arrays.asList()); + new Required(null).validate(field, null, formatter, Arrays.asList()); unreachable(); } catch (ValidationException ex) @@ -101,7 +101,7 @@ public class RequiredTest extends TapestryTestCase replay(); - new Required().validate(field, null, formatter, Arrays.asList("A", "B")); + new Required(null).validate(field, null, formatter, Arrays.asList("A", "B")); verify(); } @@ -114,7 +114,7 @@ public class RequiredTest extends TapestryTestCase replay(); - new Required().validate(field, null, formatter, "not null"); + new Required(null).validate(field, null, formatter, "not null"); verify(); }