You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by Igor Drobiazko <ig...@gmail.com> on 2010/10/21 10:37:35 UTC

Re: svn commit: r1025793 - in /tapestry/tapestry5/trunk/tapestry-core/src: main/java/org/apache/tapestry5/corelib/ main/java/org/apache/tapestry5/corelib/components/ main/java/org/apache/tapestry5/services/ main/resources/org/apache/tapestry5/ test/j

This change breaks the compatibility. The default binding prefix of
clientValidation parameter changed from PROP to LITERAL.

Again, it is not a big deal to fix it when upgrading to 5.2, but maybe there
is a way to keep the backward compatibility.

On Thu, Oct 21, 2010 at 1:46 AM, <hl...@apache.org> wrote:

> Author: hlship
> Date: Wed Oct 20 23:46:20 2010
> New Revision: 1025793
>
> URL: http://svn.apache.org/viewvc?rev=1025793&view=rev
> Log:
> TAP5-538: Allow client-side validation when focus lost on field ("blur"),
> when form submits, or not at all
>
> Added:
>
>  tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/ClientValidation.java
>   (with props)
> Modified:
>
>  tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Form.java
>
>  tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
>
>  tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js
>
>  tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditRemoveReorder.java
>
>  tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditorDemo.java
>
>  tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ValidBeanEditorDemo.java
>
> Added:
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/ClientValidation.java
> URL:
> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/ClientValidation.java?rev=1025793&view=auto
>
> ==============================================================================
> ---
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/ClientValidation.java
> (added)
> +++
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/ClientValidation.java
> Wed Oct 20 23:46:20 2010
> @@ -0,0 +1,41 @@
> +// Copyright 2010 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.corelib;
> +
> +/**
> + * Controls if and how client-side form input validation occurs. For
> compatibility with Tapestry 5.1,
> + * a coercion from "true" to {@link #BLUR} and from "false" to {@link
> #NONE} are added (though these
> + * may be removed some time after Tapestry 5.2).
> + *
> + * @since 5.2.2
> + */
> +public enum ClientValidation
> +{
> +    /**
> +     * Fields validate as the user tabs out of them ("onblur" client side
> event), as well as when the form submits. This
> +     * is the default behavior.
> +     */
> +    BLUR,
> +
> +    /**
> +     * Fields only validate when the form submits (validation errors will
> prevent the form from actually submitting).
> +     */
> +    SUBMIT,
> +
> +    /**
> +     * Client-side validation is disabled.
> +     */
> +    NONE;
> +}
>
> Propchange:
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/ClientValidation.java
>
> ------------------------------------------------------------------------------
>    svn:eol-style = native
>
> Modified:
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Form.java
> URL:
> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Form.java?rev=1025793&r1=1025792&r2=1025793&view=diff
>
> ==============================================================================
> ---
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Form.java
> (original)
> +++
> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Form.java
> Wed Oct 20 23:46:20 2010
> @@ -27,6 +27,7 @@ import org.apache.tapestry5.annotations.
>  import org.apache.tapestry5.annotations.OnEvent;
>  import org.apache.tapestry5.annotations.Parameter;
>  import org.apache.tapestry5.annotations.Persist;
> +import org.apache.tapestry5.corelib.ClientValidation;
>  import org.apache.tapestry5.corelib.internal.ComponentActionSink;
>  import org.apache.tapestry5.corelib.internal.FormSupportImpl;
>  import org.apache.tapestry5.corelib.internal.InternalFormSupport;
> @@ -46,6 +47,7 @@ import org.apache.tapestry5.ioc.internal
>  import org.apache.tapestry5.ioc.internal.util.TapestryException;
>  import org.apache.tapestry5.ioc.util.ExceptionUtils;
>  import org.apache.tapestry5.ioc.util.IdAllocator;
> +import org.apache.tapestry5.json.JSONObject;
>  import org.apache.tapestry5.runtime.Component;
>  import org.apache.tapestry5.services.ClientBehaviorSupport;
>  import org.apache.tapestry5.services.ClientDataEncoder;
> @@ -54,6 +56,7 @@ import org.apache.tapestry5.services.Env
>  import org.apache.tapestry5.services.FormSupport;
>  import org.apache.tapestry5.services.Heartbeat;
>  import org.apache.tapestry5.services.Request;
> +import org.apache.tapestry5.services.javascript.InitializationPriority;
>  import org.apache.tapestry5.services.javascript.JavaScriptSupport;
>  import org.slf4j.Logger;
>
> @@ -160,16 +163,11 @@ public class Form implements ClientEleme
>     private boolean clientLogicDefaultEnabled;
>
>     /**
> -     * If true (the default) then client validation is enabled for the
> form, and
> -     * the default set of JavaScript libraries
> -     * (Prototype, Scriptaculous and the Tapestry library) will be added
> to the
> -     * rendered page, and the form will
> -     * register itself for validation. This may be turned off when client
> -     * validation is not desired; for example, when
> -     * many validations are used that do not operate on the client side at
> all.
> +     * Controls when client validation occurs on the client, if at all.
> Defaults to {@link ClientValidation#BLUR}.
>      */
> -    @Parameter
> -    private boolean clientValidation = clientLogicDefaultEnabled;
> +    @Parameter(allowNull = false, defaultPrefix =
> BindingConstants.LITERAL)
> +    private ClientValidation clientValidation = clientLogicDefaultEnabled
> ? ClientValidation.BLUR
> +            : ClientValidation.NONE;
>
>     /**
>      * If true (the default), then the JavaScript will be added to position
> the
> @@ -383,6 +381,8 @@ public class Form implements ClientEleme
>
>         formSupport = createRenderTimeFormSupport(clientId, actionSink,
> allocator);
>
> +        addJavaScriptInitialization();
> +
>         if (zone != null)
>             linkFormToZone(link);
>
> @@ -412,7 +412,7 @@ public class Form implements ClientEleme
>
>         form = writer.element("form", "id", clientId, "method", "post",
> "action", actionURL);
>
> -        if ((zone != null || clientValidation) && !request.isXHR())
> +        if ((zone != null || clientValidation != ClientValidation.NONE) &&
> !request.isXHR())
>             writer.attributes("onsubmit", MarkupConstants.WAIT_FOR_PAGE);
>
>         resources.renderInformalParameters(writer);
> @@ -432,6 +432,16 @@ public class Form implements ClientEleme
>         environment.peek(Heartbeat.class).begin();
>     }
>
> +    private void addJavaScriptInitialization()
> +    {
> +        JSONObject validateSpec = new JSONObject().put("blur",
> clientValidation == ClientValidation.BLUR).put("submit",
> +                clientValidation != ClientValidation.NONE);
> +
> +        JSONObject spec = new JSONObject("formId",
> clientId).put("validate", validateSpec);
> +
> +        javascriptSupport.addInitializerCall(InitializationPriority.EARLY,
> "formEventManager", spec);
> +    }
> +
>     @HeartbeatDeferred
>     private void linkFormToZone(Link link)
>     {
> @@ -460,8 +470,8 @@ public class Form implements ClientEleme
>     InternalFormSupport createRenderTimeFormSupport(String clientId,
> ComponentActionSink actionSink,
>             IdAllocator allocator)
>     {
> -        return new FormSupportImpl(resources, clientId, actionSink,
> clientBehaviorSupport, clientValidation, allocator,
> -                validationId);
> +        return new FormSupportImpl(resources, clientId, actionSink,
> clientBehaviorSupport,
> +                clientValidation != ClientValidation.NONE, allocator,
> validationId);
>     }
>
>     void afterRender(MarkupWriter writer)
>
> 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=1025793&r1=1025792&r2=1025793&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
> Wed Oct 20 23:46:20 2010
> @@ -40,6 +40,7 @@ import org.apache.tapestry5.ajax.MultiZo
>  import org.apache.tapestry5.annotations.*;
>  import org.apache.tapestry5.annotations.ContentType;
>  import org.apache.tapestry5.beaneditor.Validate;
> +import org.apache.tapestry5.corelib.ClientValidation;
>  import org.apache.tapestry5.corelib.LoopFormState;
>  import org.apache.tapestry5.corelib.SubmitMode;
>  import org.apache.tapestry5.corelib.data.BlankOption;
> @@ -1217,8 +1218,18 @@ public final class TapestryModule
>                 return calendar;
>             }
>         }));
> +
> +        // Add support for "true" and "false", for compatibility with
> Tapestry 5.1 and earlier.
> +        // These aliases may be removed in some later release.
> +
> +        StringToEnumCoercion<ClientValidation>
> stringToClientValidationCoercion = StringToEnumCoercion
> +                .create(ClientValidation.class).addAlias("true",
> ClientValidation.BLUR)
> +                .addAlias("false", ClientValidation.NONE);
> +
> +        configuration.add(CoercionTuple.create(String.class,
> ClientValidation.class, stringToClientValidationCoercion));
>     }
>
> +    @SuppressWarnings("rawtypes")
>     private static <T extends Enum> void add(Configuration<CoercionTuple>
> configuration, Class<T> enumType)
>     {
>         configuration.add(CoercionTuple.create(String.class, enumType,
> StringToEnumCoercion.create(enumType)));
>
> 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=1025793&r1=1025792&r2=1025793&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
> Wed Oct 20 23:46:20 2010
> @@ -1,16 +1,17 @@
> -// Copyright 2007, 2008, 2009, 2010 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.
> +/* Copyright 2007, 2008, 2009, 2010 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.
> + */
>
>  var Tapestry = {
>
> @@ -745,100 +746,115 @@ Element.addMethods( {
>        }
>  });
>
> -Element.addMethods('FORM', {
> -       /**
> -        * Gets or creates the Tapestry.FormEventManager for the form.
> -        *
> -        * @param form
> -        *            form element
> -        */
> -       getFormEventManager : function(form) {
> -               form = $(form);
> -               var t = $T(form);
> +Element
> +               .addMethods(
> +                               'FORM',
> +                               {
> +                                       /**
> +                                        * Gets the
> Tapestry.FormEventManager for the form.
> +                                        *
> +                                        * @param form
> +                                        *            form element
> +                                        */
> +                                       getFormEventManager :
> function(form) {
> +                                               form = $(form);
>
> -               var manager = t.formEventManager;
> +                                               var manager =
> $T(form).formEventManager;
>
> -               if (manager == undefined) {
> -                       manager = new Tapestry.FormEventManager(form);
> -                       t.formEventManager = manager;
> -               }
> +                                               if (manager == undefined) {
>
> -               return manager;
> -       },
> +                                                       throw "No
> Tapestry.FormEventManager object has been created for form '#{id}'."
> +
> .interpolate(form);
> +                                               }
>
> -       /**
> -        * Identifies in the form what is the cause of the submission. The
> element's
> -        * id is stored into the t:submit hidden field (created as needed).
> -        *
> -        * @param form
> -        *            to update
> -        * @param element
> -        *            id or element that is the cause of the submit (a
> Submit or
> -        *            LinkSubmit)
> -        */
> -       setSubmittingElement : function(form, element) {
> -               form.getFormEventManager().setSubmittingElement(element);
> -       },
> -
> -       /** Turns off client validation for the next submission of the
> form. */
> -       skipValidation : function(form) {
> -               $T(form).skipValidation = true;
> -       },
> -
> -       /**
> -        * Programmatically perform a submit, invling the onsubmit event
> handler (if
> -        * present) before calling form.submit().
> -        */
> -       performSubmit : function(form, event) {
> -               if (form.onsubmit == undefined
> -                               || form.onsubmit.call(window.document,
> event)) {
> -                       form.submit();
> -               }
> -       },
> +                                               return manager;
> +                                       },
>
> -       /**
> -        * Sends an Ajax request to the Form's action. This encapsulates a
> few
> -        * things, such as a default onFailure handler, and working around
> -        * bugs/features in Prototype concerning how submit buttons are
> processed.
> -        *
> -        * @param form
> -        *            used to define the data to be sent in the request
> -        * @param options
> -        *            standard Prototype Ajax Options
> -        * @return Ajax.Request the Ajax.Request created for the request
> -        */
> -       sendAjaxRequest : function(form, url, options) {
> -               form = $(form);
> +                                       /**
> +                                        * Identifies in the form what is
> the cause of the
> +                                        * submission. The element's id is
> stored into the t:submit
> +                                        * hidden field (created as
> needed).
> +                                        *
> +                                        * @param form
> +                                        *            to update
> +                                        * @param element
> +                                        *            id or element that is
> the cause of the submit
> +                                        *            (a Submit or
> LinkSubmit)
> +                                        */
> +                                       setSubmittingElement :
> function(form, element) {
> +                                               form.getFormEventManager()
> +
> .setSubmittingElement(element);
> +                                       },
>
> -               /*
> -                * Generally, options should not be null or missing,
> because otherwise
> -                * there's no way to provide any callbacks!
> -                */
> -               options = Object.clone(options || {});
> +                                       /**
> +                                        * Turns off client validation for
> the next submission of
> +                                        * the form.
> +                                        */
> +                                       skipValidation : function(form) {
> +                                               $T(form).skipValidation =
> true;
> +                                       },
>
> -               /*
> -                * Find the elements, skipping over any submit buttons.
> This works
> -                * around bugs in Prototype 1.6.0.2.
> -                */
> -               var elements = form.getElements().reject(function(e) {
> -                       return e.tagName == "INPUT" && e.type == "submit";
> -               });
> +                                       /**
> +                                        * Programmatically perform a
> submit, invoking the onsubmit
> +                                        * event handler (if present)
> before calling form.submit().
> +                                        */
> +                                       performSubmit : function(form,
> event) {
> +                                               if (form.onsubmit ==
> undefined
> +                                                               ||
> form.onsubmit.call(window.document, event)) {
> +                                                       form.submit();
> +                                               }
> +                                       },
>
> -               var hash = Form.serializeElements(elements, true);
> +                                       /**
> +                                        * Sends an Ajax request to the
> Form's action. This
> +                                        * encapsulates a few things, such
> as a default onFailure
> +                                        * handler, and working around
> bugs/features in Prototype
> +                                        * concerning how submit buttons
> are processed.
> +                                        *
> +                                        * @param form
> +                                        *            used to define the
> data to be sent in the
> +                                        *            request
> +                                        * @param options
> +                                        *            standard Prototype
> Ajax Options
> +                                        * @return Ajax.Request the
> Ajax.Request created for the
> +                                        *         request
> +                                        */
> +                                       sendAjaxRequest : function(form,
> url, options) {
> +                                               form = $(form);
>
> -               /*
> -                * Copy the parameters in, overwriting field values,
> because Prototype
> -                * 1.6.0.2 does not.
> -                */
> -               Object.extend(hash, options.parameters);
> +                                               /*
> +                                                * Generally, options
> should not be null or missing,
> +                                                * because otherwise
> there's no way to provide any
> +                                                * callbacks!
> +                                                */
> +                                               options =
> Object.clone(options || {});
> +
> +                                               /*
> +                                                * Find the elements,
> skipping over any submit buttons.
> +                                                * This works around bugs
> in Prototype 1.6.0.2.
> +                                                */
> +                                               var elements =
> form.getElements().reject(function(e) {
> +                                                       return e.tagName ==
> "INPUT" && e.type == "submit";
> +                                               });
>
> -               options.parameters = hash;
> +                                               var hash =
> Form.serializeElements(elements, true);
>
> -               /* Ajax.Request will convert the hash into a query string
> and post it. */
> +                                               /*
> +                                                * Copy the parameters in,
> overwriting field values,
> +                                                * because Prototype
> 1.6.0.2 does not.
> +                                                */
> +                                               Object.extend(hash,
> options.parameters);
> +
> +                                               options.parameters = hash;
> +
> +                                               /*
> +                                                * Ajax.Request will
> convert the hash into a query
> +                                                * string and post it.
> +                                                */
>
> -               return Tapestry.ajaxRequest(url, options);
> -       }
> -});
> +                                               return
> Tapestry.ajaxRequest(url, options);
> +                                       }
> +                               });
>
>  Element.addMethods( [ 'INPUT', 'SELECT', 'TEXTAREA' ], {
>        /**
> @@ -1055,7 +1071,6 @@ Tapestry.Initializer = {
>                if (element.tagName == "FORM") {
>
>                        // Create the FEM if necessary.
> -                       element.getFormEventManager();
>                        element.addClassName(Tapestry.PREVENT_SUBMISSION);
>
>                        /*
> @@ -1114,6 +1129,18 @@ Tapestry.Initializer = {
>        },
>
>        /**
> +        * Sets up a Tapestry.FormEventManager for the form, and enables
> events for
> +        * validations. This is executed with InitializationPriority.EARLY,
> to
> +        * ensure that the FormEventManager exists vefore any validations
> are added
> +        * for fields within the Form.
> +        *
> +        * @since 5.2.2
> +        */
> +       formEventManager : function(spec) {
> +               $T(spec.formId).formEventManager = new
> Tapestry.FormEventManager(spec);
> +       },
> +
> +       /**
>         * Keys in the masterSpec are ids of field control elements. Value
> is a list
>         * of validation specs. Each validation spec is a 2 or 3 element
> array.
>         */
> @@ -1125,11 +1152,9 @@ Tapestry.Initializer = {
>                                                        var field =
> $(pair.key);
>
>                                                        /*
> -                                                        * Force the
> creation of the form and field event
> -                                                        * managers.
> +                                                        * Force the
> creation of the field event manager.
>                                                         */
>
> -
> $(field.form).getFormEventManager();
>
>  $(field).getFieldEventManager();
>
>                                                        $A(pair.value)
> @@ -1203,8 +1228,6 @@ Tapestry.Initializer = {
>                var hidden = $(spec.element + "-hidden");
>                var form = $(hidden.form);
>
> -               form.getFormEventManager();
> -
>                function runAnimation(makeVisible) {
>                        var effect = makeVisible ?
> Tapestry.ElementEffect[spec.show]
>                                        || Tapestry.ElementEffect.slidedown
> @@ -1499,8 +1522,10 @@ Tapestry.ErrorPopup = Class.create( {
>
>  Tapestry.FormEventManager = Class.create( {
>
> -       initialize : function(form) {
> -               this.form = $(form);
> +       initialize : function(spec) {
> +               this.form = $(spec.formId);
> +               this.validateOnBlur = spec.validate.blur;
> +               this.validateOnSubmit = spec.validate.submit;
>
>                this.form.onsubmit =
> this.handleSubmit.bindAsEventListener(this);
>        },
> @@ -1629,20 +1654,27 @@ Tapestry.FieldEventManager = Class.creat
>
>                this.translator = Prototype.K;
>
> -               document.observe(Tapestry.FOCUS_CHANGE_EVENT,
> function(event) {
> -                       /*
> -                        * If changing focus *within the same form* then
> perform validation.
> -                        * Note that Tapestry.currentFocusField does not
> change until after
> -                        * the FOCUS_CHANGE_EVENT notification.
> -                        */
> -                       if (Tapestry.currentFocusField == this.field
> -                                       && this.field.form ==
> event.memo.form)
> -                               this.validateInput();
> +               var fem = $(this.field.form).getFormEventManager();
>
> -               }.bindAsEventListener(this));
> +               if (fem.validateOnBlur) {
> +
> +                       document.observe(Tapestry.FOCUS_CHANGE_EVENT,
> function(event) {
> +                               /*
> +                                * If changing focus *within the same form*
> then perform
> +                                * validation. Note that
> Tapestry.currentFocusField does not
> +                                * change until after the
> FOCUS_CHANGE_EVENT notification.
> +                                */
> +                               if (Tapestry.currentFocusField ==
> this.field
> +                                               && this.field.form ==
> event.memo.form)
> +                                       this.validateInput();
> +
> +                       }.bindAsEventListener(this));
> +               }
>
> -
> $(this.field.form).observe(Tapestry.FORM_VALIDATE_FIELDS_EVENT,
> -
> this.validateInput.bindAsEventListener(this));
> +               if (fem.validateOnSubmit) {
> +
> $(this.field.form).observe(Tapestry.FORM_VALIDATE_FIELDS_EVENT,
> +
> this.validateInput.bindAsEventListener(this));
> +               }
>        },
>
>        /**
>
> Modified:
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditRemoveReorder.java
> URL:
> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditRemoveReorder.java?rev=1025793&r1=1025792&r2=1025793&view=diff
>
> ==============================================================================
> ---
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditRemoveReorder.java
> (original)
> +++
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditRemoveReorder.java
> Wed Oct 20 23:46:20 2010
> @@ -1,10 +1,10 @@
> -// Copyright 2007 The Apache Software Foundation
> +// Copyright 2007, 2010 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
> +// 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,
> @@ -14,13 +14,15 @@
>
>  package org.apache.tapestry5.integration.app1.pages;
>
> +import org.apache.tapestry5.corelib.ClientValidation;
> +
>  public class BeanEditRemoveReorder extends BeanEditorDemo
>  {
>
>     @Override
> -    public boolean getClientValidation()
> +    public ClientValidation getClientValidation()
>     {
> -        return true;
> +        return ClientValidation.BLUR;
>     }
>
>     @Override
>
> Modified:
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditorDemo.java
> URL:
> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditorDemo.java?rev=1025793&r1=1025792&r2=1025793&view=diff
>
> ==============================================================================
> ---
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditorDemo.java
> (original)
> +++
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditorDemo.java
> Wed Oct 20 23:46:20 2010
> @@ -1,4 +1,4 @@
> -// Copyright 2007 The Apache Software Foundation
> +// Copyright 2007, 2010 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,6 +20,7 @@ import org.apache.tapestry5.annotations.
>  import org.apache.tapestry5.annotations.Persist;
>  import org.apache.tapestry5.annotations.Property;
>  import org.apache.tapestry5.beaneditor.Validate;
> +import org.apache.tapestry5.corelib.ClientValidation;
>  import org.apache.tapestry5.corelib.components.BeanEditForm;
>  import org.apache.tapestry5.integration.app1.data.RegistrationData;
>
> @@ -29,7 +30,7 @@ public class BeanEditorDemo
>     private String message;
>
>     @Component(id = "registrationData", parameters =
> -    { "clientValidation=clientValidation" })
> +    { "clientValidation=prop:clientValidation" })
>     private BeanEditForm form;
>
>     @ApplicationState
> @@ -51,9 +52,9 @@ public class BeanEditorDemo
>         form.clearErrors();
>     }
>
> -    public boolean getClientValidation()
> +    public ClientValidation getClientValidation()
>     {
> -        return false;
> +        return ClientValidation.NONE;
>     }
>
>     public String getPageTitle()
>
> Modified:
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ValidBeanEditorDemo.java
> URL:
> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ValidBeanEditorDemo.java?rev=1025793&r1=1025792&r2=1025793&view=diff
>
> ==============================================================================
> ---
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ValidBeanEditorDemo.java
> (original)
> +++
> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ValidBeanEditorDemo.java
> Wed Oct 20 23:46:20 2010
> @@ -14,13 +14,15 @@
>
>  package org.apache.tapestry5.integration.app1.pages;
>
> +import org.apache.tapestry5.corelib.ClientValidation;
> +
>  public class ValidBeanEditorDemo extends BeanEditorDemo
>  {
>
>     @Override
> -    public boolean getClientValidation()
> +    public ClientValidation getClientValidation()
>     {
> -        return true;
> +        return ClientValidation.BLUR;
>     }
>
>     @Override
> @@ -32,9 +34,9 @@ public class ValidBeanEditorDemo extends
>     Object onCanceledFromRegistrationData()
>     {
>         setMessage("Form was cancelled.");
> -
> +
>         clearErrors();
> -
> +
>         return this;
>     }
>  }
>
>
>


-- 
Best regards,

Igor Drobiazko
http://tapestry5.de

Re: svn commit: r1025793 - in /tapestry/tapestry5/trunk/tapestry-core/src: main/java/org/apache/tapestry5/corelib/ main/java/org/apache/tapestry5/corelib/components/ main/java/org/apache/tapestry5/services/ main/resources/org/apache/tapestry5/ test/j

Posted by Howard Lewis Ship <hl...@gmail.com>.
Yes, but what people would bind the clientvalidation parameter to
would be "true" or "false".  I set up a way to define aliases for
string --> enum coercions and aliased BLUR as "true" and NONE as
"false".  Therefore, unless the user was really binding the
clientvalidation parameter to an actual property (something I've only
done inside Tapestry internal tests), they will get the same behavior
in 5.2 and in 5.1.


On Thu, Oct 21, 2010 at 1:37 AM, Igor Drobiazko
<ig...@gmail.com> wrote:
> This change breaks the compatibility. The default binding prefix of
> clientValidation parameter changed from PROP to LITERAL.
>
> Again, it is not a big deal to fix it when upgrading to 5.2, but maybe there
> is a way to keep the backward compatibility.
>
> On Thu, Oct 21, 2010 at 1:46 AM, <hl...@apache.org> wrote:
>
>> Author: hlship
>> Date: Wed Oct 20 23:46:20 2010
>> New Revision: 1025793
>>
>> URL: http://svn.apache.org/viewvc?rev=1025793&view=rev
>> Log:
>> TAP5-538: Allow client-side validation when focus lost on field ("blur"),
>> when form submits, or not at all
>>
>> Added:
>>
>>  tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/ClientValidation.java
>>   (with props)
>> Modified:
>>
>>  tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Form.java
>>
>>  tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
>>
>>  tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js
>>
>>  tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditRemoveReorder.java
>>
>>  tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditorDemo.java
>>
>>  tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ValidBeanEditorDemo.java
>>
>> Added:
>> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/ClientValidation.java
>> URL:
>> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/ClientValidation.java?rev=1025793&view=auto
>>
>> ==============================================================================
>> ---
>> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/ClientValidation.java
>> (added)
>> +++
>> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/ClientValidation.java
>> Wed Oct 20 23:46:20 2010
>> @@ -0,0 +1,41 @@
>> +// Copyright 2010 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.corelib;
>> +
>> +/**
>> + * Controls if and how client-side form input validation occurs. For
>> compatibility with Tapestry 5.1,
>> + * a coercion from "true" to {@link #BLUR} and from "false" to {@link
>> #NONE} are added (though these
>> + * may be removed some time after Tapestry 5.2).
>> + *
>> + * @since 5.2.2
>> + */
>> +public enum ClientValidation
>> +{
>> +    /**
>> +     * Fields validate as the user tabs out of them ("onblur" client side
>> event), as well as when the form submits. This
>> +     * is the default behavior.
>> +     */
>> +    BLUR,
>> +
>> +    /**
>> +     * Fields only validate when the form submits (validation errors will
>> prevent the form from actually submitting).
>> +     */
>> +    SUBMIT,
>> +
>> +    /**
>> +     * Client-side validation is disabled.
>> +     */
>> +    NONE;
>> +}
>>
>> Propchange:
>> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/ClientValidation.java
>>
>> ------------------------------------------------------------------------------
>>    svn:eol-style = native
>>
>> Modified:
>> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Form.java
>> URL:
>> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Form.java?rev=1025793&r1=1025792&r2=1025793&view=diff
>>
>> ==============================================================================
>> ---
>> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Form.java
>> (original)
>> +++
>> tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Form.java
>> Wed Oct 20 23:46:20 2010
>> @@ -27,6 +27,7 @@ import org.apache.tapestry5.annotations.
>>  import org.apache.tapestry5.annotations.OnEvent;
>>  import org.apache.tapestry5.annotations.Parameter;
>>  import org.apache.tapestry5.annotations.Persist;
>> +import org.apache.tapestry5.corelib.ClientValidation;
>>  import org.apache.tapestry5.corelib.internal.ComponentActionSink;
>>  import org.apache.tapestry5.corelib.internal.FormSupportImpl;
>>  import org.apache.tapestry5.corelib.internal.InternalFormSupport;
>> @@ -46,6 +47,7 @@ import org.apache.tapestry5.ioc.internal
>>  import org.apache.tapestry5.ioc.internal.util.TapestryException;
>>  import org.apache.tapestry5.ioc.util.ExceptionUtils;
>>  import org.apache.tapestry5.ioc.util.IdAllocator;
>> +import org.apache.tapestry5.json.JSONObject;
>>  import org.apache.tapestry5.runtime.Component;
>>  import org.apache.tapestry5.services.ClientBehaviorSupport;
>>  import org.apache.tapestry5.services.ClientDataEncoder;
>> @@ -54,6 +56,7 @@ import org.apache.tapestry5.services.Env
>>  import org.apache.tapestry5.services.FormSupport;
>>  import org.apache.tapestry5.services.Heartbeat;
>>  import org.apache.tapestry5.services.Request;
>> +import org.apache.tapestry5.services.javascript.InitializationPriority;
>>  import org.apache.tapestry5.services.javascript.JavaScriptSupport;
>>  import org.slf4j.Logger;
>>
>> @@ -160,16 +163,11 @@ public class Form implements ClientEleme
>>     private boolean clientLogicDefaultEnabled;
>>
>>     /**
>> -     * If true (the default) then client validation is enabled for the
>> form, and
>> -     * the default set of JavaScript libraries
>> -     * (Prototype, Scriptaculous and the Tapestry library) will be added
>> to the
>> -     * rendered page, and the form will
>> -     * register itself for validation. This may be turned off when client
>> -     * validation is not desired; for example, when
>> -     * many validations are used that do not operate on the client side at
>> all.
>> +     * Controls when client validation occurs on the client, if at all.
>> Defaults to {@link ClientValidation#BLUR}.
>>      */
>> -    @Parameter
>> -    private boolean clientValidation = clientLogicDefaultEnabled;
>> +    @Parameter(allowNull = false, defaultPrefix =
>> BindingConstants.LITERAL)
>> +    private ClientValidation clientValidation = clientLogicDefaultEnabled
>> ? ClientValidation.BLUR
>> +            : ClientValidation.NONE;
>>
>>     /**
>>      * If true (the default), then the JavaScript will be added to position
>> the
>> @@ -383,6 +381,8 @@ public class Form implements ClientEleme
>>
>>         formSupport = createRenderTimeFormSupport(clientId, actionSink,
>> allocator);
>>
>> +        addJavaScriptInitialization();
>> +
>>         if (zone != null)
>>             linkFormToZone(link);
>>
>> @@ -412,7 +412,7 @@ public class Form implements ClientEleme
>>
>>         form = writer.element("form", "id", clientId, "method", "post",
>> "action", actionURL);
>>
>> -        if ((zone != null || clientValidation) && !request.isXHR())
>> +        if ((zone != null || clientValidation != ClientValidation.NONE) &&
>> !request.isXHR())
>>             writer.attributes("onsubmit", MarkupConstants.WAIT_FOR_PAGE);
>>
>>         resources.renderInformalParameters(writer);
>> @@ -432,6 +432,16 @@ public class Form implements ClientEleme
>>         environment.peek(Heartbeat.class).begin();
>>     }
>>
>> +    private void addJavaScriptInitialization()
>> +    {
>> +        JSONObject validateSpec = new JSONObject().put("blur",
>> clientValidation == ClientValidation.BLUR).put("submit",
>> +                clientValidation != ClientValidation.NONE);
>> +
>> +        JSONObject spec = new JSONObject("formId",
>> clientId).put("validate", validateSpec);
>> +
>> +        javascriptSupport.addInitializerCall(InitializationPriority.EARLY,
>> "formEventManager", spec);
>> +    }
>> +
>>     @HeartbeatDeferred
>>     private void linkFormToZone(Link link)
>>     {
>> @@ -460,8 +470,8 @@ public class Form implements ClientEleme
>>     InternalFormSupport createRenderTimeFormSupport(String clientId,
>> ComponentActionSink actionSink,
>>             IdAllocator allocator)
>>     {
>> -        return new FormSupportImpl(resources, clientId, actionSink,
>> clientBehaviorSupport, clientValidation, allocator,
>> -                validationId);
>> +        return new FormSupportImpl(resources, clientId, actionSink,
>> clientBehaviorSupport,
>> +                clientValidation != ClientValidation.NONE, allocator,
>> validationId);
>>     }
>>
>>     void afterRender(MarkupWriter writer)
>>
>> 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=1025793&r1=1025792&r2=1025793&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
>> Wed Oct 20 23:46:20 2010
>> @@ -40,6 +40,7 @@ import org.apache.tapestry5.ajax.MultiZo
>>  import org.apache.tapestry5.annotations.*;
>>  import org.apache.tapestry5.annotations.ContentType;
>>  import org.apache.tapestry5.beaneditor.Validate;
>> +import org.apache.tapestry5.corelib.ClientValidation;
>>  import org.apache.tapestry5.corelib.LoopFormState;
>>  import org.apache.tapestry5.corelib.SubmitMode;
>>  import org.apache.tapestry5.corelib.data.BlankOption;
>> @@ -1217,8 +1218,18 @@ public final class TapestryModule
>>                 return calendar;
>>             }
>>         }));
>> +
>> +        // Add support for "true" and "false", for compatibility with
>> Tapestry 5.1 and earlier.
>> +        // These aliases may be removed in some later release.
>> +
>> +        StringToEnumCoercion<ClientValidation>
>> stringToClientValidationCoercion = StringToEnumCoercion
>> +                .create(ClientValidation.class).addAlias("true",
>> ClientValidation.BLUR)
>> +                .addAlias("false", ClientValidation.NONE);
>> +
>> +        configuration.add(CoercionTuple.create(String.class,
>> ClientValidation.class, stringToClientValidationCoercion));
>>     }
>>
>> +    @SuppressWarnings("rawtypes")
>>     private static <T extends Enum> void add(Configuration<CoercionTuple>
>> configuration, Class<T> enumType)
>>     {
>>         configuration.add(CoercionTuple.create(String.class, enumType,
>> StringToEnumCoercion.create(enumType)));
>>
>> 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=1025793&r1=1025792&r2=1025793&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
>> Wed Oct 20 23:46:20 2010
>> @@ -1,16 +1,17 @@
>> -// Copyright 2007, 2008, 2009, 2010 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.
>> +/* Copyright 2007, 2008, 2009, 2010 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.
>> + */
>>
>>  var Tapestry = {
>>
>> @@ -745,100 +746,115 @@ Element.addMethods( {
>>        }
>>  });
>>
>> -Element.addMethods('FORM', {
>> -       /**
>> -        * Gets or creates the Tapestry.FormEventManager for the form.
>> -        *
>> -        * @param form
>> -        *            form element
>> -        */
>> -       getFormEventManager : function(form) {
>> -               form = $(form);
>> -               var t = $T(form);
>> +Element
>> +               .addMethods(
>> +                               'FORM',
>> +                               {
>> +                                       /**
>> +                                        * Gets the
>> Tapestry.FormEventManager for the form.
>> +                                        *
>> +                                        * @param form
>> +                                        *            form element
>> +                                        */
>> +                                       getFormEventManager :
>> function(form) {
>> +                                               form = $(form);
>>
>> -               var manager = t.formEventManager;
>> +                                               var manager =
>> $T(form).formEventManager;
>>
>> -               if (manager == undefined) {
>> -                       manager = new Tapestry.FormEventManager(form);
>> -                       t.formEventManager = manager;
>> -               }
>> +                                               if (manager == undefined) {
>>
>> -               return manager;
>> -       },
>> +                                                       throw "No
>> Tapestry.FormEventManager object has been created for form '#{id}'."
>> +
>> .interpolate(form);
>> +                                               }
>>
>> -       /**
>> -        * Identifies in the form what is the cause of the submission. The
>> element's
>> -        * id is stored into the t:submit hidden field (created as needed).
>> -        *
>> -        * @param form
>> -        *            to update
>> -        * @param element
>> -        *            id or element that is the cause of the submit (a
>> Submit or
>> -        *            LinkSubmit)
>> -        */
>> -       setSubmittingElement : function(form, element) {
>> -               form.getFormEventManager().setSubmittingElement(element);
>> -       },
>> -
>> -       /** Turns off client validation for the next submission of the
>> form. */
>> -       skipValidation : function(form) {
>> -               $T(form).skipValidation = true;
>> -       },
>> -
>> -       /**
>> -        * Programmatically perform a submit, invling the onsubmit event
>> handler (if
>> -        * present) before calling form.submit().
>> -        */
>> -       performSubmit : function(form, event) {
>> -               if (form.onsubmit == undefined
>> -                               || form.onsubmit.call(window.document,
>> event)) {
>> -                       form.submit();
>> -               }
>> -       },
>> +                                               return manager;
>> +                                       },
>>
>> -       /**
>> -        * Sends an Ajax request to the Form's action. This encapsulates a
>> few
>> -        * things, such as a default onFailure handler, and working around
>> -        * bugs/features in Prototype concerning how submit buttons are
>> processed.
>> -        *
>> -        * @param form
>> -        *            used to define the data to be sent in the request
>> -        * @param options
>> -        *            standard Prototype Ajax Options
>> -        * @return Ajax.Request the Ajax.Request created for the request
>> -        */
>> -       sendAjaxRequest : function(form, url, options) {
>> -               form = $(form);
>> +                                       /**
>> +                                        * Identifies in the form what is
>> the cause of the
>> +                                        * submission. The element's id is
>> stored into the t:submit
>> +                                        * hidden field (created as
>> needed).
>> +                                        *
>> +                                        * @param form
>> +                                        *            to update
>> +                                        * @param element
>> +                                        *            id or element that is
>> the cause of the submit
>> +                                        *            (a Submit or
>> LinkSubmit)
>> +                                        */
>> +                                       setSubmittingElement :
>> function(form, element) {
>> +                                               form.getFormEventManager()
>> +
>> .setSubmittingElement(element);
>> +                                       },
>>
>> -               /*
>> -                * Generally, options should not be null or missing,
>> because otherwise
>> -                * there's no way to provide any callbacks!
>> -                */
>> -               options = Object.clone(options || {});
>> +                                       /**
>> +                                        * Turns off client validation for
>> the next submission of
>> +                                        * the form.
>> +                                        */
>> +                                       skipValidation : function(form) {
>> +                                               $T(form).skipValidation =
>> true;
>> +                                       },
>>
>> -               /*
>> -                * Find the elements, skipping over any submit buttons.
>> This works
>> -                * around bugs in Prototype 1.6.0.2.
>> -                */
>> -               var elements = form.getElements().reject(function(e) {
>> -                       return e.tagName == "INPUT" && e.type == "submit";
>> -               });
>> +                                       /**
>> +                                        * Programmatically perform a
>> submit, invoking the onsubmit
>> +                                        * event handler (if present)
>> before calling form.submit().
>> +                                        */
>> +                                       performSubmit : function(form,
>> event) {
>> +                                               if (form.onsubmit ==
>> undefined
>> +                                                               ||
>> form.onsubmit.call(window.document, event)) {
>> +                                                       form.submit();
>> +                                               }
>> +                                       },
>>
>> -               var hash = Form.serializeElements(elements, true);
>> +                                       /**
>> +                                        * Sends an Ajax request to the
>> Form's action. This
>> +                                        * encapsulates a few things, such
>> as a default onFailure
>> +                                        * handler, and working around
>> bugs/features in Prototype
>> +                                        * concerning how submit buttons
>> are processed.
>> +                                        *
>> +                                        * @param form
>> +                                        *            used to define the
>> data to be sent in the
>> +                                        *            request
>> +                                        * @param options
>> +                                        *            standard Prototype
>> Ajax Options
>> +                                        * @return Ajax.Request the
>> Ajax.Request created for the
>> +                                        *         request
>> +                                        */
>> +                                       sendAjaxRequest : function(form,
>> url, options) {
>> +                                               form = $(form);
>>
>> -               /*
>> -                * Copy the parameters in, overwriting field values,
>> because Prototype
>> -                * 1.6.0.2 does not.
>> -                */
>> -               Object.extend(hash, options.parameters);
>> +                                               /*
>> +                                                * Generally, options
>> should not be null or missing,
>> +                                                * because otherwise
>> there's no way to provide any
>> +                                                * callbacks!
>> +                                                */
>> +                                               options =
>> Object.clone(options || {});
>> +
>> +                                               /*
>> +                                                * Find the elements,
>> skipping over any submit buttons.
>> +                                                * This works around bugs
>> in Prototype 1.6.0.2.
>> +                                                */
>> +                                               var elements =
>> form.getElements().reject(function(e) {
>> +                                                       return e.tagName ==
>> "INPUT" && e.type == "submit";
>> +                                               });
>>
>> -               options.parameters = hash;
>> +                                               var hash =
>> Form.serializeElements(elements, true);
>>
>> -               /* Ajax.Request will convert the hash into a query string
>> and post it. */
>> +                                               /*
>> +                                                * Copy the parameters in,
>> overwriting field values,
>> +                                                * because Prototype
>> 1.6.0.2 does not.
>> +                                                */
>> +                                               Object.extend(hash,
>> options.parameters);
>> +
>> +                                               options.parameters = hash;
>> +
>> +                                               /*
>> +                                                * Ajax.Request will
>> convert the hash into a query
>> +                                                * string and post it.
>> +                                                */
>>
>> -               return Tapestry.ajaxRequest(url, options);
>> -       }
>> -});
>> +                                               return
>> Tapestry.ajaxRequest(url, options);
>> +                                       }
>> +                               });
>>
>>  Element.addMethods( [ 'INPUT', 'SELECT', 'TEXTAREA' ], {
>>        /**
>> @@ -1055,7 +1071,6 @@ Tapestry.Initializer = {
>>                if (element.tagName == "FORM") {
>>
>>                        // Create the FEM if necessary.
>> -                       element.getFormEventManager();
>>                        element.addClassName(Tapestry.PREVENT_SUBMISSION);
>>
>>                        /*
>> @@ -1114,6 +1129,18 @@ Tapestry.Initializer = {
>>        },
>>
>>        /**
>> +        * Sets up a Tapestry.FormEventManager for the form, and enables
>> events for
>> +        * validations. This is executed with InitializationPriority.EARLY,
>> to
>> +        * ensure that the FormEventManager exists vefore any validations
>> are added
>> +        * for fields within the Form.
>> +        *
>> +        * @since 5.2.2
>> +        */
>> +       formEventManager : function(spec) {
>> +               $T(spec.formId).formEventManager = new
>> Tapestry.FormEventManager(spec);
>> +       },
>> +
>> +       /**
>>         * Keys in the masterSpec are ids of field control elements. Value
>> is a list
>>         * of validation specs. Each validation spec is a 2 or 3 element
>> array.
>>         */
>> @@ -1125,11 +1152,9 @@ Tapestry.Initializer = {
>>                                                        var field =
>> $(pair.key);
>>
>>                                                        /*
>> -                                                        * Force the
>> creation of the form and field event
>> -                                                        * managers.
>> +                                                        * Force the
>> creation of the field event manager.
>>                                                         */
>>
>> -
>> $(field.form).getFormEventManager();
>>
>>  $(field).getFieldEventManager();
>>
>>                                                        $A(pair.value)
>> @@ -1203,8 +1228,6 @@ Tapestry.Initializer = {
>>                var hidden = $(spec.element + "-hidden");
>>                var form = $(hidden.form);
>>
>> -               form.getFormEventManager();
>> -
>>                function runAnimation(makeVisible) {
>>                        var effect = makeVisible ?
>> Tapestry.ElementEffect[spec.show]
>>                                        || Tapestry.ElementEffect.slidedown
>> @@ -1499,8 +1522,10 @@ Tapestry.ErrorPopup = Class.create( {
>>
>>  Tapestry.FormEventManager = Class.create( {
>>
>> -       initialize : function(form) {
>> -               this.form = $(form);
>> +       initialize : function(spec) {
>> +               this.form = $(spec.formId);
>> +               this.validateOnBlur = spec.validate.blur;
>> +               this.validateOnSubmit = spec.validate.submit;
>>
>>                this.form.onsubmit =
>> this.handleSubmit.bindAsEventListener(this);
>>        },
>> @@ -1629,20 +1654,27 @@ Tapestry.FieldEventManager = Class.creat
>>
>>                this.translator = Prototype.K;
>>
>> -               document.observe(Tapestry.FOCUS_CHANGE_EVENT,
>> function(event) {
>> -                       /*
>> -                        * If changing focus *within the same form* then
>> perform validation.
>> -                        * Note that Tapestry.currentFocusField does not
>> change until after
>> -                        * the FOCUS_CHANGE_EVENT notification.
>> -                        */
>> -                       if (Tapestry.currentFocusField == this.field
>> -                                       && this.field.form ==
>> event.memo.form)
>> -                               this.validateInput();
>> +               var fem = $(this.field.form).getFormEventManager();
>>
>> -               }.bindAsEventListener(this));
>> +               if (fem.validateOnBlur) {
>> +
>> +                       document.observe(Tapestry.FOCUS_CHANGE_EVENT,
>> function(event) {
>> +                               /*
>> +                                * If changing focus *within the same form*
>> then perform
>> +                                * validation. Note that
>> Tapestry.currentFocusField does not
>> +                                * change until after the
>> FOCUS_CHANGE_EVENT notification.
>> +                                */
>> +                               if (Tapestry.currentFocusField ==
>> this.field
>> +                                               && this.field.form ==
>> event.memo.form)
>> +                                       this.validateInput();
>> +
>> +                       }.bindAsEventListener(this));
>> +               }
>>
>> -
>> $(this.field.form).observe(Tapestry.FORM_VALIDATE_FIELDS_EVENT,
>> -
>> this.validateInput.bindAsEventListener(this));
>> +               if (fem.validateOnSubmit) {
>> +
>> $(this.field.form).observe(Tapestry.FORM_VALIDATE_FIELDS_EVENT,
>> +
>> this.validateInput.bindAsEventListener(this));
>> +               }
>>        },
>>
>>        /**
>>
>> Modified:
>> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditRemoveReorder.java
>> URL:
>> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditRemoveReorder.java?rev=1025793&r1=1025792&r2=1025793&view=diff
>>
>> ==============================================================================
>> ---
>> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditRemoveReorder.java
>> (original)
>> +++
>> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditRemoveReorder.java
>> Wed Oct 20 23:46:20 2010
>> @@ -1,10 +1,10 @@
>> -// Copyright 2007 The Apache Software Foundation
>> +// Copyright 2007, 2010 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
>> +// 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,
>> @@ -14,13 +14,15 @@
>>
>>  package org.apache.tapestry5.integration.app1.pages;
>>
>> +import org.apache.tapestry5.corelib.ClientValidation;
>> +
>>  public class BeanEditRemoveReorder extends BeanEditorDemo
>>  {
>>
>>     @Override
>> -    public boolean getClientValidation()
>> +    public ClientValidation getClientValidation()
>>     {
>> -        return true;
>> +        return ClientValidation.BLUR;
>>     }
>>
>>     @Override
>>
>> Modified:
>> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditorDemo.java
>> URL:
>> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditorDemo.java?rev=1025793&r1=1025792&r2=1025793&view=diff
>>
>> ==============================================================================
>> ---
>> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditorDemo.java
>> (original)
>> +++
>> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/BeanEditorDemo.java
>> Wed Oct 20 23:46:20 2010
>> @@ -1,4 +1,4 @@
>> -// Copyright 2007 The Apache Software Foundation
>> +// Copyright 2007, 2010 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,6 +20,7 @@ import org.apache.tapestry5.annotations.
>>  import org.apache.tapestry5.annotations.Persist;
>>  import org.apache.tapestry5.annotations.Property;
>>  import org.apache.tapestry5.beaneditor.Validate;
>> +import org.apache.tapestry5.corelib.ClientValidation;
>>  import org.apache.tapestry5.corelib.components.BeanEditForm;
>>  import org.apache.tapestry5.integration.app1.data.RegistrationData;
>>
>> @@ -29,7 +30,7 @@ public class BeanEditorDemo
>>     private String message;
>>
>>     @Component(id = "registrationData", parameters =
>> -    { "clientValidation=clientValidation" })
>> +    { "clientValidation=prop:clientValidation" })
>>     private BeanEditForm form;
>>
>>     @ApplicationState
>> @@ -51,9 +52,9 @@ public class BeanEditorDemo
>>         form.clearErrors();
>>     }
>>
>> -    public boolean getClientValidation()
>> +    public ClientValidation getClientValidation()
>>     {
>> -        return false;
>> +        return ClientValidation.NONE;
>>     }
>>
>>     public String getPageTitle()
>>
>> Modified:
>> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ValidBeanEditorDemo.java
>> URL:
>> http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ValidBeanEditorDemo.java?rev=1025793&r1=1025792&r2=1025793&view=diff
>>
>> ==============================================================================
>> ---
>> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ValidBeanEditorDemo.java
>> (original)
>> +++
>> tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ValidBeanEditorDemo.java
>> Wed Oct 20 23:46:20 2010
>> @@ -14,13 +14,15 @@
>>
>>  package org.apache.tapestry5.integration.app1.pages;
>>
>> +import org.apache.tapestry5.corelib.ClientValidation;
>> +
>>  public class ValidBeanEditorDemo extends BeanEditorDemo
>>  {
>>
>>     @Override
>> -    public boolean getClientValidation()
>> +    public ClientValidation getClientValidation()
>>     {
>> -        return true;
>> +        return ClientValidation.BLUR;
>>     }
>>
>>     @Override
>> @@ -32,9 +34,9 @@ public class ValidBeanEditorDemo extends
>>     Object onCanceledFromRegistrationData()
>>     {
>>         setMessage("Form was cancelled.");
>> -
>> +
>>         clearErrors();
>> -
>> +
>>         return this;
>>     }
>>  }
>>
>>
>>
>
>
> --
> Best regards,
>
> Igor Drobiazko
> http://tapestry5.de
>



-- 
Howard M. Lewis Ship

Creator of Apache Tapestry

The source for Tapestry training, mentoring and support. Contact me to
learn how I can get you up and productive in Tapestry fast!

(971) 678-5210
http://howardlewisship.com

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tapestry.apache.org
For additional commands, e-mail: dev-help@tapestry.apache.org