Author: hlship
Date: Tue Jul 5 18:30:49 2011
New Revision: 1143161
URL: http://svn.apache.org/viewvc?rev=1143161&view=rev
Log:
TAP5-1451: Form component should indicate that a form submission was canceled
on the client side
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/EventConstants.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/SubmitMode.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditForm.java
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/corelib/components/LinkSubmit.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Submit.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalConstants.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/corelib/components/BeanEditForm.tml
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/corelib/components/SubmitTest.java
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/EventConstants.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/EventConstants.java?rev=1143161&r1=1143160&r2=1143161&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/EventConstants.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/EventConstants.java
Tue Jul 5 18:30:49 2011
@@ -48,14 +48,14 @@ public class EventConstants
/**
* Invoked before {@link #PREPARE} when rendering out the form.
- *
+ *
* @see org.apache.tapestry5.corelib.components.Form
*/
public static final String PREPARE_FOR_RENDER = "prepareForRender";
/**
* Invoked before {@link #PREPARE} when the form is submitted.
- *
+ *
* @see org.apache.tapestry5.corelib.components.Form
*/
public static final String PREPARE_FOR_SUBMIT = "prepareForSubmit";
@@ -63,7 +63,7 @@ public class EventConstants
/**
* Invoked to let the containing component(s) prepare for the form
rendering or the form
* submission.
- *
+ *
* @see org.apache.tapestry5.corelib.components.Form
*/
public static final String PREPARE = "prepare";
@@ -72,14 +72,17 @@ public class EventConstants
* Event type for a notification after the form has submitted. This event
notification occurs on
* any form submit,
* without respect to "success" or "failure".
- *
+ *
* @see org.apache.tapestry5.corelib.components.Form
*/
public static final String SUBMIT = "submit";
/**
- * Event type associated with clicking the cancel button inside a {@link
BeanEditForm}.
- *
+ * Event triggered when a client-side form is canceled. This occurs after
page activation, and after
+ * the prepare events for the form, but before any stored {@link
ComponentAction}s for the form are triggered.
+ *
+ * @see org.apache.tapestry5.corelib.SubmitMode#CANCEL
+ *
* @since 5.2.0
*/
public static final String CANCELED = "canceled";
@@ -88,7 +91,7 @@ public class EventConstants
* Event type for a notification after the form has submitted, when there
are no errors in the
* validation tracker.
* This occurs before the {@link #SUBMIT} event.
- *
+ *
* @see org.apache.tapestry5.corelib.components.Form
*/
public static final String SUCCESS = "success";
@@ -148,7 +151,7 @@ public class EventConstants
* all the values that were supplied from the client during a form
submission. The event handler
* method should have
* a single parameter, of type Object[] or type List, to receive the
values.
- *
+ *
* @since 5.1.0.0
*/
public static final String SYNCHRONIZE_VALUES = "synchronizeValues";
@@ -158,7 +161,7 @@ public class EventConstants
* container of what context (if any) is available. The event handler may
return a renderable
* object or null. If
* null is returned, the component renders its own body as the partial
markup response.
- *
+ *
* @since 5.1.0.1
*/
public static final String PROGRESSIVE_DISPLAY = "progressiveDisplay";
@@ -167,7 +170,7 @@ public class EventConstants
* Event triggered by an {@link
org.apache.tapestry5.corelib.mixins.Autocomplete} mixin to
* request completions of
* the current input. The context is the partial string provided by the
client.
- *
+ *
* @since 5.1.0.4
*/
public static final String PROVIDE_COMPLETIONS = "provideCompletions";
@@ -176,7 +179,7 @@ public class EventConstants
* Event triggered by {@link
org.apache.tapestry5.corelib.components.Select} component to inform
* its
* container that Select's value has changed.
- *
+ *
* @since 5.2.0
*/
public static final String VALUE_CHANGED = "valueChanged";
@@ -185,7 +188,7 @@ public class EventConstants
* Event triggered during page render link generation. The first context
parameter is the {@link Link} object, the
* second is the {@link PageRenderRequestParameters} from which the Link
* was created. The event is triggered on the actively rendering page.
- *
+ *
* @since 5.2.0
*/
public static final String DECORATE_PAGE_RENDER_LINK =
"decoratePageRenderLink";
@@ -195,7 +198,7 @@ public class EventConstants
* the second is the {@link ComponentEventRequestParameters} from which
the Link
* was created. The event is triggered on the actively rendering page, not
necessarily the page
* containing the component.
- *
+ *
* @since 5.2.0
*/
public static final String DECORATE_COMPONENT_EVENT_LINK =
"decorateComponentEventLink";
@@ -204,7 +207,7 @@ public class EventConstants
* Name of a event triggered by the form component on the {@linkplain
ComponentSource#getActivePage() active page}
* to allow it to pre-allocate the names of any query parameters that
might be used by the page for its own purposes
* and should not be allocated to components. An {@link IdAllocator} is
passed as the event context.
- *
+ *
* @since 5.2.0
*/
public static final String PREALLOCATE_FORM_CONTROL_NAMES =
"preallocateFormControlNames";
@@ -218,19 +221,18 @@ public class EventConstants
public static final String NODE_SELECTED = "nodeSelected";
/**
- * Event triggered by the {@link
org.apache.tapestry5.corelib.components.Tree}
- * component when a leaf node is unselected.
+ * Event triggered by the {@link
org.apache.tapestry5.corelib.components.Tree}
+ * component when a leaf node is unselected.
*
- * @since 5.3
+ * @since 5.3
*/
public static final String NODE_UNSELECTED = "nodeUnselected";
-
+
/**
- * Event triggered by {@link
org.apache.tapestry5.corelib.mixins.ZoneRefresh ZoneRefresh} to refresh the
+ * Event triggered by {@link
org.apache.tapestry5.corelib.mixins.ZoneRefresh ZoneRefresh} to refresh the
* {@link org.apache.tapestry5.corelib.components.Zone Zone}
- *
+ *
* @since 5.3
*/
- public static final String REFRESH = "refresh";
-
+ public static final String REFRESH = "refresh";
}
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/SubmitMode.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/SubmitMode.java?rev=1143161&r1=1143160&r2=1143161&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/SubmitMode.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/SubmitMode.java
Tue Jul 5 18:30:49 2011
@@ -1,4 +1,4 @@
-// Copyright 2010 The Apache Software Foundation
+// Copyright 2010, 2011 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,16 +20,19 @@ import org.apache.tapestry5.corelib.comp
/**
* Defines the client and server-side behavior of a {@link Submit} or {@link
LinkSubmit} component.
- *
+ *
* @since 5.2.0
*/
public enum SubmitMode
{
- /** Submit the form normally, with full validation on the client and
server side. */
+ /**
+ * Submit the form normally, with full validation on the client and server
side.
+ */
NORMAL,
/**
- * Cancel the form; bypass client-side form validation. Validation still
occurs
+ * Cancel the form; bypass client-side form validation. Fires the {@link
EventConstants#CANCELED} event.
+ * If the event handler for that event allows the submission to proceed,
then server-side validation still occurs
* on the server, though generally the data is discarded by the event
listener
* (listening to the Submit component's {@link EventConstants#SELECTED}
event).
*/
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditForm.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditForm.java?rev=1143161&r1=1143160&r2=1143161&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditForm.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/BeanEditForm.java
Tue Jul 5 18:30:49 2011
@@ -14,21 +14,8 @@
package org.apache.tapestry5.corelib.components;
-import java.io.IOException;
-
-import org.apache.tapestry5.BindingConstants;
-import org.apache.tapestry5.ClientElement;
-import org.apache.tapestry5.ComponentResources;
-import org.apache.tapestry5.EventConstants;
-import org.apache.tapestry5.Field;
-import org.apache.tapestry5.FormValidationControl;
-import org.apache.tapestry5.TrackableComponentEventCallback;
-import org.apache.tapestry5.annotations.Component;
-import org.apache.tapestry5.annotations.Environmental;
-import org.apache.tapestry5.annotations.Events;
-import org.apache.tapestry5.annotations.Parameter;
-import org.apache.tapestry5.annotations.Property;
-import org.apache.tapestry5.annotations.SupportsInformalParameters;
+import org.apache.tapestry5.*;
+import org.apache.tapestry5.annotations.*;
import org.apache.tapestry5.beaneditor.BeanModel;
import org.apache.tapestry5.internal.beaneditor.BeanModelUtils;
import org.apache.tapestry5.ioc.annotations.Inject;
@@ -49,12 +36,12 @@ import org.apache.tapestry5.services.Bea
* <p/>
* BeanEditForm contains a {@link
org.apache.tapestry5.corelib.components.Form} component and will trigger all the
* events of a Form.
- *
+ *
+ * @tapestrydoc
* @see org.apache.tapestry5.beaneditor.BeanModel
* @see org.apache.tapestry5.services.BeanModelSource
* @see org.apache.tapestry5.corelib.components.PropertyEditor
* @see org.apache.tapestry5.beaneditor.DataType
- * @tapestrydoc
* @see Form
* @see Errors
* @see BeanEditor
@@ -124,7 +111,7 @@ public class BeanEditForm implements Cli
* If set to true, then the form will include an additional button after
the submit button labeled "Cancel".
* The cancel button will submit the form, bypassing client-side
validation. The BeanEditForm will fire a
* {@link EventConstants#CANCELED} event (before the form's {@link
EventConstants#VALIDATE} event).
- *
+ *
* @since 5.2.0
*/
@Property
@@ -147,10 +134,6 @@ public class BeanEditForm implements Cli
@Inject
private BeanModelSource beanModelSource;
- @SuppressWarnings("unchecked")
- @Environmental
- private TrackableComponentEventCallback eventCallback;
-
boolean onPrepareFromForm()
{
resources.triggerEvent(EventConstants.PREPARE, null, null);
@@ -199,13 +182,4 @@ public class BeanEditForm implements Cli
{
form.recordError(errorMessage);
}
-
- boolean onSelectedFromCancel() throws IOException
- {
- resources.triggerEvent(EventConstants.CANCELED, null, eventCallback);
-
- // Prevent further event handlers.
-
- return true;
- }
}
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=1143161&r1=1143160&r2=1143161&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
Tue Jul 5 18:30:49 2011
@@ -14,48 +14,15 @@
package org.apache.tapestry5.corelib.components;
-import java.io.EOFException;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-
-import org.apache.tapestry5.BindingConstants;
-import org.apache.tapestry5.CSSClassConstants;
-import org.apache.tapestry5.ClientElement;
-import org.apache.tapestry5.ComponentAction;
-import org.apache.tapestry5.ComponentResources;
-import org.apache.tapestry5.EventConstants;
-import org.apache.tapestry5.EventContext;
-import org.apache.tapestry5.Field;
-import org.apache.tapestry5.FormValidationControl;
-import org.apache.tapestry5.Link;
-import org.apache.tapestry5.MarkupConstants;
-import org.apache.tapestry5.MarkupWriter;
-import org.apache.tapestry5.PersistenceConstants;
-import org.apache.tapestry5.SymbolConstants;
-import org.apache.tapestry5.TrackableComponentEventCallback;
-import org.apache.tapestry5.ValidationDecorator;
-import org.apache.tapestry5.ValidationException;
-import org.apache.tapestry5.ValidationTracker;
-import org.apache.tapestry5.ValidationTrackerImpl;
-import org.apache.tapestry5.ValidationTrackerWrapper;
-import org.apache.tapestry5.annotations.Environmental;
-import org.apache.tapestry5.annotations.Events;
-import org.apache.tapestry5.annotations.HeartbeatDeferred;
-import org.apache.tapestry5.annotations.Log;
-import org.apache.tapestry5.annotations.Mixin;
-import org.apache.tapestry5.annotations.OnEvent;
-import org.apache.tapestry5.annotations.Parameter;
-import org.apache.tapestry5.annotations.Persist;
+import org.apache.tapestry5.*;
+import org.apache.tapestry5.annotations.*;
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;
import org.apache.tapestry5.corelib.mixins.RenderInformals;
import org.apache.tapestry5.dom.Element;
-import org.apache.tapestry5.internal.BeanValidationContext;
-import org.apache.tapestry5.internal.BeanValidationContextImpl;
-import org.apache.tapestry5.internal.InternalSymbols;
-import org.apache.tapestry5.internal.TapestryInternalUtils;
+import org.apache.tapestry5.internal.*;
import org.apache.tapestry5.internal.services.HeartbeatImpl;
import org.apache.tapestry5.internal.util.AutofocusValidationDecorator;
import org.apache.tapestry5.ioc.Location;
@@ -66,39 +33,52 @@ 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.JSONArray;
import org.apache.tapestry5.json.JSONObject;
import org.apache.tapestry5.runtime.Component;
-import org.apache.tapestry5.services.ClientBehaviorSupport;
-import org.apache.tapestry5.services.ClientDataEncoder;
-import org.apache.tapestry5.services.ComponentSource;
-import org.apache.tapestry5.services.Environment;
-import org.apache.tapestry5.services.FormSupport;
-import org.apache.tapestry5.services.Heartbeat;
-import org.apache.tapestry5.services.Request;
+import org.apache.tapestry5.services.*;
import org.apache.tapestry5.services.javascript.InitializationPriority;
import org.apache.tapestry5.services.javascript.JavaScriptSupport;
import org.slf4j.Logger;
+import java.io.EOFException;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+
/**
* An HTML form, which will enclose other components to render out the various
* types of fields.
- * <p/>
+ * <p>
* A Form emits many notification events. When it renders, it fires a
* {@link org.apache.tapestry5.EventConstants#PREPARE_FOR_RENDER}
notification, followed by a
- * {@link EventConstants#PREPARE} notification.
- * <p/>
+ * {@link EventConstants#PREPARE} notification.</p>
+ * <p>
* When the form is submitted, the component emits several notifications:
first a
* {@link EventConstants#PREPARE_FOR_SUBMIT}, then a {@link
EventConstants#PREPARE}: these allow the page to update its
- * state as necessary to prepare for the form submission, then (after
components enclosed by the form have operated), a
- * {@link EventConstants#VALIDATE} event is emitted, to allow for cross-form
validation. After that, either a
+ * state as necessary to prepare for the form submission.</p>
+ * <p>
+ * The Form component determines if the form was cancelled (see {@link
org.apache.tapestry5.corelib.SubmitMode#CANCEL}. If so,
+ * an {@link EventConstants#CANCELED} event is emitted.</p>
+ * <p>
+ * Next come notifications to contained components (or more accurately, the
execution of stored {@link ComponentAction}s), to allow each component to
retrieve and validate
+ * submitted values, and update server-side properties. This is based on the
{@code t:formdata} query parameter,
+ * which contains serialized object data (generated when the form initially
renders).
+ * </p>
+ * <p>Once the form data is processed, the next step is to emit the
+ * {@link EventConstants#VALIDATE}, which allows for cross-form validation.
After that, either a
* {@link EventConstants#SUCCESS} OR {@link EventConstants#FAILURE} event
(depending on whether the
* {@link ValidationTracker} has recorded any errors). Lastly, a {@link
EventConstants#SUBMIT} event, for any listeners
- * that care only about form submission, regardless of success or failure.
- * <p/>
- * For all of these notifications, the event context is derived from the
<strong>context</strong> parameter. This
+ * that care only about form submission, regardless of success or failure.</p>
+ * <p>
+ * For all of these notifications, the event context is derived from the
<strong>context</strong> component parameter. This
* context is encoded into the form's action URI (the parameter is not read
when the form is submitted, instead the
* values encoded into the form are used).
- *
+ * </p>
+ * <p>
+ * While rendering, or processing a Form submission, the Form component places
a {@link FormSupport} object into the {@linkplain Environment environment},
+ * so that enclosed components can coordinate with the Form component.
+ * </p>
+ *
* @tapestrydoc
* @see BeanEditForm
* @see Errors
@@ -106,8 +86,8 @@ import org.slf4j.Logger;
* @see Label
*/
@Events(
-{ EventConstants.PREPARE_FOR_RENDER, EventConstants.PREPARE,
EventConstants.PREPARE_FOR_SUBMIT,
- EventConstants.VALIDATE, EventConstants.SUBMIT,
EventConstants.FAILURE, EventConstants.SUCCESS })
+ {EventConstants.PREPARE_FOR_RENDER, EventConstants.PREPARE,
EventConstants.PREPARE_FOR_SUBMIT,
+ EventConstants.VALIDATE, EventConstants.SUBMIT,
EventConstants.FAILURE, EventConstants.SUCCESS})
public class Form implements ClientElement, FormValidationControl
{
/**
@@ -119,7 +99,8 @@ public class Form implements ClientEleme
/**
* Used by {@link Submit}, etc., to identify which particular client-side
element (by element id)
* was responsible for the submission. An empty hidden field is created,
as needed, to store this value.
- *
+ * Starting in Tapestry 5.3, this is a JSONArray with two values: the
client id followed by the client name.
+ *
* @since 5.2.0
*/
public static final String SUBMITTING_ELEMENT_ID = "t:submit";
@@ -162,7 +143,7 @@ public class Form implements ClientEleme
* cursor into the form. The field to
* receive focus is the first rendered field that is in error, or required,
* or present (in that order of priority).
- *
+ *
* @see SymbolConstants#FORM_CLIENT_LOGIC_ENABLED
*/
@Parameter
@@ -190,7 +171,7 @@ public class Form implements ClientEleme
* Prefix value used when searching for validation messages and
constraints.
* The default is the Form component's
* id. This is overridden by {@link
org.apache.tapestry5.corelib.components.BeanEditForm}.
- *
+ *
* @see org.apache.tapestry5.services.FormSupport#getFormValidationId()
*/
@Parameter
@@ -289,10 +270,10 @@ public class Form implements ClientEleme
* persistent field and be stored into the session). This means that if no
errors are recorded,
* the tracker parameter is not updated and (in the default case) no data
is stored into the
* session.
- *
- * @see <a
href="https://issues.apache.org/jira/browse/TAP5-979">TAP5-979</a>
+ *
* @return a tracker ready to receive data (possibly a previously stored
tracker with field
* input and errors)
+ * @see <a
href="https://issues.apache.org/jira/browse/TAP5-979">TAP5-979</a>
*/
private ValidationTracker getWrappedTracker()
{
@@ -442,23 +423,23 @@ public class Form implements ClientEleme
* Creates an {@link
org.apache.tapestry5.corelib.internal.InternalFormSupport} for
* this Form. This method is used
* by {@link org.apache.tapestry5.corelib.components.FormInjector}.
- * <p>
+ * <p/>
* This method may also be invoked as the handler for the
"internalCreateRenderTimeFormSupport" event.
- *
+ *
* @param clientId
- * the client-side id for the rendered form
- * element
+ * the client-side id for the rendered form
+ * element
* @param actionSink
- * used to collect component actions that will, ultimately, be
- * written as the t:formdata hidden
- * field
+ * used to collect component actions that will, ultimately, be
+ * written as the t:formdata hidden
+ * field
* @param allocator
- * used to allocate unique ids
+ * used to allocate unique ids
* @return form support object
*/
@OnEvent("internalCreateRenderTimeFormSupport")
InternalFormSupport createRenderTimeFormSupport(String clientId,
ComponentActionSink actionSink,
- IdAllocator allocator)
+ IdAllocator allocator)
{
return new FormSupportImpl(resources, clientId, actionSink,
clientBehaviorSupport,
clientValidation != ClientValidation.NONE, allocator,
validationId);
@@ -497,7 +478,7 @@ public class Form implements ClientEleme
}
@SuppressWarnings(
- { "unchecked", "InfiniteLoopStatement" })
+ {"unchecked", "InfiniteLoopStatement"})
@Log
Object onAction(EventContext context) throws IOException
{
@@ -525,6 +506,14 @@ public class Form implements ClientEleme
resources.triggerContextEvent(EventConstants.PREPARE, context,
eventCallback);
+ if (isFormCancelled())
+ {
+ resources.triggerContextEvent(EventConstants.CANCELED,
context, eventCallback);
+ if (eventCallback.isAborted())
+ return true;
+ }
+
+
environment.push(BeanValidationContext.class, new
BeanValidationContextImpl(validate));
if (eventCallback.isAborted())
@@ -565,8 +554,7 @@ public class Form implements ClientEleme
resources.triggerContextEvent(EventConstants.SUBMIT, context,
eventCallback);
return eventCallback.isAborted();
- }
- finally
+ } finally
{
environment.pop(Heartbeat.class);
environment.pop(FormSupport.class);
@@ -579,13 +567,39 @@ public class Form implements ClientEleme
}
}
+ private boolean isFormCancelled()
+ {
+ // The "cancel" query parameter is reserved for this purpose; if it is
present then the form was canceled on the
+ // client side. For image submits, there will be two parameters:
"cancel.x" and "cancel.y".
+
+ if (request.getParameter(InternalConstants.CANCEL_NAME) != null ||
+ request.getParameter(InternalConstants.CANCEL_NAME + ".x") !=
null)
+ {
+ return true;
+ }
+
+ // When JavaScript is involved, it's more complicated. In fact, this
is part of HLS's desire
+ // to have all forms submit via XHR when JavaScript is present, since
it would provide
+ // an opportunity to get the submitting element's value into the
request properly.
+
+ String raw = request.getParameter(SUBMITTING_ELEMENT_ID);
+
+ if (raw != null &&
+ new
JSONArray(raw).getString(1).equals(InternalConstants.CANCEL_NAME))
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+
private void fireValidateEvent(String eventName, EventContext context,
TrackableComponentEventCallback callback)
{
try
{
resources.triggerContextEvent(eventName, context, callback);
- }
- catch (RuntimeException ex)
+ } catch (RuntimeException ex)
{
ValidationException ve = ExceptionUtils.findCause(ex,
ValidationException.class);
@@ -645,18 +659,15 @@ public class Form implements ClientEleme
component = null;
}
- }
- catch (EOFException ex)
+ } catch (EOFException ex)
{
// Expected
- }
- catch (Exception ex)
+ } catch (Exception ex)
{
Location location = component == null ? null :
component.getComponentResources().getLocation();
throw new TapestryException(ex.getMessage(), location, ex);
- }
- finally
+ } finally
{
InternalUtils.close(ois);
}
@@ -732,9 +743,8 @@ public class Form implements ClientEleme
{
activePageResources.triggerEvent(EventConstants.PREALLOCATE_FORM_CONTROL_NAMES,
new Object[]
- { idAllocator }, null);
- }
- catch (RuntimeException ex)
+ {idAllocator}, null);
+ } catch (RuntimeException ex)
{
logger.error(
String.format("Unable to obtrain form control names to
preallocate: %s",
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/LinkSubmit.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/LinkSubmit.java?rev=1143161&r1=1143160&r2=1143161&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/LinkSubmit.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/LinkSubmit.java
Tue Jul 5 18:30:49 2011
@@ -14,19 +14,14 @@
package org.apache.tapestry5.corelib.components;
-import org.apache.tapestry5.BindingConstants;
-import org.apache.tapestry5.ClientElement;
-import org.apache.tapestry5.ComponentAction;
-import org.apache.tapestry5.ComponentResources;
-import org.apache.tapestry5.EventConstants;
-import org.apache.tapestry5.MarkupWriter;
-import org.apache.tapestry5.TrackableComponentEventCallback;
+import org.apache.tapestry5.*;
import org.apache.tapestry5.annotations.Environmental;
import org.apache.tapestry5.annotations.Events;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.SupportsInformalParameters;
import org.apache.tapestry5.corelib.SubmitMode;
import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.json.JSONArray;
import org.apache.tapestry5.json.JSONObject;
import org.apache.tapestry5.services.FormSupport;
import org.apache.tapestry5.services.Heartbeat;
@@ -38,7 +33,7 @@ import org.apache.tapestry5.services.jav
* Generates a client-side hyperlink that submits the enclosing form. If the
link is clicked in the browser, the
* component will trigger an event ({@linkplain EventConstants#SELECTED
selected} by default) , just like {@link Submit}
* .
- *
+ *
* @tapestrydoc
*/
@SupportsInformalParameters
@@ -62,7 +57,7 @@ public class LinkSubmit implements Clien
* Defines the mode, or client-side behavior, for the submit. The default
is {@link SubmitMode#NORMAL}; clicking the
* button submits the form with validation. {@link SubmitMode#CANCEL}
indicates the client-side validation
* should be omitted (though server-side validation still occurs).
- *
+ *
* @since 5.2.0
*/
@Parameter(allowNull = false, defaultPrefix = BindingConstants.LITERAL)
@@ -80,7 +75,7 @@ public class LinkSubmit implements Clien
/**
* The list of values that will be made available to event handler method
of this component when the form is
* submitted.
- *
+ *
* @since 5.2.0
*/
@Parameter
@@ -126,7 +121,9 @@ public class LinkSubmit implements Clien
{
this.clientId = clientId;
- if (clientId.equals(request.getParameter(Form.SUBMITTING_ELEMENT_ID)))
+ String raw = request.getParameter(Form.SUBMITTING_ELEMENT_ID);
+
+ if (raw != null && new JSONArray(raw).getString(0).equals(clientId))
{
Runnable notification = new Runnable()
{
@@ -153,7 +150,7 @@ public class LinkSubmit implements Clien
writer.element("span",
- "id", clientId);
+ "id", clientId);
resources.renderInformalParameters(writer);
}
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Submit.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Submit.java?rev=1143161&r1=1143160&r2=1143161&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Submit.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/corelib/components/Submit.java
Tue Jul 5 18:30:49 2011
@@ -20,8 +20,9 @@ import org.apache.tapestry5.annotations.
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.SupportsInformalParameters;
import org.apache.tapestry5.corelib.SubmitMode;
-import org.apache.tapestry5.dom.Element;
+import org.apache.tapestry5.internal.InternalConstants;
import org.apache.tapestry5.ioc.annotations.Inject;
+import org.apache.tapestry5.json.JSONArray;
import org.apache.tapestry5.services.FormSupport;
import org.apache.tapestry5.services.Heartbeat;
import org.apache.tapestry5.services.Request;
@@ -31,7 +32,7 @@ import org.apache.tapestry5.services.jav
* Corresponds to <input type="submit"> or <input type="image">, a
client-side element that can force the
* enclosing form to submit. The submit responsible for the form submission
will post a notification that allows the
* application to know that it was the responsible entity. The notification is
named "selected" and has no context.
- *
+ *
* @tapestrydoc
*/
@SupportsInformalParameters
@@ -64,7 +65,7 @@ public class Submit implements ClientEle
/**
* The list of values that will be made available to event handler method
of this component when the form is
* submitted.
- *
+ *
* @since 5.1.0.0
*/
@Parameter
@@ -72,7 +73,7 @@ public class Submit implements ClientEle
/**
* If provided, the component renders an input tag with type "image".
Otherwise "submit".
- *
+ *
* @since 5.1.0.0
*/
@Parameter(defaultPrefix = BindingConstants.ASSET)
@@ -82,7 +83,7 @@ public class Submit implements ClientEle
* Defines the mode, or client-side behavior, for the submit. The default
is {@link SubmitMode#NORMAL}; clicking the
* button submits the form with validation. {@link SubmitMode#CANCEL}
indicates the client-side validation
* should be omitted (though server-side validation still occurs).
- *
+ *
* @since 5.2.0
*/
@Parameter(allowNull = false, defaultPrefix = BindingConstants.LITERAL)
@@ -138,7 +139,11 @@ public class Submit implements ClientEle
{
clientId = javascriptSupport.allocateClientId(resources);
- String name = formSupport.allocateControlName(resources.getId());
+ boolean isCancel = mode == SubmitMode.CANCEL;
+
+ String name =
+ isCancel ? InternalConstants.CANCEL_NAME :
+ formSupport.allocateControlName(resources.getId());
// Save the element, to see if an id is later requested.
@@ -146,29 +151,36 @@ public class Submit implements ClientEle
writer.element("input",
- "type", type,
+ "type", type,
- "name", name,
+ "name", name,
- "id", clientId);
+ "id", clientId);
if (disabled)
+ {
writer.attributes("disabled", "disabled");
+ }
if (image != null)
+ {
writer.attributes("src", image.toClientURL());
+ }
formSupport.store(this, new ProcessSubmission(clientId, name));
resources.renderInformalParameters(writer);
+
+ if (isCancel)
+ {
+ javascriptSupport.addInitializerCall("cancelButton",
getClientId());
+ }
+
}
void afterRender(MarkupWriter writer)
{
writer.end();
-
- if (mode == SubmitMode.CANCEL)
- javascriptSupport.addInitializerCall("cancelButton",
getClientId());
}
void processSubmission(String clientId, String elementName)
@@ -199,8 +211,13 @@ public class Submit implements ClientEle
{
// Case #1: via JavaScript, the client id is passed up.
- if (clientId.equals(request.getParameter(Form.SUBMITTING_ELEMENT_ID)))
+ String raw = request.getParameter(Form.SUBMITTING_ELEMENT_ID);
+
+ if (raw != null &&
+ new JSONArray(raw).getString(0).equals(clientId))
+ {
return true;
+ }
// Case #2: No JavaScript, look for normal semantic (non-null value
for the element's name).
// If configured as an image submit, look for a value for the x
position. Ah, the ugliness
@@ -215,7 +232,7 @@ public class Submit implements ClientEle
/**
* Returns the component's client id. This must be called after the
component has rendered.
- *
+ *
* @return client id for the component
*/
public String getClientId()
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalConstants.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalConstants.java?rev=1143161&r1=1143160&r2=1143161&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalConstants.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/InternalConstants.java
Tue Jul 5 18:30:49 2011
@@ -92,21 +92,21 @@ public final class InternalConstants
* useful when the code opening the response stream wants to explicitly
control whether GZIP
* compression occurs or
* not.
- *
+ *
* @since 5.1.0.0
*/
public static final String SUPPRESS_COMPRESSION =
"tapestry.supress-compression";
/**
* Name of response header for content encoding.
- *
+ *
* @since 5.1.0.0
*/
public static final String CONTENT_ENCODING_HEADER = "Content-Encoding";
/**
* Response content encoding value indicating use of GZIP compression.
- *
+ *
* @since 5.1.0.0
*/
public static final String GZIP_CONTENT_ENCODING = "gzip";
@@ -128,16 +128,24 @@ public final class InternalConstants
/**
* Name of the core {@link JavaScriptStack}, which supplies the basic
JavaScript infrastructure
* on the client.
- *
+ *
* @since 5.2.0
*/
public static final String CORE_STACK_NAME = "core";
/**
* The names of the standard controlled subpackages.
- *
+ *
* @since 5.3
*/
public static final String[] SUBPACKAGES =
- { PAGES_SUBPACKAGE, COMPONENTS_SUBPACKAGE, MIXINS_SUBPACKAGE,
BASE_SUBPACKAGE };
+ {PAGES_SUBPACKAGE, COMPONENTS_SUBPACKAGE, MIXINS_SUBPACKAGE,
BASE_SUBPACKAGE};
+
+ /**
+ * The element name for a submit input element used to cancel the form
(rather than
+ * submit it normally).
+ *
+ * @since 5.3
+ */
+ public static final String CANCEL_NAME = "cancel";
}
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=1143161&r1=1143160&r2=1143161&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/services/TapestryModule.java
Tue Jul 5 18:30:49 2011
@@ -2377,7 +2377,7 @@ public final class TapestryModule
configuration.add(SymbolConstants.BLACKBIRD_ENABLED, false);
- configuration.add(InternalSymbols.PRE_SELECTED_FORM_NAMES,
"reset,submit,select,id,method,action,onsubmit");
+ configuration.add(InternalSymbols.PRE_SELECTED_FORM_NAMES,
"reset,submit,select,id,method,action,onsubmit," +
InternalConstants.CANCEL_NAME);
configuration.add(SymbolConstants.COMPONENT_RENDER_TRACING_ENABLED,
false);
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/BeanEditForm.tml
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/BeanEditForm.tml?rev=1143161&r1=1143160&r2=1143161&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/BeanEditForm.tml
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/corelib/components/BeanEditForm.tml
Tue Jul 5 18:30:49 2011
@@ -1,5 +1,5 @@
<form t:id="form" validate="object"
- xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+ xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
<t:errors/>
<div class="t-beaneditor">
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=1143161&r1=1143160&r2=1143161&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry5/tapestry.js
Tue Jul 5 18:30:49 2011
@@ -1550,7 +1550,7 @@ Tapestry.FormEventManager = Class.create
this.submitHidden = hiddens.first();
}
- this.submitHidden.value = element == null ? null :
$(element).id;
+ this.submitHidden.value = element == null ? null :
Object.toJSON([$(element).id, $(element).name]);
},
handleSubmit : function(domevent) {
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/corelib/components/SubmitTest.java
URL:
http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/corelib/components/SubmitTest.java?rev=1143161&r1=1143160&r2=1143161&view=diff
==============================================================================
---
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/corelib/components/SubmitTest.java
(original)
+++
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/corelib/components/SubmitTest.java
Tue Jul 5 18:30:49 2011
@@ -1,4 +1,4 @@
-// Copyright 2007, 2008, 2010 The Apache Software Foundation
+// Copyright 2007, 2008, 2010, 2011 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.
@@ -60,7 +60,7 @@ public class SubmitTest extends Internal
// Also: test for the alternate, JavaScript oriented way, of
determining the
// element/component that triggered the submission.
- train_getParameter(request, Form.SUBMITTING_ELEMENT_ID, "xyz");
+ train_getParameter(request, Form.SUBMITTING_ELEMENT_ID, "[ 'xyz',
'pdq' ]");
replay();