You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2008/02/28 19:52:56 UTC
svn commit: r632085 [1/2] - in /tapestry/tapestry5/trunk/tapestry-core/src:
main/java/org/apache/tapestry/ main/java/org/apache/tapestry/corelib/base/
main/java/org/apache/tapestry/corelib/components/
main/java/org/apache/tapestry/corelib/data/ main/ja...
Author: hlship
Date: Thu Feb 28 10:52:45 2008
New Revision: 632085
URL: http://svn.apache.org/viewvc?rev=632085&view=rev
Log:
TAPESTRY-1650: Add support for injecting (via Ajax) new content into an existing client-side form
Added:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormInjector.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/SubmitNotifier.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/data/InsertPosition.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientBehaviorSupport.java
- copied, changed from r630031, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ZoneSetup.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientBehaviorSupportImpl.java
- copied, changed from r630031, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ZoneSetupImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/test/app1/FormInjectorDemo.tml
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormInjectorDemo.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ClientBehaviorSupportImplTest.java
- copied, changed from r630031, tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ZoneSetupImplTest.java
Removed:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxUIDManager.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/AjaxUIDManagerImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ZoneSetup.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ZoneSetupImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/AjaxUIDManagerImplTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/services/ZoneSetupImplTest.java
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResources.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/PageRenderSupport.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractComponentEventLink.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormFragment.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Loop.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PageLink.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Radio.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Zone.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/internal/FormSupportImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueue.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueueImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderSupportImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PartialRenderPageRenderSupport.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableRequestImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/FormSupport.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/util/StringToEnumCoercion.java
tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/corelib/internal/FormSupportImplTest.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/components/Any.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/internal/test/InternalBaseTestCase.java
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResources.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResources.java?rev=632085&r1=632084&r2=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResources.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResources.java Thu Feb 28 10:52:45 2008
@@ -192,4 +192,11 @@
* <em>next</em> request (the attached page instance is not affected).
*/
void discardPersistentFieldChanges();
+
+ /**
+ * Returns the name of element that represents the component in its template, or null if not known.
+ *
+ * @return the element name or null
+ */
+ String getElementName();
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java?rev=632085&r1=632084&r2=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ComponentResourcesCommon.java Thu Feb 28 10:52:45 2008
@@ -53,6 +53,18 @@
/**
* A convienience for invoking {@link #triggerContextEvent(String, EventContext , ComponentEventCallback)}. Wraps
* the context values into an {@link org.apache.tapestry.EventContext}.
+ *
+ * @param eventType event type (as determined from the request, or otherwise by design)
+ * @param context Values that may be provided to the event handler method as method parameters, or null if no
+ * context values are available
+ * @param callback the handler to be informed of the result, or null if the event is a notification that does not
+ * support return values from event handler methods (the value true is allowed even if the handler
+ * is null).
+ * @return true if any event handler was invoked (even if no event handler method returns a non-null value)
+ * @throws org.apache.tapestry.runtime.ComponentEventException
+ * if an event handler method throws a checked or unchecked exception
+ * @see org.apache.tapestry.internal.transform.OnEventWorker
+ * @see org.apache.tapestry.annotations.OnEvent
*/
boolean triggerEvent(String eventType, Object[] contextValues, ComponentEventCallback callback);
@@ -97,12 +109,13 @@
Locale getLocale();
/**
- * Returns the name of element that represents the component in its template, or null if the element was a component
- * type (in the Tapestry namespace).
+ * Returns the name of element that represents the component in its template, or the provided default element name
+ * if the element was a component type (in the Tapestry namespace).
*
+ * @param defaultElementName element name to return if the element name is not known (may be null)
* @return the element name
*/
- String getElementName();
+ String getElementName(String defaultElementName);
/**
* Returns a block from the component's template, referenced by its id.
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/PageRenderSupport.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/PageRenderSupport.java?rev=632085&r1=632084&r2=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/PageRenderSupport.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/PageRenderSupport.java Thu Feb 28 10:52:45 2008
@@ -1,4 +1,4 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 2007, 2008 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -14,7 +14,6 @@
package org.apache.tapestry;
-import org.apache.tapestry.ioc.internal.util.IdAllocator;
import org.apache.tapestry.ioc.services.SymbolSource;
import org.apache.tapestry.services.AssetSource;
@@ -30,10 +29,18 @@
* precisely match the input value (an underscore and a unique index value may be appended).
*
* @param id the component id from which a unique id will be generated
- * @return a unqiue id for this rendering of the page
- * @see IdAllocator
+ * @return a unique id for this rendering of the page
+ * @see org.apache.tapestry.ioc.internal.util.IdAllocator
*/
String allocateClientId(String id);
+
+ /**
+ * As with {@link #allocateClientId(String)} but uses the id of the component extracted
+ * from the resources.
+ * @param resources of the component which requires an id
+ * @return a unique id for this rendering of the page
+ */
+ String allocateClientId(ComponentResources resources);
/**
* Adds one or more new script assets to the page. Assets are added uniquely, and appear as
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractComponentEventLink.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractComponentEventLink.java?rev=632085&r1=632084&r2=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractComponentEventLink.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractComponentEventLink.java Thu Feb 28 10:52:45 2008
@@ -17,7 +17,7 @@
import org.apache.tapestry.*;
import org.apache.tapestry.annotations.Environmental;
import org.apache.tapestry.annotations.Parameter;
-import org.apache.tapestry.internal.services.ZoneSetup;
+import org.apache.tapestry.internal.services.ClientBehaviorSupport;
import org.apache.tapestry.ioc.annotations.Inject;
import java.util.List;
@@ -49,13 +49,13 @@
private PageRenderSupport _support;
@Environmental
- private ZoneSetup _zoneSetup;
+ private ClientBehaviorSupport _clientBehaviorSupport;
void beginRender(MarkupWriter writer)
{
if (isDisabled()) return;
- String clientId = _support.allocateClientId(_resources.getId());
+ String clientId = _support.allocateClientId(_resources);
Object[] contextArray = _context == null ? new Object[0] : _context.toArray();
@@ -63,7 +63,7 @@
writeLink(writer, clientId, link);
- if (_zone != null) _zoneSetup.linkZone(clientId, _zone);
+ if (_zone != null) _clientBehaviorSupport.linkZone(clientId, _zone);
}
/**
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.java?rev=632085&r1=632084&r2=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.java Thu Feb 28 10:52:45 2008
@@ -22,10 +22,10 @@
import org.apache.tapestry.corelib.internal.FormSupportImpl;
import org.apache.tapestry.corelib.mixins.RenderInformals;
import org.apache.tapestry.dom.Element;
+import org.apache.tapestry.internal.services.ClientBehaviorSupport;
import org.apache.tapestry.internal.services.ComponentInvocationMap;
import org.apache.tapestry.internal.services.ComponentResultProcessorWrapper;
import org.apache.tapestry.internal.services.HeartbeatImpl;
-import org.apache.tapestry.internal.services.ZoneSetup;
import org.apache.tapestry.internal.util.Base64ObjectInputStream;
import org.apache.tapestry.internal.util.Base64ObjectOutputStream;
import org.apache.tapestry.ioc.Location;
@@ -38,7 +38,6 @@
import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
-import static java.lang.String.format;
import java.util.List;
/**
@@ -180,7 +179,7 @@
private ComponentEventResultProcessor _componentEventResultProcessor;
@Environmental
- private ZoneSetup _zoneSetup;
+ private ClientBehaviorSupport _clientBehaviorSupport;
private String _name;
@@ -208,17 +207,18 @@
throw new RuntimeException(ex);
}
- _name = _pageRenderSupport.allocateClientId(_resources.getId());
+ _name = _pageRenderSupport.allocateClientId(_resources);
- _formSupport = new FormSupportImpl(_name, _actions);
+ _formSupport = new FormSupportImpl(_name, _actions, _clientBehaviorSupport, _clientValidation);
- if (_zone != null) _zoneSetup.linkZone(_name, _zone);
+ if (_zone != null) _clientBehaviorSupport.linkZone(_name, _zone);
// TODO: Forms should not allow to nest. Perhaps a set() method instead of a push() method
// for this kind of check?
_environment.push(FormSupport.class, _formSupport);
_environment.push(ValidationTracker.class, _tracker);
+
// Now that the environment is setup, inform the component or other listeners that the form
// is about to render.
@@ -261,14 +261,6 @@
_formSupport.executeDeferred();
- if (_clientValidation)
- {
- // The validations are a JSON object that doesn't need to be enclosed in quotes.
- // Invoking addScript() will add in the default JavaScript (prototype, scriptaculous, tapestry.js).
- _pageRenderSupport.addScript(
- format("Tapestry.registerForm('%s', %s);", _name, _formSupport.getValidations()));
- }
-
String encodingType = _formSupport.getEncodingType();
if (encodingType != null) _form.forceAttributes("enctype", encodingType);
@@ -286,7 +278,13 @@
throw new RuntimeException(ex);
}
- _div.element("input", "type", "hidden", "name", FORM_DATA, "value", _actions.toBase64());
+ _div.element("input",
+
+ "type", "hidden",
+
+ "name", FORM_DATA,
+
+ "value", _actions.toBase64());
}
void cleanupRender()
@@ -318,6 +316,7 @@
try
{
+
ComponentResultProcessorWrapper callback = new ComponentResultProcessorWrapper(
_componentEventResultProcessor);
@@ -329,45 +328,7 @@
if (callback.isAborted()) return true;
- // TODO: Ajax stuff will eventually mean there are multiple values for this parameter
- // name
-
- String actionsBase64 = _request.getParameter(FORM_DATA);
-
- ObjectInputStream ois = null;
-
- Component component = null;
-
- try
- {
- ois = new Base64ObjectInputStream(actionsBase64);
-
- while (true)
- {
- String componentId = ois.readUTF();
- ComponentAction action = (ComponentAction) ois.readObject();
-
- component = _source.getComponent(componentId);
-
- action.execute(component);
-
- component = null;
- }
- }
- catch (EOFException ex)
- {
- // Expected
- }
- catch (Exception ex)
- {
- Location location = component == null ? null : component.getComponentResources().getLocation();
-
- throw new TapestryException(ex.getMessage(), location, ex);
- }
- finally
- {
- InternalUtils.close(ois);
- }
+ executeStoredActions();
heartbeat.end();
@@ -409,6 +370,59 @@
{
_environment.pop(Heartbeat.class);
_environment.pop(FormSupport.class);
+ }
+ }
+
+ /**
+ * Pulls the stored actions out of the request, converts them from MIME stream back to object stream and then
+ * objects, and executes them.
+ */
+ private void executeStoredActions()
+ {
+ String[] values = _request.getParameters(FORM_DATA);
+
+ System.out.println("values = " + values);
+
+ if (values == null) return;
+
+ // Due to Ajax (FormInjector) there may be multiple values here, so handle each one individually.
+
+ for (String actionsBase64 : values)
+ {
+ ObjectInputStream ois = null;
+
+ Component component = null;
+
+ try
+ {
+ ois = new Base64ObjectInputStream(actionsBase64);
+
+ while (true)
+ {
+ String componentId = ois.readUTF();
+ ComponentAction action = (ComponentAction) ois.readObject();
+
+ component = _source.getComponent(componentId);
+
+ action.execute(component);
+
+ component = null;
+ }
+ }
+ catch (EOFException ex)
+ {
+ // Expected
+ }
+ catch (Exception ex)
+ {
+ Location location = component == null ? null : component.getComponentResources().getLocation();
+
+ throw new TapestryException(ex.getMessage(), location, ex);
+ }
+ finally
+ {
+ InternalUtils.close(ois);
+ }
}
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormFragment.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormFragment.java?rev=632085&r1=632084&r2=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormFragment.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormFragment.java Thu Feb 28 10:52:45 2008
@@ -21,7 +21,7 @@
import org.apache.tapestry.corelib.internal.FormSupportAdapter;
import org.apache.tapestry.corelib.internal.WrappedComponentAction;
import org.apache.tapestry.dom.Element;
-import org.apache.tapestry.internal.services.ZoneSetup;
+import org.apache.tapestry.internal.services.ClientBehaviorSupport;
import org.apache.tapestry.ioc.annotations.Inject;
import org.apache.tapestry.ioc.internal.util.CollectionFactory;
import org.apache.tapestry.ioc.internal.util.Defense;
@@ -84,7 +84,7 @@
private ComponentResources _resources;
@Environmental
- private ZoneSetup _zoneSetup;
+ private ClientBehaviorSupport _clientBehaviorSupport;
private String _clientId;
@@ -162,7 +162,7 @@
writer.end();
- _zoneSetup.addFormFragment(_clientId, _show, _hide);
+ _clientBehaviorSupport.addFormFragment(_clientId, _show, _hide);
_componentActions = CollectionFactory.newList();
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormInjector.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormInjector.java?rev=632085&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormInjector.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormInjector.java Thu Feb 28 10:52:45 2008
@@ -0,0 +1,212 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.*;
+import org.apache.tapestry.annotations.Environmental;
+import org.apache.tapestry.annotations.Parameter;
+import org.apache.tapestry.annotations.SupportsInformalParameters;
+import org.apache.tapestry.corelib.data.InsertPosition;
+import org.apache.tapestry.corelib.internal.FormSupportImpl;
+import org.apache.tapestry.internal.services.ClientBehaviorSupport;
+import org.apache.tapestry.internal.services.ComponentResultProcessorWrapper;
+import org.apache.tapestry.internal.services.PageRenderQueue;
+import org.apache.tapestry.internal.util.Base64ObjectOutputStream;
+import org.apache.tapestry.ioc.annotations.Inject;
+import org.apache.tapestry.ioc.internal.util.IdAllocator;
+import org.apache.tapestry.runtime.RenderCommand;
+import org.apache.tapestry.runtime.RenderQueue;
+import org.apache.tapestry.services.*;
+
+import java.io.IOException;
+import java.util.List;
+
+/**
+ * A way to add new content to an existing Form. The FormInjector emulates its tag from
+ * the template (or uses a <div>).
+ * When triggered, new content is obtained from the application and is injected before or after the
+ * element.
+ */
+@SupportsInformalParameters
+public class FormInjector implements ClientElement
+{
+ public static final String INJECT_EVENT = "inject";
+
+ public static final String FORMID_PARAMETER = "t:formid";
+
+ /**
+ * The context for the link (optional parameter). This list of values will be converted into strings and included in
+ * the URI. The strings will be coerced back to whatever their values are and made available to event handler
+ * methods.
+ */
+ @Parameter
+ private List<?> _context;
+
+ @Parameter(defaultPrefix = TapestryConstants.LITERAL_BINDING_PREFIX, value = "above")
+ private InsertPosition _position;
+
+ /**
+ * Name of a function on the client-side Tapestry.ZoneEffect object that is invoked to make added content visible.
+ * Leaving as null uses the default function, "highlight".
+ */
+ @Parameter(defaultPrefix = TapestryConstants.LITERAL_BINDING_PREFIX)
+ private String _show;
+
+
+ @Environmental
+ private PageRenderSupport _pageRenderSupport;
+
+ @Environmental
+ private FormSupport _formSupport;
+
+ @Environmental
+ private ClientBehaviorSupport _clientBehaviorSupport;
+
+ @Inject
+ @Ajax
+ private ComponentEventResultProcessor _componentEventResultProcessor;
+
+
+ @Inject
+ private PageRenderQueue _pageRenderQueue;
+
+ private String _clientId;
+
+ @Inject
+ private ComponentResources _resources;
+
+ @Inject
+ private Request _request;
+
+ @Inject
+ private Environment _environment;
+
+ void beginRender(MarkupWriter writer)
+ {
+ _clientId = _pageRenderSupport.allocateClientId(_resources);
+
+ writer.element(_resources.getElementName("div"),
+
+ "id", _clientId);
+
+ _resources.renderInformalParameters(writer);
+
+ // Now work on the JavaScript side of things.
+
+ Link link = _resources.createActionLink(INJECT_EVENT, false,
+ _context == null ? new Object[0] : _context.toArray());
+
+ link.addParameter(FORMID_PARAMETER, _formSupport.getClientId());
+
+ _clientBehaviorSupport.addFormInjector(_clientId, link, _position, _show);
+ }
+
+ void afterRender(MarkupWriter writer)
+ {
+ writer.end();
+ }
+
+
+ /**
+ * Returns the unique client-side id of the rendered element.
+ */
+ public String getClientId()
+ {
+ return _clientId;
+ }
+
+ /**
+ * Invoked via an Ajax request. Triggers an action event and captures the return value. The return value from the
+ * event notification is what will ultimately render (typically, its a Block). However, we do a <em>lot</em> of
+ * tricks to provide the desired FormSupport around the what renders.
+ */
+ void onInject(EventContext context) throws IOException
+ {
+ ComponentResultProcessorWrapper callback = new ComponentResultProcessorWrapper(
+ _componentEventResultProcessor);
+
+ _resources.triggerContextEvent(TapestryConstants.ACTION_EVENT, context, callback);
+
+ if (!callback.isAborted()) return;
+
+ // Here's where it gets very, very tricky.
+
+ final RenderCommand rootRenderCommand = _pageRenderQueue.getRootRenderCommand();
+
+ final String formId = _request.getParameter(FORMID_PARAMETER);
+
+ final Base64ObjectOutputStream actions = new Base64ObjectOutputStream();
+
+ final RenderCommand cleanup = new RenderCommand()
+ {
+ public void render(MarkupWriter writer, RenderQueue queue)
+ {
+ try
+ {
+ actions.close();
+ }
+ catch (IOException ex)
+ {
+ throw new RuntimeException(ex);
+ }
+
+ _environment.pop(ValidationTracker.class);
+ FormSupportImpl formSupport = (FormSupportImpl) _environment.pop(FormSupport.class);
+
+ formSupport.executeDeferred();
+
+ writer.element("input",
+
+ "type", "hidden",
+
+ "name", Form.FORM_DATA,
+
+ "value", actions.toBase64());
+ }
+ };
+
+ final RenderCommand setup = new RenderCommand()
+ {
+ public void render(MarkupWriter writer, RenderQueue queue)
+ {
+ // Kind of ugly, but the only way to ensure we don't have name collisions on the
+ // client side is to force a unique id into each name (as well as each id, but that's
+ // PageRenderSupport's job). It would be nice if we could agree on the uid, but
+ // not essential.
+
+ String uid = Long.toHexString(System.currentTimeMillis());
+
+ IdAllocator idAllocator = new IdAllocator(":" + uid);
+
+ FormSupportImpl formSupport = new FormSupportImpl(formId, actions, _clientBehaviorSupport, true,
+ idAllocator);
+ _environment.push(FormSupport.class, formSupport);
+
+
+ _environment.push(ValidationTracker.class, new ValidationTrackerImpl());
+
+ // Queue up the root render command to execute first, and the cleanup
+ // to execute after it is done.
+
+ queue.push(cleanup);
+ queue.push(rootRenderCommand);
+ }
+ };
+
+ // Replace rootRenderCommand with our more complicated setup.
+
+ _pageRenderQueue.initializeForPartialPageRender(setup);
+ }
+}
\ No newline at end of file
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Loop.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Loop.java?rev=632085&r1=632084&r2=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Loop.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Loop.java Thu Feb 28 10:52:45 2008
@@ -14,13 +14,11 @@
package org.apache.tapestry.corelib.components;
-import org.apache.tapestry.ComponentAction;
-import org.apache.tapestry.ComponentResources;
-import org.apache.tapestry.MarkupWriter;
-import org.apache.tapestry.PrimaryKeyEncoder;
+import org.apache.tapestry.*;
import org.apache.tapestry.annotations.*;
import org.apache.tapestry.ioc.annotations.Inject;
import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
+import org.apache.tapestry.services.ComponentDefaultProvider;
import org.apache.tapestry.services.FormSupport;
import org.apache.tapestry.services.Heartbeat;
@@ -160,9 +158,10 @@
}
/**
- * Defines the collection of values for the loop to iterate over.
+ * Defines the collection of values for the loop to iterate over. If not specified, defaults to a property of the
+ * container whose name
*/
- @Parameter(required = true)
+ @Parameter(required = true, principal = true)
private Iterable<?> _source;
/**
@@ -186,7 +185,7 @@
* The element to render. If not null, then the loop will render the indicated element around its body (on each pass
* through the loop). The default is derived from the component template.
*/
- @Parameter(value = "prop:componentResources.elementName", defaultPrefix = "literal")
+ @Parameter(value = "prop:componentResources.elementName", defaultPrefix = TapestryConstants.LITERAL_BINDING_PREFIX)
private String _elementName;
/**
@@ -210,6 +209,14 @@
@Inject
private ComponentResources _resources;
+
+ @Inject
+ private ComponentDefaultProvider _componentDefaultProvider;
+
+ Binding defaultSource()
+ {
+ return _componentDefaultProvider.defaultBinding("source", _resources);
+ }
@SetupRender
boolean setup()
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PageLink.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PageLink.java?rev=632085&r1=632084&r2=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PageLink.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PageLink.java Thu Feb 28 10:52:45 2008
@@ -66,7 +66,7 @@
{
if (_disabled) return;
- _clientId = _support.allocateClientId(_resources.getId());
+ _clientId = _support.allocateClientId(_resources);
Object[] activationContext = _context != null ? _context.toArray() : _emptyContext;
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Radio.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Radio.java?rev=632085&r1=632084&r2=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Radio.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Radio.java Thu Feb 28 10:52:45 2008
@@ -124,7 +124,7 @@
{
String value = _container.toClient(_value);
- _clientId = _pageRenderSupport.allocateClientId(_resources.getId());
+ _clientId = _pageRenderSupport.allocateClientId(_resources);
_controlName = _container.getElementName();
writer.element("input", "type", "radio", "id", _clientId, "name", _controlName, "value", value);
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/SubmitNotifier.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/SubmitNotifier.java?rev=632085&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/SubmitNotifier.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/SubmitNotifier.java Thu Feb 28 10:52:45 2008
@@ -0,0 +1,67 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.components;
+
+import org.apache.tapestry.ComponentAction;
+import org.apache.tapestry.ComponentResources;
+import org.apache.tapestry.annotations.Environmental;
+import org.apache.tapestry.ioc.annotations.Inject;
+import org.apache.tapestry.services.FormSupport;
+
+/**
+ * A non visual component used to provide notifications to its container during a form submission. Records actions into
+ * the form on {@link org.apache.tapestry.annotations.BeginRender} and {@link org.apache.tapestry.annotations.AfterRender}
+ * that (during the form submission) triggers "BeginSubmit" and "AfterSubmit" events. The container can receive these
+ * events to perform setup before a group of components process their submission, and perform cleanup afterwards.
+ */
+public class SubmitNotifier
+{
+ private static final class TriggerEvent implements ComponentAction<SubmitNotifier>
+ {
+ private final String _eventType;
+
+ public TriggerEvent(String eventType)
+ {
+ _eventType = eventType;
+ }
+
+ public void execute(SubmitNotifier component)
+ {
+ component.trigger(_eventType);
+ }
+ }
+
+
+ @Inject
+ private ComponentResources _resources;
+
+ @Environmental
+ private FormSupport _formSupport;
+
+ void beginRender()
+ {
+ _formSupport.store(this, new TriggerEvent("BeginSubmit"));
+ }
+
+ void afterRender()
+ {
+ _formSupport.store(this, new TriggerEvent("AfterSubmit"));
+ }
+
+ private void trigger(String eventType)
+ {
+ _resources.triggerEvent(eventType, null, null);
+ }
+}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Zone.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Zone.java?rev=632085&r1=632084&r2=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Zone.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Zone.java Thu Feb 28 10:52:45 2008
@@ -19,7 +19,7 @@
import org.apache.tapestry.annotations.Parameter;
import org.apache.tapestry.annotations.SupportsInformalParameters;
import org.apache.tapestry.dom.Element;
-import org.apache.tapestry.internal.services.ZoneSetup;
+import org.apache.tapestry.internal.services.ClientBehaviorSupport;
import org.apache.tapestry.ioc.annotations.Inject;
import org.apache.tapestry.json.JSONObject;
@@ -65,7 +65,7 @@
private PageRenderSupport _pageRenderSupport;
@Environmental
- private ZoneSetup _zoneSetup;
+ private ClientBehaviorSupport _clientBehaviorSupport;
/**
* If true (the default) then the zone will render normally. If false, then the "t-invisible"
@@ -79,7 +79,7 @@
void beginRender(MarkupWriter writer)
{
- _clientId = _pageRenderSupport.allocateClientId(_resources.getId());
+ _clientId = _pageRenderSupport.allocateClientId(_resources);
Element e = writer.element("div", "id", _clientId);
@@ -94,7 +94,7 @@
JSONObject spec = new JSONObject();
spec.put("div", _clientId);
- _zoneSetup.addZone(_clientId, _show, _update);
+ _clientBehaviorSupport.addZone(_clientId, _show, _update);
}
void afterRender(MarkupWriter writer)
Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/data/InsertPosition.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/data/InsertPosition.java?rev=632085&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/data/InsertPosition.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/data/InsertPosition.java Thu Feb 28 10:52:45 2008
@@ -0,0 +1,26 @@
+// Copyright 2008 The Apache Software Foundation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package org.apache.tapestry.corelib.data;
+
+public enum InsertPosition
+{
+ /**
+ * Insert the new content above (i.e., before) the insertion position.
+ */
+ ABOVE,
+
+ /** Insert the new context below (i.e., after) the insertion position. */
+ BELOW;
+}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/internal/FormSupportImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/internal/FormSupportImpl.java?rev=632085&r1=632084&r2=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/internal/FormSupportImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/internal/FormSupportImpl.java Thu Feb 28 10:52:45 2008
@@ -16,11 +16,10 @@
import org.apache.tapestry.ComponentAction;
import org.apache.tapestry.Field;
+import org.apache.tapestry.internal.services.ClientBehaviorSupport;
import static org.apache.tapestry.ioc.internal.util.CollectionFactory.newList;
import static org.apache.tapestry.ioc.internal.util.Defense.*;
import org.apache.tapestry.ioc.internal.util.IdAllocator;
-import org.apache.tapestry.json.JSONArray;
-import org.apache.tapestry.json.JSONObject;
import org.apache.tapestry.runtime.Component;
import org.apache.tapestry.services.FormSupport;
@@ -29,22 +28,22 @@
import java.util.List;
/**
- * Provides support to components enclosed by a form when the form is rendering (allowing the
- * components to registry form submit callback commands), and also during form submission time.
+ * Provides support to components enclosed by a form when the form is rendering (allowing the components to registry
+ * form submit callback commands), and also during form submission time.
* <p/>
- * TODO: Most methods should only be invokable depending on whether the form is rendering or
- * processing a submission.
+ * TODO: Most methods should only be invokable depending on whether the form is rendering or processing a submission.
*/
public class FormSupportImpl implements FormSupport
{
- private final IdAllocator _idAllocator = new IdAllocator();
+ private final ClientBehaviorSupport _clientBehaviorSupport;
- private final String _clientId;
+ private final boolean _clientValidationEnabled;
- private final ObjectOutputStream _actions;
+ private final IdAllocator _idAllocator;
- private final JSONObject _validations = new JSONObject();
+ private final String _clientId;
+ private final ObjectOutputStream _actions;
private List<Runnable> _commands;
@@ -55,16 +54,34 @@
*/
public FormSupportImpl()
{
- this(null, null);
+ this(null, null, null, false, null);
}
/**
* Constructor used when rendering.
*/
- public FormSupportImpl(String clientId, ObjectOutputStream actions)
+ public FormSupportImpl(String clientId, ObjectOutputStream actions, ClientBehaviorSupport clientBehaviorSupport,
+ boolean clientValidationEnabled)
+ {
+ this(clientId, actions, clientBehaviorSupport, clientValidationEnabled, new IdAllocator());
+ }
+
+ /**
+ * Full constructor.
+ */
+ public FormSupportImpl(String clientId, ObjectOutputStream actions, ClientBehaviorSupport clientBehaviorSupport,
+ boolean clientValidationEnabled, IdAllocator idAllocator)
{
_clientId = clientId;
_actions = actions;
+ _clientBehaviorSupport = clientBehaviorSupport;
+ _clientValidationEnabled = clientValidationEnabled;
+ _idAllocator = idAllocator;
+ }
+
+ public String getFormId()
+ {
+ return _clientId;
}
public String allocateControlName(String id)
@@ -138,39 +155,9 @@
public void addValidation(Field field, String validationName, String message, Object constraint)
{
- String fieldId = field.getClientId();
-
- JSONArray specs;
-
- if (_validations.has(fieldId)) specs = _validations.getJSONArray(fieldId);
- else
- {
- specs = new JSONArray();
- _validations.put(fieldId, specs);
- }
-
- JSONArray thisSpec = new JSONArray();
-
- thisSpec.put(validationName);
- thisSpec.put(message);
-
- if (constraint != null) thisSpec.put(constraint);
-
- specs.put(thisSpec);
+ if (_clientValidationEnabled)
+ _clientBehaviorSupport.addValidation(field, validationName, message, constraint);
}
- /**
- * Returns the combined validation data collected via {@link #addValidation(org.apache.tapestry.Field, String, String, Object)}.
- * The keys of this object are the client ids of the {@link org.apache.tapestry.Field}s, the values
- * are an array of validation specifications for that field. Each validation specification is itself
- * an array of two or three values: the validation name (i.e., a method of the client-side Tapestry.Validation
- * object), the message if the field is invalid and, optionally, the constraint value.
- *
- * @return the validation object
- */
- public JSONObject getValidations()
- {
- return _validations;
- }
}
Copied: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientBehaviorSupport.java (from r630031, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ZoneSetup.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientBehaviorSupport.java?p2=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientBehaviorSupport.java&p1=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ZoneSetup.java&r1=630031&r2=632085&rev=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ZoneSetup.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientBehaviorSupport.java Thu Feb 28 10:52:45 2008
@@ -14,30 +14,32 @@
package org.apache.tapestry.internal.services;
+import org.apache.tapestry.Field;
+import org.apache.tapestry.Link;
+import org.apache.tapestry.corelib.data.InsertPosition;
+
/**
- * Collects details about zone usage for efficient initialization of the client side objects. This has grown
- * to include the client-side behavior associated with {@link org.apache.tapestry.corelib.components.FormFragment}s.
+ * Collects details about zone usage for efficient initialization of the client side objects. This has grown to include
+ * the client-side behavior associated with {@link org.apache.tapestry.corelib.components.FormFragment}s.
*
* @see org.apache.tapestry.corelib.components.Zone
*/
-public interface ZoneSetup
+public interface ClientBehaviorSupport
{
/**
- * Adds a new client-side Tapestry.Zone object. Zones are linked to a
- * an element (typically, a <div>). A Zone may have handlers
- * used to initially show it, or to highlight it when its content changes.
- * Such handlers are referenced by name, as functions of the
- * Tapestry.ZoneEffect object.
+ * Adds a new client-side Tapestry.Zone object. Zones are linked to a an element (typically, a <div>). A Zone
+ * may have handlers used to initially show it, or to highlight it when its content changes. Such handlers are
+ * referenced by name, as functions of the Tapestry.ZoneEffect object.
*
* @param clientId client-side id of the element that will be updated by the zone
- * @param showFunctionName name of the function used to initially show the zone (if not visible), or null for default
+ * @param showFunctionName name of the function used to initially show the zone (if not visible), or null for
+ * default
* @param updateFunctionName name of function used to highlight the function after an update, or null for default
*/
void addZone(String clientId, String showFunctionName, String updateFunctionName);
/**
- * Sets the client-side onclick handler for an <a> element to perform an Ajax update
- * of a zone.
+ * Sets the client-side onclick handler for an <a> element to perform an Ajax update of a zone.
*
* @param linkId id of the link to Ajax enable
* @param elementId id of an element that has been previously registered as a Zone
@@ -45,9 +47,8 @@
void linkZone(String linkId, String elementId);
/**
- * Adds a new client-side Tapestry.FormFragment object. FormFragment's are used to make parts of a
- * client-side form visible or invisible, which involves interactions with both the server-side and client-side
- * validation.
+ * Adds a new client-side Tapestry.FormFragment object. FormFragment's are used to make parts of a client-side form
+ * visible or invisible, which involves interactions with both the server-side and client-side validation.
*
* @param clientId client-side id of the element that will be made visible or invisible
* @param showFunctionName name of function (of the Tapestry.ZoneEffect object) used to make the SubForm visible, or
@@ -55,5 +56,27 @@
* @param hideFunctionName name of the function used to make the SubForm invisible, or null for the default
*/
void addFormFragment(String clientId, String showFunctionName, String hideFunctionName);
+
+ /**
+ * Adds a new client-side Tapestry.FormInjector object. FormInjectors are used to extend an existing Form with new
+ * content.
+ *
+ * @param clientId client-side id of the element that identifiess where the new content will be placed
+ * @param link action request link used to trigger the server-side object, to render the new content
+ * @param insertPosition where the new content should go (above or below the element)
+ * @param showFunctionName name of function (of the Tapestry.ZoneEffect object) used to make the new element
+ * visible, or null for the default
+ */
+ void addFormInjector(String clientId, Link link, InsertPosition insertPosition, String showFunctionName);
+
+ /**
+ * Collects field validation information.
+ *
+ * @param field for which validation is being generated
+ * @param validationName name of validation method (see Tapestry.Validation in tapestry.js)
+ * @param message the error message to display if the field is invalid
+ * @param constraint additional constraint value, or null for validations that don't require a constraint
+ */
+ void addValidation(Field field, String validationName, String message, Object constraint);
}
Copied: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientBehaviorSupportImpl.java (from r630031, tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ZoneSetupImpl.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientBehaviorSupportImpl.java?p2=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientBehaviorSupportImpl.java&p1=tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ZoneSetupImpl.java&r1=630031&r2=632085&rev=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ZoneSetupImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ClientBehaviorSupportImpl.java Thu Feb 28 10:52:45 2008
@@ -14,11 +14,14 @@
package org.apache.tapestry.internal.services;
+import org.apache.tapestry.Field;
+import org.apache.tapestry.Link;
import org.apache.tapestry.PageRenderSupport;
+import org.apache.tapestry.corelib.data.InsertPosition;
import org.apache.tapestry.json.JSONArray;
import org.apache.tapestry.json.JSONObject;
-public class ZoneSetupImpl implements ZoneSetup
+public class ClientBehaviorSupportImpl implements ClientBehaviorSupport
{
static final String ZONE_INITIALIZER_STRING = "Tapestry.initializeZones(%s, %s);";
@@ -30,11 +33,13 @@
private final JSONArray _subForms = new JSONArray();
- private boolean _zonesDirty;
+ private final JSONArray _injectors = new JSONArray();
+
+ private final JSONObject _validations = new JSONObject();
- private boolean _subformsDirty;
+ private boolean _zonesDirty;
- public ZoneSetupImpl(PageRenderSupport pageRenderSupport)
+ public ClientBehaviorSupportImpl(PageRenderSupport pageRenderSupport)
{
_pageRenderSupport = pageRenderSupport;
}
@@ -78,16 +83,57 @@
addFunction(spec, "hide", hideFunctionName);
_subForms.put(spec);
+ }
+
+ public void addFormInjector(String clientId, Link link, InsertPosition insertPosition, String showFunctionName)
+ {
+ JSONObject spec = new JSONObject();
+ spec.put("element", clientId);
+
+ spec.put("url", link.toAbsoluteURI());
+
+ if (insertPosition == InsertPosition.BELOW)
+ spec.put("below", true);
+
+ addFunction(spec, "show", showFunctionName);
+
+ _injectors.put(spec);
+ }
+
+ public void addValidation(Field field, String validationName, String message, Object constraint)
+ {
+ String fieldId = field.getClientId();
+
+ JSONArray specs;
- _subformsDirty = true;
+ if (_validations.has(fieldId)) specs = _validations.getJSONArray(fieldId);
+ else
+ {
+ specs = new JSONArray();
+ _validations.put(fieldId, specs);
+ }
+ JSONArray thisSpec = new JSONArray();
+
+ thisSpec.put(validationName);
+ thisSpec.put(message);
+
+ if (constraint != null) thisSpec.put(constraint);
+
+ specs.put(thisSpec);
}
public void writeInitializationScript()
{
if (_zonesDirty) _pageRenderSupport.addScript(ZONE_INITIALIZER_STRING, _zones, _links);
- if (_subformsDirty)
+ if (_subForms.length() > 0)
_pageRenderSupport.addScript("Tapestry.initializeFormFragments(%s);", _subForms);
+
+ if (_injectors.length() > 0)
+ _pageRenderSupport.addScript("Tapestry.initializeFormInjectors(%s);", _injectors);
+
+ if (_validations.length() > 0)
+ _pageRenderSupport.addScript("Tapestry.registerValidation(%s);", _validations);
}
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueue.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueue.java?rev=632085&r1=632084&r2=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueue.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueue.java Thu Feb 28 10:52:45 2008
@@ -48,7 +48,16 @@
void initializeForPartialPageRender(RenderCommand rootCommand);
/**
- * Returns true if {@link #initializeForPartialPageRender(org.apache.tapestry.runtime.RenderCommand)} has been invoked.
+ * Obtains the value previously supplied to {@link #initializeForPartialPageRender(org.apache.tapestry.runtime.RenderCommand)}.
+ * This allows the "natural" renderer to be substituted or otherwise manipulated.
+ *
+ * @return the root renderer
+ */
+ RenderCommand getRootRenderCommand();
+
+ /**
+ * Returns true if {@link #initializeForPartialPageRender(org.apache.tapestry.runtime.RenderCommand)} has been
+ * invoked.
*/
boolean isPartialRenderInitialized();
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueueImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueueImpl.java?rev=632085&r1=632084&r2=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueueImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderQueueImpl.java Thu Feb 28 10:52:45 2008
@@ -63,6 +63,11 @@
_rootCommand = rootCommand;
}
+ public RenderCommand getRootRenderCommand()
+ {
+ return _rootCommand;
+ }
+
public Page getRenderingPage()
{
return _page;
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderSupportImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderSupportImpl.java?rev=632085&r1=632084&r2=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderSupportImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PageRenderSupportImpl.java Thu Feb 28 10:52:45 2008
@@ -15,6 +15,7 @@
package org.apache.tapestry.internal.services;
import org.apache.tapestry.Asset;
+import org.apache.tapestry.ComponentResources;
import org.apache.tapestry.PageRenderSupport;
import static org.apache.tapestry.ioc.internal.util.Defense.notNull;
import org.apache.tapestry.ioc.internal.util.IdAllocator;
@@ -41,11 +42,11 @@
/**
* @param builder Used to assemble JavaScript includes and snippets
- * @param symbolSource Used to example symbols (in
- * {@linkplain #addClasspathScriptLink(String...) in classpath scripts)
+ * @param symbolSource Used to example symbols (in {@linkplain #addClasspathScriptLink(String...) in classpath
+ * scripts)
* @param assetSource Used to convert classpath scripts to {@link Asset}s
- * @param coreScripts core scripts (evaluated as classpaths scripts) that are added to any page that
- * includes a script link or script block
+ * @param coreScripts core scripts (evaluated as classpaths scripts) that are added to any page that includes a
+ * script link or script block
*/
public PageRenderSupportImpl(DocumentHeadBuilder builder, SymbolSource symbolSource,
AssetSource assetSource, String... coreScripts)
@@ -60,6 +61,11 @@
public String allocateClientId(String id)
{
return _idAllocator.allocateId(id);
+ }
+
+ public String allocateClientId(ComponentResources resources)
+ {
+ return allocateClientId(resources.getId());
}
public void addScriptLink(Asset... scriptAssets)
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PartialRenderPageRenderSupport.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PartialRenderPageRenderSupport.java?rev=632085&r1=632084&r2=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PartialRenderPageRenderSupport.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/PartialRenderPageRenderSupport.java Thu Feb 28 10:52:45 2008
@@ -15,6 +15,7 @@
package org.apache.tapestry.internal.services;
import org.apache.tapestry.Asset;
+import org.apache.tapestry.ComponentResources;
import org.apache.tapestry.PageRenderSupport;
import org.apache.tapestry.ioc.internal.util.IdAllocator;
import org.apache.tapestry.json.JSONObject;
@@ -44,6 +45,11 @@
return _idAllocator.allocateId(id);
}
+ public String allocateClientId(ComponentResources resources)
+ {
+ return allocateClientId(resources.getId());
+ }
+
/**
* Does nothing. Script links are only supported during full page renders, not partials (at this time).
*/
@@ -73,7 +79,8 @@
}
/**
- * Updates the reply with a "script" key, if any scripting has been collected via {@link #addScript(String, Object[])} }.
+ * Updates the reply with a "script" key, if any scripting has been collected via {@link #addScript(String,
+ * Object[])} }.
*
* @param reply
*/
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java?rev=632085&r1=632084&r2=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/ComponentPageElementImpl.java Thu Feb 28 10:52:45 2008
@@ -1065,9 +1065,9 @@
return _page.getLocale();
}
- public String getElementName()
+ public String getElementName(String defaultElementName)
{
- return _elementName;
+ return _elementName != null ? _elementName : defaultElementName;
}
public Block getBlock(String id)
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java?rev=632085&r1=632084&r2=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/structure/InternalComponentResourcesImpl.java Thu Feb 28 10:52:45 2008
@@ -134,6 +134,10 @@
_page.discardPersistentFieldChanges();
}
+ public String getElementName()
+ {
+ return getElementName(null);
+ }
public String getCompleteId()
{
@@ -347,9 +351,9 @@
return _messages;
}
- public String getElementName()
+ public String getElementName(String defaultElementName)
{
- return _element.getElementName();
+ return _element.getElementName(defaultElementName);
}
public void queueRender(RenderQueue queue)
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableRequestImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableRequestImpl.java?rev=632085&r1=632084&r2=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableRequestImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/test/TestableRequestImpl.java Thu Feb 28 10:52:45 2008
@@ -91,7 +91,9 @@
public String[] getParameters(String name)
{
- return nyi("getParameters");
+ String value = getParameter(name);
+
+ return value == null ? null : new String[] { value };
}
public String getPath()
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/FormSupport.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/FormSupport.java?rev=632085&r1=632084&r2=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/FormSupport.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/FormSupport.java Thu Feb 28 10:52:45 2008
@@ -19,35 +19,31 @@
import org.apache.tapestry.Field;
/**
- * Services provided by an enclosing Form control component to the various form element components
- * it encloses. Implements {@link ClientElement}, to share the id of the enclosing form.
+ * Services provided by an enclosing Form control component to the various form element components it encloses.
+ * Implements {@link org.apache.tapestry.ClientElement}, to share the id of the enclosing form.
*
* @see org.apache.tapestry.Field
*/
public interface FormSupport extends ClientElement
{
/**
- * Allocates a unique (within the form) control name for some enclosed component,
- * based on the component's id.
+ * Allocates a unique (within the form) control name for some enclosed component, based on the component's id.
*
* @param id the component's id
- * @return a unique string, usually the component's id, but sometime extended with a unique
- * number or string
+ * @return a unique string, usually the component's id, but sometime extended with a unique number or string
*/
String allocateControlName(String id);
/**
- * Stores an action for execution during a later request. If the action contains any mutable
- * state, it should be in its final state before invoking this method and its internal
- * state should not be changed subsequently.
+ * Stores an action for execution during a later request. If the action contains any mutable state, it should be in
+ * its final state before invoking this method and its internal state should not be changed subsequently.
*/
<T> void store(T component, ComponentAction<T> action);
/**
- * As with {@link #store(Object, org.apache.tapestry.ComponentAction)}}, but the
- * action is also invoked immediately. This is useful for defining an action that
- * should occur symmetrically in both the render request and the form submission's
- * action request.
+ * As with {@link #store(Object, org.apache.tapestry.ComponentAction)}}, but the action is also invoked immediately.
+ * This is useful for defining an action that should occur symmetrically in both the render request and the form
+ * submission's action request.
*
* @param component component against which to trigger the action
* @param action the action that will be triggered (and passed the component)
@@ -55,11 +51,11 @@
<T> void storeAndExecute(T component, ComponentAction<T> action);
/**
- * Defers a command until the end of the form submission. The command will be executed after the
- * Form's validate notification, but before the Form's submit, success or failure notifications.
- * During a form render, runnables are executed after the body of the form has rendered.
+ * Defers a command until the end of the form submission. The command will be executed after the Form's validate
+ * notification, but before the Form's submit, success or failure notifications. During a form render, runnables are
+ * executed after the body of the form has rendered.
*
- * @param command
+ * @param command to be executed
*/
void defer(Runnable command);
@@ -72,7 +68,8 @@
void setEncodingType(String encodingType);
/**
- * Collects field validation information.
+ * Collects field validation information. A Form may turn off client-side validation, in which case these calls will
+ * be ignored.
*
* @param field for which validation is being generated
* @param validationName name of validation method (see Tapestry.Validation in tapestry.js)
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java?rev=632085&r1=632084&r2=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/TapestryModule.java Thu Feb 28 10:52:45 2008
@@ -18,6 +18,7 @@
import org.apache.tapestry.annotations.*;
import org.apache.tapestry.beaneditor.Validate;
import org.apache.tapestry.corelib.data.GridPagerPosition;
+import org.apache.tapestry.corelib.data.InsertPosition;
import org.apache.tapestry.grid.GridDataSource;
import org.apache.tapestry.internal.*;
import org.apache.tapestry.internal.beaneditor.PrimitiveFieldConstraintGenerator;
@@ -563,9 +564,12 @@
}
/**
- * Adds coercions: <ul> <li>String to {@link SelectModel} <li>Map to {@link SelectModel} <li>Collection to {@link
- * GridDataSource} <li>null to {@link GridDataSource} <li>String to {@link GridPagerPosition} <li>List to {@link
- * SelectModel} <li>{@link ComponentResourcesAware} (typically, a component) to {@link ComponentResources} </ul>
+ * Adds coercions: <ul> <li>String to {@link org.apache.tapestry.SelectModel} <li>String to {@link
+ * org.apache.tapestry.corelib.data.InsertPosition} <li>Map to {@link org.apache.tapestry.SelectModel}
+ * <li>Collection to {@link GridDataSource} <li>null to {@link org.apache.tapestry.grid.GridDataSource} <li>String
+ * to {@link org.apache.tapestry.corelib.data.GridPagerPosition} <li>List to {@link SelectModel} <li>{@link
+ * org.apache.tapestry.runtime.ComponentResourcesAware} (typically, a component) to {@link
+ * org.apache.tapestry.ComponentResources} </ul>
*/
public static void contributeTypeCoercer(Configuration<CoercionTuple> configuration)
{
@@ -605,7 +609,9 @@
});
add(configuration, String.class, GridPagerPosition.class,
- new StringToEnumCoercion<GridPagerPosition>(GridPagerPosition.class));
+ StringToEnumCoercion.create(GridPagerPosition.class));
+
+ add(configuration, String.class, InsertPosition.class, StringToEnumCoercion.create(InsertPosition.class));
add(configuration, List.class, SelectModel.class, new Coercion<List, SelectModel>()
{
@@ -1291,10 +1297,11 @@
/**
* Adds page render filters, each of which provides an {@link org.apache.tapestry.annotations.Environmental}
* service. Filters often provide {@link Environmental} services needed by components as they render. <dl>
- * <dt>PageRenderSupport</dt> <dd>Provides {@link PageRenderSupport}</dd> <dt>ZoneSetup</dt> <dd>Provides {@link
- * ZoneSetup}</dd> <dt>Heartbeat</dt> <dd>Provides {@link org.apache.tapestry.services.Heartbeat}</dd>
- * <dt>DefaultValidationDecorator</dt> <dd>Provides {@link org.apache.tapestry.ValidationDecorator} (as an instance
- * of {@link org.apache.tapestry.internal.DefaultValidationDecorator})</dd> </dl>
+ * <dt>PageRenderSupport</dt> <dd>Provides {@link PageRenderSupport}</dd> <dt>ClientBehaviorSupport</dt>
+ * <dd>Provides {@link org.apache.tapestry.internal.services.ClientBehaviorSupport}</dd> <dt>Heartbeat</dt>
+ * <dd>Provides {@link org.apache.tapestry.services.Heartbeat}</dd> <dt>DefaultValidationDecorator</dt> <dd>Provides
+ * {@link org.apache.tapestry.ValidationDecorator} (as an instance of {@link org.apache.tapestry.internal.DefaultValidationDecorator})</dd>
+ * </dl>
*/
public void contributeMarkupRenderer(OrderedConfiguration<MarkupRendererFilter> configuration,
@@ -1340,21 +1347,21 @@
}
};
- MarkupRendererFilter zoneSetup = new MarkupRendererFilter()
+ MarkupRendererFilter clientBehaviorSupport = new MarkupRendererFilter()
{
public void renderMarkup(MarkupWriter writer, MarkupRenderer renderer)
{
PageRenderSupport pageRenderSupport = _environment.peekRequired(PageRenderSupport.class);
- ZoneSetupImpl setup = new ZoneSetupImpl(pageRenderSupport);
+ ClientBehaviorSupportImpl clientBehaviorSupport = new ClientBehaviorSupportImpl(pageRenderSupport);
- _environment.push(ZoneSetup.class, setup);
+ _environment.push(ClientBehaviorSupport.class, clientBehaviorSupport);
renderer.renderMarkup(writer);
- _environment.pop(ZoneSetup.class);
+ _environment.pop(ClientBehaviorSupport.class);
- setup.writeInitializationScript();
+ clientBehaviorSupport.writeInitializationScript();
}
};
@@ -1395,7 +1402,7 @@
configuration.add("PageRenderSupport", pageRenderSupport);
- configuration.add("ZoneSetup", zoneSetup, "after:PageRenderSupport");
+ configuration.add("ClientBehaviorSupport", clientBehaviorSupport, "after:PageRenderSupport");
configuration.add("Heartbeat", heartbeat, "after:PageRenderSupport");
configuration.add("DefaultValidationDecorator", defaultValidationDecorator, "after:Heartbeat");
}
@@ -1409,8 +1416,8 @@
* @param configuration filters for the service
* @param renderQueue does most of the work
* @return the service
- * @see #contributePartialMarkupRenderer(org.apache.tapestry.ioc.OrderedConfiguration,
- * org.apache.tapestry.internal.services.AjaxUIDManager, org.apache.tapestry.Asset, ValidationMessagesSource)
+ * @see #contributePartialMarkupRenderer(org.apache.tapestry.ioc.OrderedConfiguration, org.apache.tapestry.Asset,
+ * ValidationMessagesSource)
*/
public PartialMarkupRenderer buildPartialMarkupRenderer(Logger logger,
List<PartialMarkupRendererFilter> configuration,
@@ -1434,15 +1441,14 @@
* to {@link #contributeMarkupRenderer(org.apache.tapestry.ioc.OrderedConfiguration, org.apache.tapestry.Asset,
* org.apache.tapestry.Asset, ValidationMessagesSource, org.apache.tapestry.ioc.services.SymbolSource, AssetSource)}
* } and overlaps it to some degree. <dl> <dt> PageRenderSupport </dt> <dd>Provides {@link
- * org.apache.tapestry.PageRenderSupport}</dd> <dt>ZoneSetup</dt> <dd>Provides {@link ZoneSetup}</dd>
- * <dt>Heartbeat</dt> <dd>Provides {@link org.apache.tapestry.services.Heartbeat}</dd>
- * <dt>DefaultValidationDecorator</dt> <dd>Provides {@link org.apache.tapestry.ValidationDecorator} (as an instance
- * of {@link org.apache.tapestry.internal.DefaultValidationDecorator})</dd> </dl>
+ * org.apache.tapestry.PageRenderSupport}</dd> <dt>ClientBehaviorSupport</dt> <dd>Provides {@link
+ * org.apache.tapestry.internal.services.ClientBehaviorSupport}</dd> <dt>Heartbeat</dt> <dd>Provides {@link
+ * org.apache.tapestry.services.Heartbeat}</dd> <dt>DefaultValidationDecorator</dt> <dd>Provides {@link
+ * org.apache.tapestry.ValidationDecorator} (as an instance of {@link org.apache.tapestry.internal.DefaultValidationDecorator})</dd>
+ * </dl>
*/
public void contributePartialMarkupRenderer(OrderedConfiguration<PartialMarkupRendererFilter> configuration,
- final AjaxUIDManager ajaxUIDManager,
-
@Path("${tapestry.field-error-marker}")
final Asset fieldErrorIcon,
@@ -1452,7 +1458,9 @@
{
public void renderMarkup(MarkupWriter writer, JSONObject reply, PartialMarkupRenderer renderer)
{
- String namespace = ":" + ajaxUIDManager.getAjaxUID();
+ String uid = Long.toHexString(System.currentTimeMillis());
+
+ String namespace = ":" + uid;
PartialRenderPageRenderSupport support = new PartialRenderPageRenderSupport(
namespace);
@@ -1467,21 +1475,21 @@
}
};
- PartialMarkupRendererFilter zoneSupport = new PartialMarkupRendererFilter()
+ PartialMarkupRendererFilter clientBehaviorSupport = new PartialMarkupRendererFilter()
{
public void renderMarkup(MarkupWriter writer, JSONObject reply, PartialMarkupRenderer renderer)
{
PageRenderSupport pageRenderSupport = _environment.peekRequired(PageRenderSupport.class);
- ZoneSetupImpl setup = new ZoneSetupImpl(pageRenderSupport);
+ ClientBehaviorSupportImpl support = new ClientBehaviorSupportImpl(pageRenderSupport);
- _environment.push(ZoneSetup.class, setup);
+ _environment.push(ClientBehaviorSupport.class, support);
renderer.renderMarkup(writer, reply);
- _environment.pop(ZoneSetup.class);
+ _environment.pop(ClientBehaviorSupport.class);
- setup.writeInitializationScript();
+ support.writeInitializationScript();
}
};
@@ -1522,7 +1530,7 @@
configuration.add("PageRenderSupport", pageRenderSupport);
- configuration.add("ZoneSupport", zoneSupport, "after:PageRenderSupport");
+ configuration.add("ClientBehaviorSupport", clientBehaviorSupport, "after:PageRenderSupport");
configuration.add("Heartbeat", heartbeat, "after:PageRenderSupport");
configuration.add("DefaultValidationDecorator", defaultValidationDecorator, "after:Heartbeat");
}
@@ -2152,14 +2160,5 @@
{
configuration.add("default", new DefaultNullFieldStrategy());
configuration.add("zero", new ZeroNullFieldStrategy());
- }
-
- public static AjaxUIDManager buildAjaxUIDManager(LinkFactory linkFactory, ServiceResources resources)
- {
- AjaxUIDManagerImpl service = resources.autobuild(AjaxUIDManagerImpl.class);
-
- linkFactory.addListener(service);
-
- return service;
}
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/util/StringToEnumCoercion.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/util/StringToEnumCoercion.java?rev=632085&r1=632084&r2=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/util/StringToEnumCoercion.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/util/StringToEnumCoercion.java Thu Feb 28 10:52:45 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
@@ -21,12 +21,11 @@
import java.util.Map;
/**
- * A {@link Coercion} for converting strings into an instance of a particular enumerated type. The
- * {@link Enum#name() name} is used as the key to identify the enum instance, in a case-insensitive
+ * A {@link org.apache.tapestry.ioc.services.Coercion} for converting strings into an instance of a particular
+ * enumerated type. The {@link Enum#name() name} is used as the key to identify the enum instance, in a case-insensitive
* fashion.
*
- * @param <T>
- * the type of enumeration
+ * @param <T> the type of enumeration
*/
public final class StringToEnumCoercion<T extends Enum> implements Coercion<String, T>
{
@@ -61,6 +60,12 @@
_stringToEnum.keySet()));
return result;
+ }
+
+
+ public static <T extends Enum> StringToEnumCoercion<T> create(Class<T> enumClass)
+ {
+ return new StringToEnumCoercion<T>(enumClass);
}
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js?rev=632085&r1=632084&r2=632085&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js Thu Feb 28 10:52:45 2008
@@ -24,6 +24,8 @@
FormFragment : Class.create(),
+ FormInjector : Class.create(),
+
ErrorPopup : Class.create(),
// An array of ErrorPopup that have been created for fields within the page
@@ -39,11 +41,11 @@
document.observe("dom:loaded", callback);
},
- // Find all elements marked with the "t-invisible" CSS class and hide() them, so that
- // Prototype's visible() method operates correctly. This is invoked when the
- // DOM is first loaded, and AGAIN whenever dynamic content is loaded via the Zone
- // mechanism.
-
+ /** Find all elements marked with the "t-invisible" CSS class and hide()s them, so that
+ * Prototype's visible() method operates correctly. This is invoked when the
+ * DOM is first loaded, and AGAIN whenever dynamic content is loaded via the Zone
+ * mechanism. In addition, adds a focus listener for each form element.
+ */
onDomLoadedCallback : function()
{
$$(".t-invisible").each(function(element)
@@ -78,18 +80,17 @@
});
},
- registerForm : function(form, clientValidations)
- {
- new Tapestry.FormEventManager(form);
-
- this.registerValidations(form, clientValidations);
- },
-
- registerValidations : function(form, clientValidations)
+ registerValidation : function(clientValidations)
{
$H(clientValidations).each(function(pair)
{
var field = $(pair.key);
+
+ var form = $(field.form);
+
+ if (! form.eventManager)
+ form.eventManager = new Tapestry.FormEventManager(form);
+
var specs = pair.value;
specs.each(function(spec)
@@ -115,9 +116,22 @@
});
},
- // Convert a form or link into a trigger of an Ajax update that
- // updates the indicated Zone.
-
+ /**
+ * Passed the JSON content of a Tapestry partial markup response, extracts
+ * the script key (if present) and evals it, then uses the DOM loaded callback
+ * to hide invisible fields and add notifications for any form elements.
+ */
+ processScriptInReply : function(reply)
+ {
+ if (reply.script != undefined)
+ eval(reply.script);
+
+ Tapestry.onDomLoadedCallback();
+ },
+
+ /** Convert a form or link into a trigger of an Ajax update that
+ * updates the indicated Zone.
+ */
linkZone : function(element, zoneDiv)
{
element = $(element);
@@ -125,20 +139,13 @@
var successHandler = function(transport)
{
- var response = transport.responseText;
- var reply = eval("(" + response + ")");
+ var reply = transport.responseJSON;
zone.show(reply.content);
- var newScript = reply.script;
-
- if (newScript != undefined)
- eval(newScript);
-
- Tapestry.onDomLoadedCallback();
+ Tapestry.processScriptInReply(reply);
};
-
if (element.tagName == "FORM")
{
// The existing handler, if present, will be responsible for form validations, which must
@@ -207,6 +214,14 @@
});
},
+ initializeFormInjectors : function(specs)
+ {
+ $A(specs).each(function(spec)
+ {
+ new Tapestry.FormInjector(spec);
+ });
+ },
+
// Links a FormFragment to a checkbox, such that changing the checkbox will hide
// or show the FormFragment. Care should be taken to render the page with the
@@ -490,7 +505,6 @@
initialize : function(form)
{
this.form = $(form);
- this.form.eventManager = this;
this.form.onsubmit = this.handleSubmit.bindAsEventListener(this);
},
@@ -522,7 +536,6 @@
this.form.fire("form:prepareforsubmit");
}
-
return event.result;
}
@@ -775,5 +788,55 @@
}
};
-Tapestry.onDOMLoaded(Tapestry.onDomLoadedCallback);
+Tapestry.FormInjector.prototype = {
+
+ initialize: function(spec)
+ {
+ this.element = $(spec.element);
+ this.url = spec.url;
+ this.below = spec.below;
+
+ this.showFunc = Tapestry.ZoneEffect[spec.show] || Tapestry.ZoneEffect.highlight;
+
+ this.element.trigger = function()
+ {
+ var successHandler = function(transport)
+ {
+ var reply = transport.responseJSON;
+
+ // Clone the FormInjector element (usually a div)
+ // to create the new element, that gets inserted
+ // before or after the FormInjector element.
+
+ var newElement = new Element(this.element.tagName);
+
+ newElement.innerHTML = reply.content;
+
+ // Insert the new content before or after the existing element.
+
+ var param = { };
+ var key = this.below ? "after" : "before";
+ param[key] = newElement;
+
+ // Add the new element with the downloaded content.
+
+ this.element.insert(param);
+
+ // Add some animation
+
+ this.showFunc(newElement);
+
+ // Handle any scripting issues.
+
+ Tapestry.processScriptInReply(reply);
+ }.bind(this);
+
+ new Ajax.Request(this.url, { onSuccess : successHandler });
+
+ return false;
+ }.bind(this);
+ }
+};
+
+Tapestry.onDOMLoaded(Tapestry.onDomLoadedCallback);
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/FormInjectorDemo.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/FormInjectorDemo.tml?rev=632085&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/FormInjectorDemo.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/FormInjectorDemo.tml Thu Feb 28 10:52:45 2008
@@ -0,0 +1,32 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+
+ <t:form>
+
+ <t:block id="newRow">
+
+ <div class="t-beaneditor-row">
+ <t:submitnotifier>
+ <t:textfield t:id="value"/>
+ </t:submitnotifier>
+ </div>
+
+ </t:block>
+
+ <div t:id="forminjector" class="t-beaneditor-row">
+ <a href="#" id="addnewrow">Add a row</a>
+ </div>
+
+ <div class="t-beaneditor-row">
+ <input type="submit" value="Sum up the values"/>
+ </div>
+
+ </t:form>
+
+ <p>
+ Current sum:
+ <span id="sum">${sum}</span>
+ </p>
+
+
+</html>
\ No newline at end of file