001// Copyright 2005 The Apache Software Foundation
002//
003// Licensed under the Apache License, Version 2.0 (the "License");
004// you may not use this file except in compliance with the License.
005// You may obtain a copy of the License at
006//
007//     http://www.apache.org/licenses/LICENSE-2.0
008//
009// Unless required by applicable law or agreed to in writing, software
010// distributed under the License is distributed on an "AS IS" BASIS,
011// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012// See the License for the specific language governing permissions and
013// limitations under the License.
014
015package org.apache.tapestry;
016
017import org.apache.hivemind.Location;
018import org.apache.tapestry.form.FormEventType;
019import org.apache.tapestry.form.IFormComponent;
020
021/**
022 * Common interface extended by {@link org.apache.tapestry.IForm} and
023 * {@link org.apache.tapestry.form.FormSupport}.
024 * 
025 * @author Howard M. Lewis Ship
026 * @since 4.0
027 */
028public interface FormBehavior
029{
030    /**
031     * Adds an additional event handler. The type determines when the handler will be invoked,
032     * {@link FormEventType#SUBMIT}is most typical.
033     * 
034     * @deprecated Wiring of form event handlers is now managed on the client side. This method may
035     *             be removed in a future release of Tapestry.
036     */
037    public void addEventHandler(FormEventType type, String functionName);
038
039    /**
040     * Adds a hidden field value to be stored in the form. This ensures that all of the <input
041     * type="hidden"> (or equivalent) are grouped together, which ensures that the output HTML is
042     * valid (ie. doesn't have <input> improperly nested with <tr>, etc.).
043     * <p>
044     * It is acceptible to add multiple hidden fields with the same name. They will be written in
045     * the order they are received.
046     */
047
048    public void addHiddenValue(String name, String value);
049
050    /**
051     * Adds a hidden field value to be stored in the form. This ensures that all of the &lt;input
052     * type="hidden"&gt; (or equivalent) are grouped together, which ensures that the output HTML is
053     * valid (ie. doesn't have &lt;input&gt; improperly nested with &lt;tr&gt;, etc.).
054     * <p>
055     * It is acceptible to add multiple hidden fields with the same name. They will be written in
056     * the order they are received.
057     * 
058     * @since 3.0
059     */
060
061    public void addHiddenValue(String name, String id, String value);
062
063    /**
064     * Constructs a unique identifier (within the Form). The identifier consists of the component's
065     * id, with an index number added to ensure uniqueness.
066     * <p>
067     * Simply invokes {@link #getElementId(IFormComponent, String)}with the component's id.
068     * <p>
069     * Note: yes, some confusion on naming here. This is the form element id, which should be (for
070     * Tapestry purposes) unique within the rendered form. The {@link IFormComponent#getClientId()}
071     * is different, and should be unique within the rendered page.
072     */
073
074    public String getElementId(IFormComponent component);
075
076    /**
077     * Constructs a unique identifier from the base id. If possible, the id is used as-is.
078     * Otherwise, a unique identifier is appended to the id.
079     * <p>
080     * This method is provided simply so that some components (
081     * {@link org.apache.tapestry.form.ImageSubmit}) have more specific control over their names.
082     * <p>
083     * Invokes {@link IFormComponent#setName(String)}with the result, as well as returning it.
084     * 
085     * @throws StaleLinkException
086     *             if, when the form itself is rewinding, the element id allocated does not match
087     *             the expected id (as allocated when the form rendered). This indicates that the
088     *             state of the application has changed between the time the form renderred and the
089     *             time it was submitted.
090     */
091
092    public String getElementId(IFormComponent component, String baseId);
093
094    /**
095     * Returns true if the form is rewinding (meaning, the form was the subject of the request
096     * cycle).
097     */
098
099    public boolean isRewinding();
100
101    /**
102     * May be invoked by a component to force the encoding type of the form to a particular value.
103     * 
104     * @see org.apache.tapestry.form.Upload
105     * @throws ApplicationRuntimeException
106     *             if the current encoding type is not null and doesn't match the provided encoding
107     *             type
108     */
109
110    public void setEncodingType(String encodingType);
111
112    /**
113     * Pre-renders the specified field, buffering the result for later use by
114     * {@link #wasPrerendered(IMarkupWriter, IComponent)}. Typically, it is a
115     * {@link org.apache.tapestry.valid.FieldLabel}&nbsp;component that pre-renders an associated
116     * field. This little dance is necessary to properly support field labels inside loops, and to
117     * handle the portlet action/render request cycle.
118     * 
119     * @param writer
120     *            the markup writer (from which a nested markup writer is obtained)
121     * @param field
122     *            the field to pre-render. The field is responsible for invoking
123     *            {@link #wasPrerendered(IMarkupWriter, IComponent)}.
124     * @param location
125     *            an optional location (of the FieldLabel component) used when reporting errors.
126     */
127    public void prerenderField(IMarkupWriter writer, IComponent field, Location location);
128
129    /**
130     * Invoked by a form control component (a field) that may have been pre-rendered. If the field
131     * was pre-rendered, then the buffered output is printed into the writer and true is returned.
132     * Otherwise, false is returned.
133     * 
134     * @return true if the field was pre-rendered and should do nothing during its render phase,
135     *         false if the field should continue as normal.
136     */
137    public boolean wasPrerendered(IMarkupWriter writer, IComponent field);
138
139    /**
140     * Adds a deferred runnable, an object to be executed either before the &lt;/form&gt; tag is
141     * rendered (when rendering), or before the form's listener is invoked (when rewinding).
142     * Runnables are executed in the order in which they are added.
143     * 
144     * @param runnable
145     *            the object to execute (which may not be null)
146     */
147
148    public void addDeferredRunnable(Runnable runnable);
149
150    /**
151     * Registers a field for automatic focus. The goal is for the first field that is in error to
152     * get focus; failing that, the first required field; failing that, any field.
153     * 
154     * @param field
155     *            the field requesting focus
156     * @param priority
157     *            a priority level used to determine whether the registered field becomes the focus
158     *            field. Constants for this purpose are defined in {@link ValidationConstants}.
159     * @since 4.0
160     */
161
162    public void registerForFocus(IFormComponent field, int priority);
163
164}