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
015 package org.apache.tapestry;
016
017 import org.apache.hivemind.Location;
018 import org.apache.tapestry.form.FormEventType;
019 import org.apache.tapestry.form.IFormComponent;
020 import org.apache.tapestry.json.JSONObject;
021
022 /**
023 * Common interface extended by {@link org.apache.tapestry.IForm} and
024 * {@link org.apache.tapestry.form.FormSupport}.
025 *
026 * @author Howard M. Lewis Ship
027 * @since 4.0
028 */
029 public interface FormBehavior
030 {
031 /**
032 * Adds an additional event handler. The type determines when the handler will be invoked,
033 * {@link FormEventType#SUBMIT}is most typical.
034 *
035 * @deprecated Wiring of form event handlers is now managed on the client side. This method may
036 * be removed in a future release of Tapestry.
037 */
038 void addEventHandler(FormEventType type, String functionName);
039
040 /**
041 * Adds a hidden field value to be stored in the form. This ensures that all of the <input
042 * type="hidden"> (or equivalent) are grouped together, which ensures that the output HTML is
043 * valid (ie. doesn't have <input> improperly nested with <tr>, etc.).
044 * <p>
045 * It is acceptible to add multiple hidden fields with the same name. They will be written in
046 * the order they are received.
047 */
048
049 void addHiddenValue(String name, String value);
050
051 /**
052 * Adds a hidden field value to be stored in the form. This ensures that all of the <input
053 * type="hidden"> (or equivalent) are grouped together, which ensures that the output HTML is
054 * valid (ie. doesn't have <input> improperly nested with <tr>, etc.).
055 * <p>
056 * It is acceptible to add multiple hidden fields with the same name. They will be written in
057 * the order they are received.
058 *
059 * @since 3.0
060 */
061
062 void addHiddenValue(String name, String id, String value);
063
064 /**
065 * Constructs a unique identifier (within the Form). The identifier consists of the component's
066 * id, with an index number added to ensure uniqueness.
067 * <p>
068 * Simply invokes {@link #getElementId(IFormComponent, String)}with the component's id.
069 * <p>
070 * Note: yes, some confusion on naming here. This is the form element id, which should be (for
071 * Tapestry purposes) unique within the rendered form. The {@link IFormComponent#getClientId()}
072 * is different, and should be unique within the rendered page.
073 */
074
075 String getElementId(IFormComponent component);
076
077 /**
078 * Constructs a unique identifier from the base id. If possible, the id is used as-is.
079 * Otherwise, a unique identifier is appended to the id.
080 * <p>
081 * This method is provided simply so that some components (
082 * {@link org.apache.tapestry.form.ImageSubmit}) have more specific control over their names.
083 * <p>
084 * Invokes {@link IFormComponent#setName(String)}with the result, as well as returning it.
085 *
086 * @throws StaleLinkException
087 * if, when the form itself is rewinding, the element id allocated does not match
088 * the expected id (as allocated when the form rendered). This indicates that the
089 * state of the application has changed between the time the form renderred and the
090 * time it was submitted.
091 */
092
093 String getElementId(IFormComponent component, String baseId);
094
095 /**
096 * Returns true if the form is rewinding (meaning, the form was the subject of the request
097 * cycle).
098 */
099
100 boolean isRewinding();
101
102 /**
103 * May be invoked by a component to force the encoding type of the form to a particular value.
104 *
105 * @see org.apache.tapestry.form.Upload
106 * @throws ApplicationRuntimeException
107 * if the current encoding type is not null and doesn't match the provided encoding
108 * type
109 */
110
111 void setEncodingType(String encodingType);
112
113 /**
114 * Pre-renders the specified field, buffering the result for later use by
115 * {@link #wasPrerendered(IMarkupWriter, IComponent)}. Typically, it is a
116 * {@link org.apache.tapestry.valid.FieldLabel} component that pre-renders an associated
117 * field. This little dance is necessary to properly support field labels inside loops, and to
118 * handle the portlet action/render request cycle.
119 *
120 * @param writer
121 * the markup writer (from which a nested markup writer is obtained)
122 * @param field
123 * the field to pre-render. The field is responsible for invoking
124 * {@link #wasPrerendered(IMarkupWriter, IComponent)}.
125 * @param location
126 * an optional location (of the FieldLabel component) used when reporting errors.
127 */
128 void prerenderField(IMarkupWriter writer, IComponent field, Location location);
129
130 /**
131 * Invoked by a form control component (a field) that may have been pre-rendered. If the field
132 * was pre-rendered, then the buffered output is printed into the writer and true is returned.
133 * Otherwise, false is returned.
134 *
135 * @return true if the field was pre-rendered and should do nothing during its render phase,
136 * false if the field should continue as normal.
137 */
138 boolean wasPrerendered(IMarkupWriter writer, IComponent field);
139
140 /**
141 * Adds a deferred runnable, an object to be executed either before the </form> tag is
142 * rendered (when rendering), or before the form's listener is invoked (when rewinding).
143 * Runnables are executed in the order in which they are added.
144 *
145 * @param runnable
146 * the object to execute (which may not be null)
147 */
148
149 void addDeferredRunnable(Runnable runnable);
150
151 /**
152 * Registers a field for automatic focus. The goal is for the first field that is in error to
153 * get focus; failing that, the first required field; failing that, any field.
154 *
155 * @param field
156 * the field requesting focus
157 * @param priority
158 * a priority level used to determine whether the registered field becomes the focus
159 * field. Constants for this purpose are defined in {@link ValidationConstants}.
160 * @since 4.0
161 */
162
163 void registerForFocus(IFormComponent field, int priority);
164
165 /**
166 * The javascript object profile being built by this context to validate/translate
167 * form values.
168 * @return {@link JSONObject} profile.
169 */
170 JSONObject getProfile();
171
172 /**
173 * Sets a flag denoting whether or not an {@link IFormComponent} field has been
174 * updated according to the logic defined in
175 * {@link org.apache.tapestry.services.ResponseBuilder#updateComponent(String)}.
176 *
177 * <p>
178 * Currently this flag is used during ajax/json responses so that cooperating
179 * {@link ResponseBuilder}s can be worked with to ensure form state is properly
180 * updated on the client. Specifically, that the hidden form input fields and
181 * any associated validation profiles are updated.
182 * </p>
183 *
184 * @param value
185 * The value to set.
186 */
187 void setFormFieldUpdating(boolean value);
188
189 /**
190 * Checks to see if a form field has been updated.
191 *
192 * @see #setFormFieldUpdating(boolean)
193 * @return
194 */
195 boolean isFormFieldUpdating();
196 }