You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2008/02/19 02:44:17 UTC

svn commit: r628957 [1/2] - in /tapestry/tapestry5/trunk: tapestry-core/src/main/java/org/apache/tapestry/ tapestry-core/src/main/java/org/apache/tapestry/corelib/base/ tapestry-core/src/main/java/org/apache/tapestry/corelib/components/ tapestry-core/s...

Author: hlship
Date: Mon Feb 18 17:44:04 2008
New Revision: 628957

URL: http://svn.apache.org/viewvc?rev=628957&view=rev
Log:
TAPESTRY-1650: Add the FormFragment component and TriggerFragment mixin

Added:
    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/FormFragment.xdoc
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/internal/WrappedComponentAction.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/TriggerFragment.xdoc
    tapestry/tapestry5/trunk/tapestry-core/src/site/apt/upgrade.apt
    tapestry/tapestry5/trunk/tapestry-core/src/site/apt/upgrade4.apt
      - copied unchanged from r617192, tapestry/tapestry5/trunk/tapestry-core/src/site/apt/upgrade.apt
    tapestry/tapestry5/trunk/tapestry-core/src/test/app1/FormFragmentDemo.tml
    tapestry/tapestry5/trunk/tapestry-core/src/test/app1/FormFragmentOutput.tml
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/SubscribeData.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormFragmentDemo.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormFragmentOutput.java
Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/Field.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ValidationTracker.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ValidationTrackerImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractField.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractTextField.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditor.xdoc
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Checkbox.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/DateField.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.xdoc
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Palette.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PasswordField.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/RadioGroup.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Select.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Submit.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextArea.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextField.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/ZoneSetup.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ZoneSetupImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentSource.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/Environment.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/FormSupport.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/default.css
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/tapestry.js
    tapestry/tapestry5/trunk/tapestry-core/src/site/site.xml
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/ValidationTrackerImplTest.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.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/services/ZoneSetupImplTest.java
    tapestry/tapestry5/trunk/tapestry-upload/src/main/java/org/apache/tapestry/upload/components/Upload.java

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/Field.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/Field.java?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/Field.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/Field.java Mon Feb 18 17:44:04 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.
@@ -15,15 +15,24 @@
 package org.apache.tapestry;
 
 /**
- * Defines a field within a form.
+ * Defines a field within a form.  Fields have a <a href="http://www.w3.org/TR/html4/interact/forms.html#control-name">control name</a>
+ * that is used when rendering and, later, when the form is submitted, to identify the query parameter.
+ * <p/>
+ * Timing is important, as components may render multiple times, due to looping and other factors. Generally,
+ * a component's {@link #getControlName()} will only be accurate after it has rendered.  In some
+ * cases, when generating JavaScript for example, it is necessary to
+ * {@linkplain org.apache.tapestry.services.Heartbeat#defer(Runnable) wait until the end of the current Heartbeat} to ensure
+ * that all components have had thier chance to render.
  */
 public interface Field extends ClientElement
 {
     /**
      * Returns the value used as the name attribute of the rendered element. This value will be
      * unique within an enclosing form, even if the same component renders multiple times.
+     *
+     * @see org.apache.tapestry.services.FormSupport#allocateControlName(String)
      */
-    String getElementName();
+    String getControlName();
 
     /**
      * Returns a user presentable (localized) label for the field, which may be used inside
@@ -31,6 +40,7 @@
      * messages.
      *
      * @return the label
+     * @see org.apache.tapestry.corelib.components.Label
      */
     String getLabel();
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ValidationTracker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ValidationTracker.java?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ValidationTracker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ValidationTracker.java Mon Feb 18 17:44:04 2008
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 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.
@@ -30,7 +30,7 @@
  * to render itself multiple times within a request, because of {@link Loop} or other similar
  * components.
  * <p/>
- * Internally, the tracker indexes its information in terms of the {@link Field#getElementName()}
+ * Internally, the tracker indexes its information in terms of the {@linkplain Field#getControlName() control name}
  * for each rendering of the component (the mechanics of Tapestry ensures that this is unique within
  * the form).
  * <p/>

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ValidationTrackerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ValidationTrackerImpl.java?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ValidationTrackerImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/ValidationTrackerImpl.java Mon Feb 18 17:44:04 2008
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 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.
@@ -95,7 +95,7 @@
 
     private FieldTracker get(Field field)
     {
-        String key = field.getElementName();
+        String key = field.getControlName();
 
         refreshFieldToTracker();
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractField.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractField.java?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractField.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractField.java Mon Feb 18 17:44:04 2008
@@ -70,16 +70,16 @@
     {
         private static final long serialVersionUID = 2690270808212097020L;
 
-        private final String _elementName;
+        private final String _controlName;
 
-        public SetupAction(final String elementName)
+        public SetupAction(String controlName)
         {
-            _elementName = elementName;
+            _controlName = controlName;
         }
 
         public void execute(AbstractField component)
         {
-            component.setupElementName(_elementName);
+            component.setupControlName(_controlName);
         }
     }
 
@@ -108,7 +108,7 @@
 
     private String _assignedClientId;
 
-    private String _elementName;
+    private String _controlName;
 
     @Environmental
     private FormSupport _formSupport;
@@ -140,14 +140,14 @@
 
         String id = _clientId;
 
-        // Often, these elementName and _clientId will end up as the same value. There are many
+        // Often, these controlName and _clientId will end up as the same value. There are many
         // exceptions, including a form that renders inside a loop, or a form inside a component
         // that is used multiple times.
 
         _assignedClientId = _pageRenderSupport.allocateClientId(id);
-        String elementName = _formSupport.allocateElementName(id);
+        String controlName = _formSupport.allocateControlName(id);
 
-        _formSupport.storeAndExecute(this, new SetupAction(elementName));
+        _formSupport.storeAndExecute(this, new SetupAction(controlName));
         _formSupport.store(this, PROCESS_SUBMISSION_ACTION);
     }
 
@@ -156,9 +156,9 @@
         return _assignedClientId;
     }
 
-    public final String getElementName()
+    public final String getControlName()
     {
-        return _elementName;
+        return _controlName;
     }
 
     public final boolean isDisabled()
@@ -169,14 +169,14 @@
     /**
      * Invoked from within a ComponentCommand callback, to restore the component's elementName.
      */
-    private void setupElementName(String elementName)
+    private void setupControlName(String controlName)
     {
-        _elementName = elementName;
+        _controlName = controlName;
     }
 
     private void processSubmission()
     {
-        if (!_disabled) processSubmission(_elementName);
+        if (!_disabled) processSubmission(_controlName);
     }
 
     /**

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractTextField.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractTextField.java?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractTextField.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/base/AbstractTextField.java Mon Feb 18 17:44:04 2008
@@ -160,7 +160,7 @@
 
     /**
      * Invoked from {@link #begin(MarkupWriter)} to write out the element and attributes (typically, &lt;input&gt;). The
-     * {@link AbstractField#getElementName() elementName} and {@link AbstractField#getClientId() clientId} properties
+     * {@linkplain AbstractField#getControlName() controlName} and {@linkplain AbstractField#getClientId() clientId} properties
      * will already have been set or updated.
      * <p/>
      * Generally, the subclass will invoke {@link MarkupWriter#element(String, Object[])}, and will be responsible for

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditor.xdoc
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditor.xdoc?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditor.xdoc (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/BeanEditor.xdoc Mon Feb 18 17:44:04 2008
@@ -2,7 +2,10 @@
     <body>
         <p>See the
             <a href="BeanEditForm.html">BeanEditForm</a>
-            documentation for examples of how to use and customize this component.
+            documentation for examples of how to use and customize this component. A further
+            example is available in the documentation for the
+            <a href="FormFragment.html">FormFragment</a>
+            component.
         </p>
     </body>
 </document>

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Checkbox.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Checkbox.java?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Checkbox.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Checkbox.java Mon Feb 18 17:44:04 2008
@@ -63,7 +63,7 @@
 
         writer.element("input", "type", "checkbox",
 
-                       "name", getElementName(),
+                       "name", getControlName(),
 
                        "id", getClientId(),
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/DateField.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/DateField.java?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/DateField.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/DateField.java Mon Feb 18 17:44:04 2008
@@ -128,7 +128,7 @@
 
                        "type", "text",
 
-                       "name", getElementName(),
+                       "name", getControlName(),
 
                        "id", clientId,
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.xdoc
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.xdoc?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.xdoc (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Form.xdoc Mon Feb 18 17:44:04 2008
@@ -11,6 +11,9 @@
                     <a href="Errors.html">Errors</a>
                 </li>
                 <li>
+                    <a href="FormFragment.html">FormFragment</a>
+                </li>
+                <li>
                     <a href="Label.html">Label</a>
                 </li>
             </ul>

Added: 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=628957&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormFragment.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormFragment.java Mon Feb 18 17:44:04 2008
@@ -0,0 +1,218 @@
+// 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.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.ioc.annotations.Inject;
+import org.apache.tapestry.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry.ioc.internal.util.Defense;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.ComponentSource;
+import org.apache.tapestry.services.Environment;
+import org.apache.tapestry.services.FormSupport;
+import org.apache.tapestry.services.Request;
+
+import java.util.List;
+
+/**
+ * A SubForm is a portion of a Form that may be selectively displayed.  Form elements inside a FormFragment
+ * will automatically bypass validation when the fragment is invisible.  The trick is to also bypass server-side
+ * form processing for such fields when the form is submitted; the fragment uses a hidden field
+ * to track its client-side visibility and will bypass field component submission logic for
+ * the components it encloses.
+ *
+ * @see org.apache.tapestry.corelib.mixins.TriggerFragment
+ */
+@SupportsInformalParameters
+public class FormFragment implements ClientElement
+{
+    /**
+     * Determines if the fragment is intially visible or initially invisible (the default). This is
+     * only used when rendering; when the form is submitted, the hidden field value
+     * is used to determine whether the elements within the fragment should be processed (or ignored
+     * if still invisible).
+     */
+    @Parameter
+    private boolean _visible;
+
+
+    /**
+     * Name of a function on the client-side Tapestry.ZoneEffect object that is invoked to
+     * make the fragment  visible.  If not specified, then
+     * the default "slidedown" function is used.
+     */
+    @Parameter(defaultPrefix = TapestryConstants.LITERAL_BINDING_PREFIX)
+    private String _show;
+
+    /**
+     * Name of a function on the client-side Tapestry.ZoneEffect object that is invoked
+     * when the fragment is to be hidden. If not specified, the default "slideup" function is used.
+     */
+    @Parameter(defaultPrefix = TapestryConstants.LITERAL_BINDING_PREFIX)
+    private String _hide;
+
+    @Inject
+    private Environment _environment;
+
+    @Environmental
+    private PageRenderSupport _pageRenderSupport;
+
+
+    @Inject
+    private ComponentSource _componentSource;
+
+    @Inject
+    private ComponentResources _resources;
+
+    @Environmental
+    private ZoneSetup _zoneSetup;
+
+    private String _clientId;
+
+    private String _controlName;
+
+    private List<WrappedComponentAction> _componentActions;
+
+    @Inject
+    private Request _request;
+
+    static class HandleSubmission implements ComponentAction<FormFragment>
+    {
+        private final String _controlName;
+
+        private final List<WrappedComponentAction> _actions;
+
+        public HandleSubmission(String controlName, List<WrappedComponentAction> actions)
+        {
+            _controlName = controlName;
+            _actions = actions;
+        }
+
+        public void execute(FormFragment component)
+        {
+            component.handleSubmission(_controlName, _actions);
+        }
+    }
+
+
+    private void handleSubmission(String elementName, List<WrappedComponentAction> actions)
+    {
+        String value = _request.getParameter(elementName);
+
+        boolean visible = Boolean.parseBoolean(value);
+
+        if (!visible) return;
+
+        // Note that we DON'T update the visible parameter, it is read only.
+
+        for (WrappedComponentAction action : actions)
+        {
+            action.execute(_componentSource);
+        }
+    }
+
+    /**
+     * Renders a &lt;div&gt; tag and provides an override of the {@link org.apache.tapestry.services.FormSupport} environmental.
+     */
+    void beginRender(MarkupWriter writer)
+    {
+        FormSupport formSupport = _environment.peekRequired(FormSupport.class);
+
+        String id = _resources.getId();
+
+        _controlName = formSupport.allocateControlName(id);
+        _clientId = _pageRenderSupport.allocateClientId(id);
+
+        Element element = writer.element("div", "id", _clientId);
+
+        _resources.renderInformalParameters(writer);
+
+        if (!_visible)
+            element.addClassName(TapestryConstants.INVISIBLE_CLASS);
+
+
+        writer.element("input",
+
+                       "type", "hidden",
+
+                       "name", _controlName,
+
+                       "id", _clientId + ":hidden",
+
+                       "value", String.valueOf(_visible));
+        writer.end();
+
+
+        _zoneSetup.addFormFragment(_clientId, _show, _hide);
+
+        _componentActions = CollectionFactory.newList();
+
+        // Here's the magic of environmentals ... we can create a wrapper around
+        // the normal FormSupport environmental that intercepts some of the behavior.
+        // Here we're setting aside all the actions inside the FormFragment so that we
+        // can control whether those actions occur when the form is submitted.
+
+        FormSupport override = new FormSupportAdapter(formSupport)
+        {
+            @Override
+            public <T> void store(T component, ComponentAction<T> action)
+            {
+                Component asComponent = Defense.cast(component, Component.class, "component");
+
+                _componentActions.add(new WrappedComponentAction(asComponent, action));
+            }
+
+            @Override
+            public <T> void storeAndExecute(T component, ComponentAction<T> action)
+            {
+                store(component, action);
+
+                action.execute(component);
+            }
+        };
+
+        // Tada!  Now all the enclosed components will use our override of FormSupport,
+        // until we pop it off.
+
+        _environment.push(FormSupport.class, override);
+
+    }
+
+    /**
+     * Closes the &lt;div&gt; tag and pops off the {@link org.apache.tapestry.services.FormSupport} environmental override.
+     *
+     * @param writer
+     */
+    void afterRender(MarkupWriter writer)
+    {
+        writer.end(); // div
+
+        _environment.pop(FormSupport.class);
+
+        _environment.peek(FormSupport.class).store(this, new HandleSubmission(_controlName, _componentActions));
+    }
+
+    public String getClientId()
+    {
+        return _clientId;
+    }
+}

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormFragment.xdoc
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormFragment.xdoc?rev=628957&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormFragment.xdoc (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/FormFragment.xdoc Mon Feb 18 17:44:04 2008
@@ -0,0 +1,178 @@
+<document>
+    <body>
+        <section name="Related Components">
+
+            <ul>
+                <li>
+                    <a href="Form.html">Form</a>
+                </li>
+            </ul>
+        </section>
+
+        <section name="Examples">
+
+            <p>
+                This example will collect a billing address for an order and, optionally, a separate
+                shipping address. Initially, the form will render just the billing address fields:
+            </p>
+
+            <p>
+                <img src="formfragment_ref_1.png"/>
+            </p>
+
+
+            <p>
+                Clicking the checkbox will trigger an animation that slides down the
+                remainder of the form.
+            </p>
+
+            <p>
+                <img src="formfragment_ref_2.png"/>
+            </p>
+
+
+            <p>
+                The FormFragment component ensures that client-side validation is only enabled for fields
+                that are actually visible to the user. In addition, for fields that are enclosed within the
+                FormFragment,
+                server-side validation and processing only occurs if the fields were visible to the user when the
+                client-side
+                form was submitted.
+            </p>
+
+            <subsection name="OrderAddress.tml">
+                <source><![CDATA[
+<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <body>
+        <h1>Order Address</h1>
+
+        <t:form>
+
+            <t:errors/>
+
+            <div class="t-beaneditor">
+
+                <h2>Billing Address</h2>
+
+                <t:beaneditor t:id="billingAddress"/>
+
+                <t:checkbox t:id="separateShipTo" t:mixins="triggerfragment" fragment="seperateShippingAddress"/>
+                <t:label for="separateShipTo">Separate Ship To?</t:label>
+
+                <t:formfragment t:id="seperateShippingAddress" visible="separateShipTo">
+
+                    <h2>Shipping Address</h2>
+
+                    <t:beaneditor t:id="shippingAddress"/>
+
+                </t:formfragment>
+
+
+                <div class="t-beaneditor-row">
+                    <input type="submit" value="Continue"/>
+                </div>
+            </div>
+
+        </t:form>
+
+    </body>
+</html>]]></source>
+
+                <p>
+                    The separateShipTo property is initially null, to the FormFragment is initially invisible. The
+                    BeanEditor
+                    and all of the individual fields are rendered, but the &lt;div&gt; for the FormFragment is simply
+                    invisible.
+                </p>
+
+                <p>
+                    The
+                    <a href="../mixins/TriggerFragment.html">TriggerFragment</a>
+                    mixin adds a client-side trigger that
+                    will show or hide the fragment as the checkbox is clicked by the user.
+                </p>
+
+
+            </subsection>
+
+            <subsection name="OrderAddress.java">
+                <source><![CDATA[
+public class OrderAddress
+{
+    @Persist
+    private ShippingAddress _billingAddress;
+
+    @Persist
+    private ShippingAddress _shippingAddress;
+
+    @Persist
+    private boolean _separateShipTo;
+
+    public ShippingAddress getBillingAddress()
+    {
+        return _billingAddress;
+    }
+
+    public void setBillingAddress(ShippingAddress billingAddress)
+    {
+        _billingAddress = billingAddress;
+    }
+
+    public ShippingAddress getShippingAddress()
+    {
+        return _shippingAddress;
+    }
+
+    public void setShippingAddress(ShippingAddress shippingAddress)
+    {
+        _shippingAddress = shippingAddress;
+    }
+
+    public boolean isSeparateShipTo()
+    {
+        return _separateShipTo;
+    }
+
+    public void setSeparateShipTo(boolean separateShipTo)
+    {
+        _separateShipTo = separateShipTo;
+    }
+}]]></source>
+            </subsection>
+
+            <p>
+                The OrderAddress page is largely just a holder of the properties (for simplicity in this example,
+                there is no event handler for the success event, nor are we going into other details that would
+                reflecting in a real application).
+            </p>
+
+            <p>
+                The BeanEditor component will create default instances of billingAddress and shippingAddress.
+                If the user does not choose to use a seperate ship-to, the shippingAddress property will contain
+                an empty ShippingAddress object. The application will need to query the separateShipTo property
+                to determine how to proceed once the form is succesfully submitted.
+            </p>
+
+        </section>
+
+        <section name="Notes">
+
+            <p>
+                FormFragments are nestable, which can lead to complex (and perhaps, confusing) interfaces.
+            </p>
+
+            <p>
+                The FormFragment doesn't just prevent server-side input validation when invisible; it prevents
+                <em>any</em>
+                server-side processing
+                for the components it encloses, as if the components were entirely absent.
+            </p>
+
+            <p>
+                If JavaScript is disabled on the client, the application will still operate, though the user
+                will have to submit the form to have the fragment(s) update.
+            </p>
+
+        </section>
+    </body>
+</document>
\ No newline at end of file

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Palette.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Palette.java?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Palette.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Palette.java Mon Feb 18 17:44:04 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.
@@ -57,7 +57,7 @@
  * DIV.t-palette SELECT { width: 300px; }
  * &lt;/style&gt;
  * </pre>
- * <p>
+ * <p/>
  * You'll want to ensure that both &lt;select&gt; in each column is the same width, otherwise the display will update poorly
  * as options are moved from one column to the other.
  * <p/>
@@ -75,7 +75,7 @@
         public void render(MarkupWriter writer)
         {
             writer.element("select", "id", getClientId() + ":avail", "multiple", "multiple", "size", getSize(), "name",
-                           getElementName() + ":avail");
+                           getControlName() + ":avail");
 
             writeDisabled(writer, isDisabled());
 
@@ -136,7 +136,7 @@
         public void render(MarkupWriter writer)
         {
             writer.element("select", "id", getClientId(), "multiple", "multiple", "size", getSize(), "name",
-                           getElementName());
+                           getControlName());
 
             writeDisabled(writer, isDisabled());
 
@@ -333,7 +333,7 @@
 
         _renderSupport.addScript("new Tapestry.Palette('%s', %s, %s);", clientId, _reorder, naturalOrder);
 
-        writer.element("input", "type", "hidden", "id", clientId + ":values", "name", getElementName() + ":values",
+        writer.element("input", "type", "hidden", "id", clientId + ":values", "name", getControlName() + ":values",
                        "value", selectedValues);
         writer.end();
     }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PasswordField.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PasswordField.java?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PasswordField.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/PasswordField.java Mon Feb 18 17:44:04 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.
@@ -31,7 +31,7 @@
 
                        "type", "password",
 
-                       "name", getElementName(),
+                       "name", getControlName(),
 
                        "id", getClientId(),
 

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=628957&r1=628956&r2=628957&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 Mon Feb 18 17:44:04 2008
@@ -74,7 +74,7 @@
 
     private String _clientId;
 
-    private String _elementName;
+    private String _controlName;
 
     /**
      * If true, then the field will render out with a disabled attribute (to turn off client-side behavior). Further, a
@@ -94,11 +94,11 @@
     }
 
     /**
-     * Returns the element name provided by the containing {@link org.apache.tapestry.RadioContainer}.
+     * Returns the control name provided by the containing {@link org.apache.tapestry.RadioContainer}.
      */
-    public String getElementName()
+    public String getControlName()
     {
-        return _elementName;
+        return _controlName;
     }
 
     public String getLabel()
@@ -125,9 +125,9 @@
         String value = _container.toClient(_value);
 
         _clientId = _pageRenderSupport.allocateClientId(_resources.getId());
-        _elementName = _container.getElementName();
+        _controlName = _container.getElementName();
 
-        writer.element("input", "type", "radio", "id", _clientId, "name", _elementName, "value", value);
+        writer.element("input", "type", "radio", "id", _clientId, "name", _controlName, "value", value);
 
         if (_container.isSelected(_value)) writer.attributes("checked", "checked");
     }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/RadioGroup.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/RadioGroup.java?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/RadioGroup.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/RadioGroup.java Mon Feb 18 17:44:04 2008
@@ -71,7 +71,7 @@
     @Environmental
     private ValidationTracker _tracker;
 
-    private String _elementName;
+    private String _controlName;
 
     final Binding defaultValue()
     {
@@ -92,16 +92,16 @@
     {
         private static final long serialVersionUID = -7984673040135949374L;
 
-        private final String _elementName;
+        private final String _controlName;
 
-        Setup(String elementName)
+        Setup(String controlName)
         {
-            _elementName = elementName;
+            _controlName = controlName;
         }
 
         public void execute(RadioGroup component)
         {
-            component.setup(_elementName);
+            component.setup(_controlName);
         }
     }
 
@@ -117,12 +117,12 @@
 
     private void setup(String elementName)
     {
-        _elementName = elementName;
+        _controlName = elementName;
     }
 
     private void processSubmission()
     {
-        String clientValue = _request.getParameter(_elementName);
+        String clientValue = _request.getParameter(_controlName);
 
         _tracker.recordInput(this, clientValue);
 
@@ -135,7 +135,7 @@
      */
     final void setupRender()
     {
-        String name = _formSupport.allocateElementName(_resources.getId());
+        String name = _formSupport.allocateControlName(_resources.getId());
 
         ComponentAction<RadioGroup> action = new Setup(name);
 
@@ -150,7 +150,7 @@
         {
             public String getElementName()
             {
-                return _elementName;
+                return _controlName;
             }
 
             public boolean isDisabled()
@@ -184,9 +184,9 @@
         _environment.pop(RadioContainer.class);
     }
 
-    public String getElementName()
+    public String getControlName()
     {
-        return _elementName;
+        return _controlName;
     }
 
     public String getLabel()

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Select.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Select.java?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Select.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Select.java Mon Feb 18 17:44:04 2008
@@ -147,7 +147,7 @@
 
     void beginRender(MarkupWriter writer)
     {
-        writer.element("select", "name", getElementName(), "id", getClientId());
+        writer.element("select", "name", getControlName(), "id", getClientId());
 
         _resources.renderInformalParameters(writer);
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Submit.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Submit.java?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Submit.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/Submit.java Mon Feb 18 17:44:04 2008
@@ -69,7 +69,7 @@
 
     void beginRender(MarkupWriter writer)
     {
-        writer.element("input", "type", "submit", "name", getElementName(), "id", getClientId());
+        writer.element("input", "type", "submit", "name", getControlName(), "id", getClientId());
 
         _resources.renderInformalParameters(writer);
     }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextArea.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextArea.java?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextArea.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextArea.java Mon Feb 18 17:44:04 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.
@@ -32,7 +32,7 @@
     {
         writer.element("textarea",
 
-                       "name", getElementName(),
+                       "name", getControlName(),
 
                        "id", getClientId());
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextField.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextField.java?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextField.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/components/TextField.java Mon Feb 18 17:44:04 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.
@@ -31,7 +31,7 @@
 
                        "type", "text",
 
-                       "name", getElementName(),
+                       "name", getControlName(),
 
                        "id", getClientId(),
 

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=628957&r1=628956&r2=628957&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 Mon Feb 18 17:44:04 2008
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2008 The Apache Software Foundation
 //
 // Licensed under the Apache License, Version 2.0 (the "License");
 // you may not use this file except in compliance with the License.
@@ -14,10 +14,7 @@
 
 package org.apache.tapestry.corelib.components;
 
-import org.apache.tapestry.ClientElement;
-import org.apache.tapestry.ComponentResources;
-import org.apache.tapestry.MarkupWriter;
-import org.apache.tapestry.PageRenderSupport;
+import org.apache.tapestry.*;
 import org.apache.tapestry.annotations.Environmental;
 import org.apache.tapestry.annotations.Parameter;
 import org.apache.tapestry.annotations.SupportsInformalParameters;
@@ -50,7 +47,7 @@
      * make the Zone's &lt;div&gt; visible before being updated.  If not specified, then
      * the basic "show" method is used.
      */
-    @Parameter
+    @Parameter(defaultPrefix = TapestryConstants.LITERAL_BINDING_PREFIX)
     private String _show;
 
     /**
@@ -59,7 +56,7 @@
      * method is used, which performs a classic "yellow fade" to indicate to the user
      * that and update has taken place.
      */
-    @Parameter
+    @Parameter(defaultPrefix = TapestryConstants.LITERAL_BINDING_PREFIX)
     private String _update;
 
     private String _clientId;

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=628957&r1=628956&r2=628957&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 Mon Feb 18 17:44:04 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.
@@ -67,7 +67,7 @@
         _actions = actions;
     }
 
-    public String allocateElementName(String id)
+    public String allocateControlName(String id)
     {
         return _idAllocator.allocateId(id);
     }

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/internal/WrappedComponentAction.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/internal/WrappedComponentAction.java?rev=628957&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/internal/WrappedComponentAction.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/internal/WrappedComponentAction.java Mon Feb 18 17:44:04 2008
@@ -0,0 +1,60 @@
+// 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.internal;
+
+import org.apache.tapestry.ComponentAction;
+import org.apache.tapestry.runtime.Component;
+import org.apache.tapestry.services.ComponentSource;
+
+import java.io.Serializable;
+
+/**
+ * A wrapper around a component id and a {@link org.apache.tapestry.ComponentAction}.
+ *
+ * @see org.apache.tapestry.corelib.components.FormFragment
+ */
+public class WrappedComponentAction implements Serializable
+{
+    private final String _componentId;
+
+    private final ComponentAction _action;
+
+    public WrappedComponentAction(Component component, ComponentAction action)
+    {
+        this(component.getComponentResources().getCompleteId(), action);
+    }
+
+    /**
+     * @param componentId the component's complete id, suitable for use with {@link org.apache.tapestry.services.ComponentSource#getComponent(String)}.
+     * @param action      the action associated with the component
+     */
+    public WrappedComponentAction(String componentId, ComponentAction action)
+    {
+        _componentId = componentId;
+        _action = action;
+    }
+
+    /**
+     * Retrieves the component from the source and executes the action.
+     *
+     * @param source used to re-acquire the component
+     */
+    public void execute(ComponentSource source)
+    {
+        Component component = source.getComponent(_componentId);
+
+        _action.execute(component);
+    }
+}

Added: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/TriggerFragment.xdoc
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/TriggerFragment.xdoc?rev=628957&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/TriggerFragment.xdoc (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/corelib/mixins/TriggerFragment.xdoc Mon Feb 18 17:44:04 2008
@@ -0,0 +1,9 @@
+<document>
+    <body>
+        <p>
+            See the
+            <a href="../components/FormFragment.html">FormFragment</a>
+            documentation for an example.
+        </p>
+    </body>
+</document>
\ No newline at end of file

Modified: 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/ZoneSetup.java?rev=628957&r1=628956&r2=628957&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/ZoneSetup.java Mon Feb 18 17:44:04 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.
@@ -15,7 +15,10 @@
 package org.apache.tapestry.internal.services;
 
 /**
- * Collects details about zone usage for effecient initialization on the client side.
+ * 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
 {
@@ -40,5 +43,17 @@
      * @param elementId id of an element that has been previously registered as a Zone
      */
     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.
+     *
+     * @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
+     *                         null for the default
+     * @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);
 }
 

Modified: 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/ZoneSetupImpl.java?rev=628957&r1=628956&r2=628957&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/ZoneSetupImpl.java Mon Feb 18 17:44:04 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.
@@ -20,7 +20,7 @@
 
 public class ZoneSetupImpl implements ZoneSetup
 {
-    static final String INITIALIZER_STRING = "Tapestry.initializeZones(%s, %s);";
+    static final String ZONE_INITIALIZER_STRING = "Tapestry.initializeZones(%s, %s);";
 
     private final PageRenderSupport _pageRenderSupport;
 
@@ -28,7 +28,11 @@
 
     private final JSONArray _links = new JSONArray();
 
-    private boolean _dirty;
+    private final JSONArray _subForms = new JSONArray();
+
+    private boolean _zonesDirty;
+
+    private boolean _subformsDirty;
 
     public ZoneSetupImpl(PageRenderSupport pageRenderSupport)
     {
@@ -40,13 +44,17 @@
         JSONObject spec = new JSONObject();
         spec.put("div", clientId);
 
-        if (showFunctionName != null) spec.put("show", showFunctionName.toLowerCase());
-
-        if (updateFunctionName != null) spec.put("update", updateFunctionName.toLowerCase());
+        addFunction(spec, "show", showFunctionName);
+        addFunction(spec, "update", updateFunctionName);
 
         _zones.put(spec);
 
-        _dirty = true;
+        _zonesDirty = true;
+    }
+
+    private void addFunction(JSONObject spec, String key, String showFunctionName)
+    {
+        if (showFunctionName != null) spec.put(key, showFunctionName.toLowerCase());
     }
 
     public void linkZone(String linkId, String elementId)
@@ -57,14 +65,29 @@
 
         _links.put(spec);
 
-        _dirty = true;
+        _zonesDirty = true;
+
+    }
+
+    public void addFormFragment(String clientId, String showFunctionName, String hideFunctionName)
+    {
+        JSONObject spec = new JSONObject();
+        spec.put("element", clientId);
+
+        addFunction(spec, "show", showFunctionName);
+        addFunction(spec, "hide", hideFunctionName);
+
+        _subForms.put(spec);
+
+        _subformsDirty = true;
 
     }
 
     public void writeInitializationScript()
     {
-        if (!_dirty) return;
+        if (_zonesDirty) _pageRenderSupport.addScript(ZONE_INITIALIZER_STRING, _zones, _links);
 
-        _pageRenderSupport.addScript(INITIALIZER_STRING, _zones, _links);
+        if (_subformsDirty)
+            _pageRenderSupport.addScript("Tapestry.initializeFormFragments(%s);", _subForms);
     }
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentSource.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentSource.java?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentSource.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/ComponentSource.java Mon Feb 18 17:44:04 2008
@@ -26,7 +26,7 @@
 public interface ComponentSource
 {
     /**
-     * Gets a component by its id.
+     * Gets a component by its complete id.
      *
      * @param componentId complete component id
      * @return the component

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/Environment.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/Environment.java?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/Environment.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/services/Environment.java Mon Feb 18 17:44:04 2008
@@ -1,4 +1,4 @@
-// Copyright 2006 The Apache Software Foundation
+// Copyright 2006, 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.
@@ -18,10 +18,11 @@
 
 /**
  * Provides access to environment services, which are almost always provided to enclosed components
- * by enclosing components.
+ * by enclosing components. Environmental services are a form of very late binding.
  * <p/>
- * The Environment acts like a collection of stacks. Each stack contains environmental service
- * providers of a given type.
+ * The Environment acts like a collection of stacks. Each stack contains environmental service instances of a given type.
+ * Most often, a stack has zero or one elements, but on occasion, a particular component will push an override
+ * onto the stack for the benefit of the components it encloses.
  *
  * @see org.apache.tapestry.annotations.Environmental
  * @see org.apache.tapestry.services.EnvironmentalShadowBuilder

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=628957&r1=628956&r2=628957&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 Mon Feb 18 17:44:04 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.
@@ -21,21 +21,25 @@
 /**
  * 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.
+ *
+ * @see org.apache.tapestry.Field
  */
 public interface FormSupport extends ClientElement
 {
     /**
-     * Allocates a unique (within the form) element name for some component enclosed component,
+     * 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
      */
-    String allocateElementName(String id);
+    String allocateControlName(String id);
 
     /**
-     * Stores an action for execution during a later request.
+     * 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);
 
@@ -76,5 +80,4 @@
      * @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);
-
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/default.css
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/default.css?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/default.css (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/default.css Mon Feb 18 17:44:04 2008
@@ -140,11 +140,11 @@
     padding: 4px 0px 2px 0px;
 }
 
-DIV.t-beaneditor LABEL:after {
+DIV.t-beaneditor-row LABEL:after {
     content: ":";
 }
 
-DIV.t-beaneditor LABEL, DIV.t-beandisplay DIV.t-beandisplay-label {
+DIV.t-beaneditor-row LABEL, DIV.t-beandisplay DIV.t-beandisplay-label {
     width: 250px;
     display: block;
     float: left;

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=628957&r1=628956&r2=628957&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 Mon Feb 18 17:44:04 2008
@@ -16,10 +16,14 @@
 
     FormEvent : Class.create(),
 
+    FormEventManager : Class.create(),
+
     FieldEventManager : Class.create(),
 
     Zone : Class.create(),
 
+    FormFragment : Class.create(),
+
     ErrorPopup : Class.create(),
 
     // An array of ErrorPopup that have been created for fields within the page
@@ -53,10 +57,12 @@
 
         $$("INPUT", "SELECT", "TEXTAREA").each(function(element)
         {
-            if (element.isObservingFocusChange == undefined)
-            {
-
+            // Due to Ajax, we may execute the callback multiple times,
+            // and we don't want to add multiple listeners to the same
+            // element.
 
+            if (! element.isObservingFocusChange)
+            {
                 element.observe("focus", function()
                 {
                     Tapestry.focusedElement = element;
@@ -74,49 +80,7 @@
 
     registerForm : function(form, clientValidations)
     {
-        form = $(form);
-
-        // Because order is important, we don't observe
-        // the event, we take it over.
-
-        form.onsubmit = function(domevent)
-        {
-            var event = new Tapestry.FormEvent(form);
-
-            form.firstError = true;
-
-	        // Locate elements that have an event manager (and therefore, validations)
-            // and let those validations execute, which may result in calls to recordError().
-
-            form.getElements().each(function(element)
-            {
-                if (element.fieldEventManager != undefined)
-                {
-                    event.field = element;
-                    element.fieldEventManager.validateInput(event);
-
-                    if (event.abort) throw $break;
-                }
-            });
-
-            if (! event.result) domevent.stop();
-
-            return event.result;
-        };
-
-        form.recordError = function(field, event, message)
-        {
-            if (form.firstError)
-            {
-                $(field).activate();
-
-                form.firstError = false;
-            }
-
-            field.decorateForValidationError(message);
-        };
-
-        // And handle the validations
+        new Tapestry.FormEventManager(form);
 
         this.registerValidations(form, clientValidations);
     },
@@ -214,6 +178,10 @@
         element.onclick = handler;
     },
 
+    // Allows many Tapestry.Zone instances, and calls to Tapestry.linkZone(), to be
+    // combined efficiently (i.e., to minimize the amount of generated JavaScript
+    // for the page).
+
     initializeZones : function (zoneSpecs, linkSpecs)
     {
         // Each spec is a hash ready to pass to Tapestry.Zone
@@ -231,6 +199,28 @@
         });
     },
 
+    initializeFormFragments : function(specs)
+    {
+        $A(specs).each(function(spec)
+        {
+            new Tapestry.FormFragment(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
+    // checkbox and the FormFragment('s visibility) in agreement.
+
+    linkCheckboxToFormFragment : function(checkbox, element)
+    {
+        checkbox = $(checkbox);
+
+        checkbox.observe("change", function()
+        {
+            $(element).formFragment.setVisible(checkbox.checked);
+        });
+    },
 
     // Adds a validator for a field.  A FieldEventManager is added, if necessary.
     // The validator will be called only for non-blank values, unless acceptBlank is
@@ -247,8 +237,8 @@
 
         field.fieldEventManager.addValidator(acceptBlank, validator);
     }
+}
 
-};
 
 // New methods added to Element.
 
@@ -259,6 +249,20 @@
     decorateForValidationError : function (element, message)
     {
         $(element).fieldEventManager.addDecorations(message);
+    },
+
+    // Checks to see if an element is truly visible, meaning the receiver and all
+    // its anscestors (up to the containing form), are visible.
+
+    isDeepVisible : function(element)
+    {
+        if (! element.visible()) return false;
+
+        // Stop at a form, which is sufficient for validation purposes.
+
+        if (element.tagName == "FORM") return true;
+
+        return $(element.parentNode).isDeepVisible();
     }
 };
 
@@ -337,6 +341,7 @@
     {
         this.form = $(form);
         this.result = true;
+        this.firstError = true;
     },
 
     // Invoked by a validator function (which is passed the event) to record an error
@@ -347,7 +352,14 @@
 
     recordError : function(message)
     {
-        this.form.recordError(this.field, this, message);
+        if (this.firstError)
+        {
+            this.field.activate();
+            this.firstError = false;
+        }
+
+        this.field.decorateForValidationError(message);
+
         this.result = false;
         this.error = true;
     }
@@ -383,7 +395,6 @@
         this.queue = { position: 'end', scope: this.field.id };
 
         Event.observe(window, "resize", this.repositionBubble.bind(this));
-
     },
 
     showMessage : function(message)
@@ -474,6 +485,50 @@
     }
 };
 
+Tapestry.FormEventManager.prototype = {
+
+    initialize : function(form)
+    {
+        this.form = $(form);
+        this.form.eventManager = this;
+
+        this.form.onsubmit = this.handleSubmit.bindAsEventListener(this);
+    },
+
+    handleSubmit : function(domevent)
+    {
+        // Locate elements that have an event manager (and therefore, validations)
+        // and let those validations execute, which may result in calls to recordError().
+
+        var event = new Tapestry.FormEvent(this.form);
+
+        this.form.getElements().each(function(element)
+        {
+            if (element.fieldEventManager != undefined)
+            {
+                event.field = element;
+                element.fieldEventManager.validateInput(event);
+
+                if (event.abort) throw $break;
+            }
+        });
+
+        if (! event.result)
+        {
+            domevent.stop();
+        }
+        else
+        {
+            this.form.fire("form:prepareforsubmit");
+        }
+
+
+        return event.result;
+    }
+
+
+};
+
 Tapestry.FieldEventManager.prototype = {
 
     initialize : function(field)
@@ -492,6 +547,9 @@
         {
             var event = new Tapestry.FormEvent(this.field.form);
 
+     // This prevents the field from taking focus if there is an error.
+            event.firstError = false;
+
             event.field = this.field;
 
             this.validateInput(event);
@@ -557,8 +615,10 @@
     validateInput : function(event)
     {
         if (this.field.disabled) return;
-        
-        // Clear out old decorations.  It's easier to remove the decorations
+
+        if (! this.field.isDeepVisible()) return;
+
+     // Clear out old decorations.  It's easier to remove the decorations
         // and then re-add them if the field is in error than it is to
         // toggle them on or off at the end.
 
@@ -581,8 +641,8 @@
             {
 
                 validator(value, event);
-  	    
-  	    // event.error is set by Tapestry.FormEvent.recordError(). 
+
+     // event.error is set by Tapestry.FormEvent.recordError().
 
                 if (event.error) throw $break;
             }
@@ -594,6 +654,7 @@
 };
 
 // Wrappers around Prototype and Scriptaculous effects, invoked from Tapestry.Zone.show().
+// All the functions of this object should have all-lowercase names. 
 
 Tapestry.ZoneEffect = {
 
@@ -605,6 +666,22 @@
     highlight : function(element)
     {
         new Effect.Highlight(element);
+    },
+
+    slidedown : function (element)
+    {
+        new Effect.SlideDown(element);
+    },
+
+    slideup : function(element)
+    {
+        new Effect.SlideUp(element);
+    },
+
+
+    fade : function(element)
+    {
+        new Effect.Fade(element);
     }
 };
 
@@ -621,11 +698,11 @@
         this.showFunc = Tapestry.ZoneEffect[spec.show] || Tapestry.ZoneEffect.show;
         this.updateFunc = Tapestry.ZoneEffect[spec.update] || Tapestry.ZoneEffect.highlight;
 
-        // Link the div back to this zone.
+     // Link the div back to this zone.
 
         this.div.zone = this;
 
-        // Look inside the Zone div for the another div with the CSS class "t-zone-update".
+     // Look inside the Zone div for the another div with the CSS class "t-zone-update".
         // If present, then this is the elements whose content will be changed, rather
         // then the entire Zone div.  This allows a Zone div to contain "wrapper" markup
         // (borders and such).  Typically, such a Zone div will initially be invisible.
@@ -646,6 +723,55 @@
         var func = this.div.visible() ? this.updateFunc : this.showFunc;
 
         func.call(this, this.div);
+    }
+};
+
+// A class that managed an element (usually a <div>) that is conditionally visible and
+// part of the form when visible.
+
+Tapestry.FormFragment.prototype = {
+
+    initialize: function(spec)
+    {
+        this.element = $(spec.element);
+
+        this.element.formFragment = this;
+
+        this.hidden = $(spec.element + ":hidden");
+
+        this.showFunc = Tapestry.ZoneEffect[spec.show] || Tapestry.ZoneEffect.slidedown;
+        this.hideFunc = Tapestry.ZoneEffect[spec.hide] || Tapestry.ZoneEffect.slideup;
+
+        $(this.hidden.form).observe("form:prepareforsubmit", function()
+        {
+            this.hidden.value = this.element.isDeepVisible();
+        }.bind(this));
+    },
+
+    hide : function()
+    {
+        this.hideFunc(this.element);
+    },
+
+    show : function()
+    {
+        this.showFunc(this.element);
+    },
+
+    toggle : function()
+    {
+        this.setVisible(! this.element.visible());
+    },
+
+    setVisible : function(visible)
+    {
+        if (visible)
+        {
+            this.show();
+            return;
+        }
+
+        this.hide();
     }
 };
 

Added: tapestry/tapestry5/trunk/tapestry-core/src/site/apt/upgrade.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/apt/upgrade.apt?rev=628957&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/site/apt/upgrade.apt (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/site/apt/upgrade.apt Mon Feb 18 17:44:04 2008
@@ -0,0 +1,29 @@
+ ----
+ Upgrade Notes
+ ----
+
+Upgrade Notes
+
+  This is a quick guide to changes between releases of Tapestry.  This is meant to provide information
+  on any additions or changes that developers will face after upgrading to the latest version of Tapestry.
+
+  It is always advised to perform a full and complete build after upgrading.
+
+Release 5.0.11
+
+* Field.getElementName()
+
+  The method <<<getElementName()>>> on interface {{{../apidocs/org/apache/tapestry/Field.html}Field}}
+  was renamed to <<<getControlName()>>>.  This brings the property in alignment with W3C documentation
+  and terminology, and helps differentiate from the element name (i.e., the tag name used to represent
+  the element in a component template).
+
+  This affects a number of existing components that implement the interface.
+
+  Method <<<allocateElementName()>>> on interface {{{../apidocs/org/apache/tapestry/services/FieldSupport.html}FieldSupport}}
+  was likewise renamed to <<<allocateControlName()>>>.
+
+* Zone
+
+  The show and hide parameters of the {{{ref/org/apache/tapestry/corelib/components/Zone.html}Zone}}
+  component now have a default binding prefix of "literal".
\ No newline at end of file

Modified: tapestry/tapestry5/trunk/tapestry-core/src/site/site.xml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/site.xml?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/site/site.xml (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/site/site.xml Mon Feb 18 17:44:04 2008
@@ -49,8 +49,12 @@
         <menu name="Tapestry Core">
             <item name="Introduction" href="/index.html"/>
             <item name="Component Reference" href="ref/index.html"/>
-            <item name="Upgrade from Tapestry 4" href="/upgrade.html"/>
             <item name="Download" href="http://tapestry.apache.org/download.html"/>
+        </menu>
+
+        <menu name="Upgrade Notes">
+            <item name="From Tapestry 5" href="upgrade.html"/>
+            <item name="From Tapestry 4" href="upgrade4.html"/>
         </menu>
 
         <menu name="User Guide">

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/FormFragmentDemo.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/FormFragmentDemo.tml?rev=628957&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/FormFragmentDemo.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/FormFragmentDemo.tml Mon Feb 18 17:44:04 2008
@@ -0,0 +1,39 @@
+<html t:type="Border"
+      xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <h1>Form Fragment Demo</h1>
+
+    <form t:id="form">
+
+        <t:errors/>
+
+        <div class="t-beaneditor">
+
+            <div class="t-beaneditor-row">
+                <t:label for="name"/>
+                <t:textfield t:id="name" value="subscribe.name"/>
+            </div>
+
+            <t:checkbox t:id="subscribeToEmail" t:mixins="triggerfragment" fragment="showEmail"/>
+            <t:label for="subscribeToEmail">Subscribe to Email?</t:label>
+
+            <t:formfragment t:id="showEmail" visible="subscribeToEmail" hide="fade">
+                <div class="t-beaneditor-row">
+                    <t:label for="email"/>
+                    <t:textfield t:id="email" value="subscribe.email"/>
+                </div>
+            </t:formfragment>
+
+
+            <div class="t-beaneditor-row">
+                <input type="submit" value="Subscribe"/>
+            </div>
+
+        </div>
+
+
+        <p>
+            <t:actionlink t:id="clear">Clear</t:actionlink>
+        </p>
+
+    </form>
+</html>
\ No newline at end of file

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/FormFragmentOutput.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/FormFragmentOutput.tml?rev=628957&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/FormFragmentOutput.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/FormFragmentOutput.tml Mon Feb 18 17:44:04 2008
@@ -0,0 +1,17 @@
+<html t:type="Border"
+      xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+    <h1>Form Fragment Demo</h1>
+
+
+    <dl>
+        <dt>Name</dt>
+        <dd id="name">${subscribe.name}</dd>
+        <dt>Email</dt>
+        <dd id="email">${subscribe.email}</dd>
+    </dl>
+
+
+    <p>
+        <t:pagelink page="formfragmentdemo">Back</t:pagelink>
+    </p>
+</html>
\ No newline at end of file

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/ValidationTrackerImplTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/ValidationTrackerImplTest.java?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/ValidationTrackerImplTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/ValidationTrackerImplTest.java Mon Feb 18 17:44:04 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.
@@ -37,8 +37,8 @@
     @Test
     public void order_added_is_maintained()
     {
-        Field fielda = newFieldWithElementName("fieldA");
-        Field fieldb = newFieldWithElementName("fieldB");
+        Field fielda = newFieldWithControlName("fieldA");
+        Field fieldb = newFieldWithControlName("fieldB");
 
         replay();
 
@@ -61,7 +61,7 @@
     @Test
     public void record_input()
     {
-        Field field = newFieldWithElementName("field");
+        Field field = newFieldWithControlName("field");
 
         replay();
 
@@ -83,7 +83,7 @@
     @Test
     public void record_error_for_field()
     {
-        Field field = newFieldWithElementName("field");
+        Field field = newFieldWithControlName("field");
 
         replay();
 
@@ -126,9 +126,9 @@
     @Test
     public void data_survives_serialization() throws Exception
     {
-        Field fielda = newFieldWithElementName("fieldA");
-        Field fieldb = newFieldWithElementName("fieldB");
-        Field fieldc = newFieldWithElementName("fieldC");
+        Field fielda = newFieldWithControlName("fieldA");
+        Field fieldb = newFieldWithControlName("fieldB");
+        Field fieldc = newFieldWithControlName("fieldC");
 
         replay();
 
@@ -156,8 +156,8 @@
     @Test
     public void clear_removes_all()
     {
-        Field fielda = newFieldWithElementName("fieldA");
-        Field fieldb = newFieldWithElementName("fieldB");
+        Field fielda = newFieldWithControlName("fieldA");
+        Field fieldb = newFieldWithControlName("fieldB");
 
         replay();
 
@@ -180,14 +180,14 @@
         verify();
     }
 
-    private final Field newFieldWithElementName(String elementName)
+    private final Field newFieldWithControlName(String controlName)
     {
         Field field = mockField();
 
         // Fields generated this way, for the purposes of this test, do not
-        // ever change their elementName. In real life, elementNames can change.
+        // ever change their controlName. In real life, elementNames can change.
 
-        expect(field.getElementName()).andReturn(elementName).atLeastOnce();
+        expect(field.getControlName()).andReturn(controlName).atLeastOnce();
 
         return field;
     }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Mon Feb 18 17:44:04 2008
@@ -1639,4 +1639,32 @@
         assertText("usingGet", "true");
         assertText("usingIs", "true");
     }
+
+    @Test
+    public void form_fragment()
+    {
+        start("Form Fragment Demo", "Clear");
+
+        type("name", "Fred");
+        // Really, you can't type in the field because it is not visible, but
+        // this checks that invisible fields are not processed.
+        type("email", "this field is ignored");
+
+        clickAndWait(SUBMIT);
+
+        assertText("name", "Fred");
+        assertText("email", "");
+
+        clickAndWait("link=Back");
+        clickAndWait("link=Clear");
+
+        click("subscribeToEmail");
+        type("name", "Barney");
+        type("email", "rubble@bedrock.gov");
+
+        clickAndWait(SUBMIT);
+
+        assertText("name", "Barney");
+        assertText("email", "rubble@bedrock.gov");
+    }
 }

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/SubscribeData.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/SubscribeData.java?rev=628957&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/SubscribeData.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/data/SubscribeData.java Mon Feb 18 17:44:04 2008
@@ -0,0 +1,46 @@
+// 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.integration.app1.data;
+
+import org.apache.tapestry.beaneditor.Validate;
+
+public class SubscribeData
+{
+    private String _name;
+    private String _email;
+
+    @Validate("required")
+    public String getName()
+    {
+        return _name;
+    }
+
+    public void setName(String name)
+    {
+        _name = name;
+    }
+
+    // Only really required if visible!
+    @Validate("required")
+    public String getEmail()
+    {
+        return _email;
+    }
+
+    public void setEmail(String email)
+    {
+        _email = email;
+    }
+}

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormFragmentDemo.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormFragmentDemo.java?rev=628957&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormFragmentDemo.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormFragmentDemo.java Mon Feb 18 17:44:04 2008
@@ -0,0 +1,70 @@
+// 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.integration.app1.pages;
+
+import org.apache.tapestry.annotations.Component;
+import org.apache.tapestry.annotations.InjectPage;
+import org.apache.tapestry.corelib.components.Form;
+import org.apache.tapestry.integration.app1.data.SubscribeData;
+
+public class FormFragmentDemo
+{
+    private SubscribeData _subscribe;
+
+    private boolean _subscribeToEmail;
+
+    @Component
+    private Form _form;
+
+    @InjectPage
+    private FormFragmentOutput _outputPage;
+
+    public SubscribeData getSubscribe()
+    {
+        return _subscribe;
+    }
+
+    public boolean isSubscribeToEmail()
+    {
+        return _subscribeToEmail;
+    }
+
+    public void setSubscribeToEmail(boolean subscribeToEmail)
+    {
+        _subscribeToEmail = subscribeToEmail;
+    }
+
+    void onPrepare()
+    {
+        _subscribe = new SubscribeData();
+    }
+
+    void onActionFromClear()
+    {
+        _form.clearErrors();
+    }
+
+    Object onFailure()
+    {
+        throw new RuntimeException("Show me the Request!");
+    }
+
+    Object onSuccess()
+    {
+
+
+        return _outputPage.initialize(_subscribe);
+    }
+}

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormFragmentOutput.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormFragmentOutput.java?rev=628957&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormFragmentOutput.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/FormFragmentOutput.java Mon Feb 18 17:44:04 2008
@@ -0,0 +1,35 @@
+// 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.integration.app1.pages;
+
+import org.apache.tapestry.annotations.Persist;
+import org.apache.tapestry.integration.app1.data.SubscribeData;
+
+public class FormFragmentOutput
+{
+    @Persist
+    private SubscribeData _subscribe;
+
+    FormFragmentOutput initialize(SubscribeData subscribe)
+    {
+        _subscribe = subscribe;
+        return this;
+    }
+
+    public SubscribeData getSubscribe()
+    {
+        return _subscribe;
+    }
+}

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java?rev=628957&r1=628956&r2=628957&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/Start.java Mon Feb 18 17:44:04 2008
@@ -61,6 +61,8 @@
     private static final List<Item> ITEMS = CollectionFactory.newList(
             new Item("actionpage", "Action Page", "tests fixture for ActionLink component"),
 
+            new Item("FormFragmentDemo", "Form Fragment Demo", "page with dynamic form sections"),
+
             new Item("BooleanDemo", "Boolean Property Demo", "demo boolean properties using both is and get prefixes"),
 
             new Item("DeleteFromGridDemo", "Delete From Grid", "demo deleting items form a Grid"),