001: /*
002: * $Id: Submit.java 557348 2007-07-18 18:15:37Z jholmes $
003: *
004: * Licensed to the Apache Software Foundation (ASF) under one
005: * or more contributor license agreements. See the NOTICE file
006: * distributed with this work for additional information
007: * regarding copyright ownership. The ASF licenses this file
008: * to you under the Apache License, Version 2.0 (the
009: * "License"); you may not use this file except in compliance
010: * with the License. You may obtain a copy of the License at
011: *
012: * http://www.apache.org/licenses/LICENSE-2.0
013: *
014: * Unless required by applicable law or agreed to in writing,
015: * software distributed under the License is distributed on an
016: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017: * KIND, either express or implied. See the License for the
018: * specific language governing permissions and limitations
019: * under the License.
020: */
021: package org.apache.struts2.components;
022:
023: import java.io.Writer;
024:
025: import javax.servlet.http.HttpServletRequest;
026: import javax.servlet.http.HttpServletResponse;
027:
028: import org.apache.commons.logging.Log;
029: import org.apache.commons.logging.LogFactory;
030: import org.apache.struts2.views.annotations.StrutsTag;
031: import org.apache.struts2.views.annotations.StrutsTagAttribute;
032:
033: import com.opensymphony.xwork2.util.ValueStack;
034:
035: /**
036: * <!-- START SNIPPET: javadoc -->
037: * Render a submit button. The submit tag is used together with the form tag to provide asynchronous form submissions.
038: * The submit can have three different types of rendering:
039: * <ul>
040: * <li>input: renders as html <input type="submit"...></li>
041: * <li>image: renders as html <input type="image"...></li>
042: * <li>button: renders as html <button type="submit"...></li>
043: * </ul>
044: * Please note that the button type has advantages by adding the possibility to seperate the submitted value from the
045: * text shown on the button face, but has issues with Microsoft Internet Explorer at least up to 6.0
046: * <!-- END SNIPPET: javadoc -->
047: *
048: * <p/> <b>Examples</b>
049: * <pre>
050: * <!-- START SNIPPET: example -->
051: * <s:submit value="%{'Submit the form'}" />
052: * <!-- END SNIPPET: example -->
053: * </pre>
054: * <pre>
055: * <!-- START SNIPPET: example2 -->
056: * Render an image submit:
057: * <s:submit type="image" value="%{'Submit the form'}" src="submit.gif"/>
058: * <!-- END SNIPPET: example2 -->
059: * </pre>
060: * <pre>
061: * <!-- START SNIPPET: example3 -->
062: * Render an button submit:
063: * <s:submit type="button" value="%{'Submit the form'}"/>
064: * <!-- END SNIPPET: example3 -->
065: * </pre>
066: *
067: * <!-- START SNIPPET: ajaxJavadoc -->
068: * <B>THE FOLLOWING IS ONLY VALID WHEN AJAX IS CONFIGURED</B>
069: * <ul>
070: * <li>href</li>
071: * <li>errorText</li>
072: * <li>listenTopics</li>
073: * <li>notifyTopics</li>
074: * <li>executeScripts</li>
075: * <li>loadingText</li>
076: * <li>listenTopics</li>
077: * <li>handler</li>
078: * <li>formId</li>
079: * <li>formFilter</li>
080: * <li>targets</li>
081: * <li>showErrorTransportText</li>
082: * <li>targets</li>
083: * <li>indicator</li>
084: * </ul>
085: * 'resultDivId' Deprecated. Use targets.</p>
086: * 'targets' is a list of element ids whose content will be updated with the
087: * text returned from request.<p/>
088: * 'errorText' is the text that will be displayed when there is an error making the request.<p/>
089: * 'onLoadJS' Deprecated. Use 'notifyTopics'.<p/>
090: * 'preInvokeJS' Deprecated. Use 'notifyTopics'.<p/>
091: * 'executeScripts' if set to true will execute javascript sections in the returned text.<p/>
092: * 'loadingText' is the text that will be displayed on the 'targets' elements while making the
093: * request.<p/>
094: * 'handler' is the name of the function that will take care of making the AJAX request. Dojo's widget
095: * and dom node are passed as parameters).<p/>
096: * 'formId' is the id of the html form whose fields will be seralized and passed as parameters
097: * in the request.<p/>
098: * 'formFilter' is the name of a function which will be used to filter the fields that will be
099: * seralized. This function takes as a parameter the element and returns true if the element
100: * should be included.<p/>
101: * 'listenTopics' comma separated list of topics names, that will trigger a request
102: * 'indicator' element to be shown while the request executing
103: * 'showErrorTransportText': whether errors should be displayed (on 'targets')</p>
104: * 'showLoadingText' show loading text on targets</p>
105: * 'notifyTopics' comma separated list of topics names, that will be published. Three parameters are passed:<p/>
106: * <ul>
107: * <li>data: html or json object when type='load' or type='error'</li>
108: * <li>type: 'before' before the request is made, 'load' when the request succeeds, or 'error' when it fails</li>
109: * <li>request: request javascript object, when type='load' or type='error'</li>
110: * </ul>
111: * <!-- END SNIPPET: ajaxJavadoc -->
112: *
113: * <!-- START SNIPPET: ajxExDescription1 -->
114: * Show the results in another div. If you want your results to be shown in
115: * a div, use the resultDivId where the id is the id of the div you want them
116: * shown in. This is an inner HTML approah. Your results get jammed into
117: * the div for you. Here is a sample of this approach:
118: * <!-- END SNIPPET: ajxExDescription1 -->
119: *
120: * <pre>
121: * <!-- START SNIPPET: ajxExample1 -->
122: * Remote form replacing another div:
123: * <div id='two' style="border: 1px solid yellow;">Initial content</div>
124: * <s:form
125: * id='theForm2'
126: * cssStyle="border: 1px solid green;"
127: * action='/AjaxRemoteForm.action'
128: * method='post'
129: * theme="ajax">
130: *
131: * <input type='text' name='data' value='Struts User' />
132: * <s:submit value="GO2" theme="ajax" resultDivId="two" />
133: *
134: * </s:form >
135: * <!-- END SNIPPET: ajxExample1 -->
136: * </pre>
137: *
138: */
139: @StrutsTag(name="submit",tldTagClass="org.apache.struts2.views.jsp.ui.SubmitTag",description="Render a submit button")
140: public class Submit extends FormButton implements RemoteUICallBean {
141:
142: private static final Log LOG = LogFactory.getLog(Submit.class);
143:
144: final public static String TEMPLATE = "submit";
145:
146: protected String href;
147: protected String errorText;
148: protected String executeScripts;
149: protected String loadingText;
150: protected String listenTopics;
151: protected String handler;
152: protected String formId;
153: protected String formFilter;
154: protected String src;
155: protected String notifyTopics;
156: protected String showErrorTransportText;
157: protected String indicator;
158: protected String showLoadingText;
159: //these two are called "preInvokeJS" and "onLoadJS" on the tld
160: //Names changed here to keep some consistency
161: protected String beforeLoading;
162: protected String afterLoading;
163:
164: //this one is called "resultDivId" on the tld
165: protected String targets;
166:
167: public Submit(ValueStack stack, HttpServletRequest request,
168: HttpServletResponse response) {
169: super (stack, request, response);
170: }
171:
172: protected String getDefaultTemplate() {
173: return TEMPLATE;
174: }
175:
176: public void evaluateParams() {
177: if ((key == null) && (value == null)) {
178: value = "Submit";
179: }
180:
181: if (((key != null)) && (value == null)) {
182: this .value = "%{getText('" + key + "')}";
183: }
184:
185: super .evaluateParams();
186: }
187:
188: public void evaluateExtraParams() {
189: super .evaluateExtraParams();
190:
191: if (href != null)
192: addParameter("href", findString(href));
193: if (errorText != null)
194: addParameter("errorText", findString(errorText));
195: if (loadingText != null)
196: addParameter("loadingText", findString(loadingText));
197: if (afterLoading != null)
198: addParameter("afterLoading", findString(afterLoading));
199: if (beforeLoading != null)
200: addParameter("beforeLoading", findString(beforeLoading));
201: if (executeScripts != null)
202: addParameter("executeScripts", findValue(executeScripts,
203: Boolean.class));
204: if (listenTopics != null)
205: addParameter("listenTopics", findString(listenTopics));
206: if (notifyTopics != null)
207: addParameter("notifyTopics", findString(notifyTopics));
208: if (handler != null)
209: addParameter("handler", findString(handler));
210: if (formId != null)
211: addParameter("formId", findString(formId));
212: if (formFilter != null)
213: addParameter("formFilter", findString(formFilter));
214: if (src != null)
215: addParameter("src", findString(src));
216: if (indicator != null)
217: addParameter("indicator", findString(indicator));
218: if (targets != null)
219: addParameter("targets", findString(targets));
220: if (showLoadingText != null)
221: addParameter("showLoadingText", findString(showLoadingText));
222: }
223:
224: /**
225: * Indicate whether the concrete button supports the type "image".
226: *
227: * @return <tt>true</tt> to indicate type image is supported.
228: */
229: protected boolean supportsImageType() {
230: return true;
231: }
232:
233: /**
234: * Overrides to be able to render body in a template rather than always before the template
235: */
236: public boolean end(Writer writer, String body) {
237: evaluateParams();
238: try {
239: addParameter("body", body);
240:
241: mergeTemplate(writer, buildTemplateName(template,
242: getDefaultTemplate()));
243: } catch (Exception e) {
244: LOG.error("error when rendering", e);
245: } finally {
246: popComponentStack();
247: }
248:
249: return false;
250: }
251:
252: @StrutsTagAttribute(description="Topic that will trigger the remote call")
253: public void setListenTopics(String listenTopics) {
254: this .listenTopics = listenTopics;
255: }
256:
257: @StrutsTagAttribute(description="The theme to use for the element. This tag will usually use the ajax theme.")
258: public void setTheme(String theme) {
259: super .setTheme(theme);
260: }
261:
262: @StrutsTagAttribute(description="The URL to call to obtain the content. Note: If used with ajax context, the value must be set as an url tag value.")
263: public void setHref(String href) {
264: this .href = href;
265: }
266:
267: @StrutsTagAttribute(description="The text to display to the user if the is an error fetching the content")
268: public void setErrorText(String errorText) {
269: this .errorText = errorText;
270: }
271:
272: @StrutsTagAttribute(name="onLoadJS",description="Deprecated. Use 'notifyTopics'. Javascript code execute after reload")
273: public void setAfterLoading(String afterLoading) {
274: this .afterLoading = afterLoading;
275: }
276:
277: @StrutsTagAttribute(name="preInvokeJS",description="Deprecated. Use 'notifyTopics'. Javascript code execute before reload")
278: public void setBeforeLoading(String beforeLoading) {
279: this .beforeLoading = beforeLoading;
280: }
281:
282: @StrutsTagAttribute(description="Javascript code in the fetched content will be executed",type="Boolean",defaultValue="false")
283: public void setExecuteScripts(String executeScripts) {
284: this .executeScripts = executeScripts;
285: }
286:
287: @StrutsTagAttribute(description="Text to be shown while content is being fetched",defaultValue="Loading...")
288: public void setLoadingText(String loadingText) {
289: this .loadingText = loadingText;
290: }
291:
292: @StrutsTagAttribute(description="Javascript function name that will make the request")
293: public void setHandler(String handler) {
294: this .handler = handler;
295: }
296:
297: @StrutsTagAttribute(description="Function name used to filter the fields of the form.")
298: public void setFormFilter(String formFilter) {
299: this .formFilter = formFilter;
300: }
301:
302: @StrutsTagAttribute(description="Form id whose fields will be serialized and passed as parameters")
303: public void setFormId(String formId) {
304: this .formId = formId;
305: }
306:
307: @StrutsTagAttribute(description="Supply an image src for image type submit button. Will have no effect for types input and button.")
308: public void setSrc(String src) {
309: this .src = src;
310: }
311:
312: @StrutsTagAttribute(description="Comma delimited list of ids of the elements whose content will be updated")
313: public void setTargets(String targets) {
314: this .targets = targets;
315: }
316:
317: @StrutsTagAttribute(description="Topics that will published when the remote call completes")
318: public void setNotifyTopics(String notifyTopics) {
319: this .notifyTopics = notifyTopics;
320: }
321:
322: @StrutsTagAttribute(description="Set whether errors will be shown or not",type="Boolean",defaultValue="true")
323: public void setShowErrorTransportText(String showErrorTransportText) {
324: this .showErrorTransportText = showErrorTransportText;
325: }
326:
327: @StrutsTagAttribute(description="Set indicator")
328: public void setIndicator(String indicator) {
329: this .indicator = indicator;
330: }
331:
332: @StrutsTagAttribute(description="Show loading text on targets",type="Boolean",defaultValue="true")
333: public void setShowLoadingText(String showLoadingText) {
334: this.showLoadingText = showLoadingText;
335: }
336: }
|