001: package com.opensymphony.webwork.components;
002:
003: import com.opensymphony.xwork.util.OgnlValueStack;
004:
005: import javax.servlet.http.HttpServletRequest;
006: import javax.servlet.http.HttpServletResponse;
007:
008: /**
009: * <!-- START SNIPPET: javadoc -->
010: * Render a submit button. The submit tag is used together with the form tag to provide asynchronous form submissions.
011: * The submit can have three different types of rendering:
012: * <ul>
013: * <li>input: renders as html <input type="submit"...></li>
014: * <li>image: renders as html <input type="image"...></li>
015: * <li>button: renders as html <button type="submit"...></li>
016: * </ul>
017: * Please note that the button type has advantages by adding the possibility to seperate the submitted value from the
018: * text shown on the button face, but has issues with Microsoft Internet Explorer at least up to 6.0
019: * <!-- END SNIPPET: javadoc -->
020: *
021: * <p/> <b>Examples</b>
022: *
023: * <pre>
024: * <!-- START SNIPPET: example -->
025: * <ww:submit value="%{'Submit'}" />
026: * <!-- END SNIPPET: example -->
027: * </pre>
028: *
029: * <pre>
030: * <!-- START SNIPPET: example2 -->
031: * Render an image submit:
032: * <ww:submit type="image" value="%{'Submit'}" label="Submit the form" src="submit.gif"/>
033: * <!-- END SNIPPET: example2 -->
034: * </pre>
035: *
036: * <pre>
037: * <!-- START SNIPPET: example3 -->
038: * Render an button submit:
039: * <ww:submit type="button" value="%{'Submit'}" label="Submit the form"/>
040: * <!-- END SNIPPET: example3 -->
041: * </pre>
042: *
043: * <!-- START SNIPPET: ajaxJavadoc -->
044: * <B>THE FOLLOWING IS ONLY VALID WHEN AJAX IS CONFIGURED</B>
045: * <ul>
046: * <li>resultDivId</li>
047: * <li>notifyTopics</li>
048: * <li>onLoadJS</li>
049: * <li>preInvokeJS</li>
050: * </ul>
051: * The remote form has three basic modes of use, using the resultDivId,
052: * the notifyTopics, or the onLoadJS. You can mix and match any combination of
053: * them to get your desired result. All of these examples are contained in the
054: * Ajax example webapp. Lets go through some scenarios to see how you might use it:
055: * <!-- END SNIPPET: ajaxJavadoc -->
056: *
057: * <!-- START SNIPPET: ajxExDescription1 -->
058: * Show the results in another div. If you want your results to be shown in
059: * a div, use the resultDivId where the id is the id of the div you want them
060: * shown in. This is an inner HTML approah. Your results get jammed into
061: * the div for you. Here is a sample of this approach:
062: * <!-- END SNIPPET: ajxExDescription1 -->
063: *
064: * <pre>
065: * <!-- START SNIPPET: ajxExample1 -->
066: * Remote form replacing another div:
067: * <div id='two' style="border: 1px solid yellow;">Initial content</div>
068: * <ww:form
069: * id='theForm2'
070: * cssStyle="border: 1px solid green;"
071: * action='/AjaxRemoteForm.action'
072: * method='post'
073: * theme="ajax">
074: *
075: * <input type='text' name='data' value='WebWork User' />
076: * <ww:submit value="GO2" theme="ajax" resultDivId="two" />
077: *
078: * </ww:form >
079: * <!-- END SNIPPET: ajxExample1 -->
080: * </pre>
081: *
082: *
083: * <!-- START SNIPPET: ajxExDescription2 -->
084: * Notify other controls(divs) of a change. Using an pub-sub model you can
085: * notify others that your control changed and they can take the appropriate action.
086: * Most likely they will execute some action to refresh. The notifyTopics does this
087: * for you. You can have many topic names in a comma delimited list.
088: * eg: notifyTopics="newPerson, dataChanged" .
089: * Here is an example of this approach:
090: * <!-- END SNIPPET: ajxExDescription2 -->
091: *
092: * <pre>
093: * <!-- START SNIPPET: ajxExample2 -->
094: * <ww:form id="frm1" action="newPersonWithXMLResult" theme="ajax" >
095: * <ww:textfield label="Name" name="person.name" value="person.name" size="20" required="true" />
096: * <ww:submit id="submitBtn" value="Save" theme="ajax" cssClass="primary" notifyTopics="personUpdated, systemWorking" />
097: * </ww:form >
098: *
099: * <ww:div href="/listPeople.action" theme="ajax" errorText="error opps"
100: * loadingText="loading..." id="cart-body" >
101: * <ww:action namespace="" name="listPeople" executeResult="true" />
102: * </ww:div>
103: * <!-- END SNIPPET: ajxExample2 -->
104: * </pre>
105: *
106: * <!-- START SNIPPET: ajxExDescription3 -->
107: * Massage the results with JavaScript. Say that your result returns some h
108: * appy XML and you want to parse it and do lots of cool things with it.
109: * The way to do this is with a onLoadJS handler. Here you provide the name of
110: * a JavaScript function to be called back with the result and the event type.
111: * The only key is that you must use the variable names 'data' and 'type' when
112: * defining the callback. For example: onLoadJS="myFancyDancyFunction(data, type)".
113: * While I talked about XML in this example, your not limited to XML, the data in
114: * the callback will be exactly whats returned as your result.
115: * Here is an example of this approach:
116: * <!-- END SNIPPET: ajxExDescription3 -->
117: *
118: * <pre>
119: * <!-- START SNIPPET: ajxExample3 -->
120: * <script language="JavaScript" type="text/javascript">
121: * function doGreatThings(data, type) {
122: * //Do whatever with your returned fragment...
123: * //Perhapps.... if xml...
124: * var xml = dojo.xml.domUtil.createDocumentFromText(data);
125: * var people = xml.getElementsByTagName("person");
126: * for(var i = 0;i < people.length; i ++){
127: * var person = people[i];
128: * var name = person.getAttribute("name")
129: * var id = person.getAttribute("id")
130: * alert('Thanks dude. Person: ' + name + ' saved great!!!');
131: * }
132: *
133: * }
134: * </script>
135: *
136: * <ww:form id="frm1" action="newPersonWithXMLResult" theme="ajax" >
137: * <ww:textfield label="Name" name="person.name" value="person.name" size="20" required="true" />
138: * <ww:submit id="submitBtn" value="Save" theme="ajax" cssClass="primary" onLoadJS="doGreatThings(data, type)" />
139: * </ww:form>
140: * <!-- END SNIPPET: ajxExample3 -->
141: * </pre>
142: *
143: * @author Patrick Lightbody
144: * @author Rene Gielen
145: * @version $Revision: 2682 $
146: * @since 2.2
147: *
148: * @ww.tag name="submit" tld-body-content="JSP" tld-tag-class="com.opensymphony.webwork.views.jsp.ui.SubmitTag"
149: * description="Render a submit button"
150: */
151: public class Submit extends FormButton {
152: final public static String TEMPLATE = "submit";
153:
154: protected String resultDivId;
155: protected String onLoadJS;
156: protected String notifyTopics;
157: protected String listenTopics;
158: protected String preInvokeJS;
159: protected String src;
160:
161: public Submit(OgnlValueStack stack, HttpServletRequest request,
162: HttpServletResponse response) {
163: super (stack, request, response);
164: }
165:
166: protected String getDefaultTemplate() {
167: return TEMPLATE;
168: }
169:
170: public void evaluateParams() {
171: if (value == null) {
172: value = "Submit";
173: }
174: super .evaluateParams();
175: }
176:
177: public void evaluateExtraParams() {
178: super .evaluateExtraParams();
179: /*if (value == null) {
180: value = "Submit";
181: }*/
182:
183: //super.evaluateParams();
184: if (null != src) {
185: addParameter("src", findString(src));
186: }
187:
188: if (null != resultDivId) {
189: addParameter("resultDivId", findString(resultDivId));
190: }
191:
192: if (null != onLoadJS) {
193: addParameter("onLoadJS", findString(onLoadJS));
194: }
195:
196: if (null != notifyTopics) {
197: addParameter("notifyTopics", findString(notifyTopics));
198: }
199:
200: if (null != listenTopics) {
201: addParameter("listenTopics", findString(listenTopics));
202: }
203:
204: if (preInvokeJS != null) {
205: addParameter("preInvokeJS", findString(preInvokeJS));
206: }
207:
208: }
209:
210: /**
211: * Indicate whether the concrete button supports the type "image".
212: *
213: * @return <tt>true</tt> to indicate type image is supported.
214: */
215: protected boolean supportsImageType() {
216: return true;
217: }
218:
219: /**
220: * The id of the HTML element to place the result (this can the the form's id or any id on the page.
221: * @ww.tagattribute required="false" type="String"
222: */
223: public void setResultDivId(String resultDivId) {
224: this .resultDivId = resultDivId;
225: }
226:
227: /**
228: * Javascript code that will be executed after the form has been submitted. The format is onLoadJS='yourMethodName(data,type)'. NOTE: the words data and type must be left like that if you want the event type and the returned data.
229: * @ww.tagattribute required="false" type="String"
230: */
231: public void setOnLoadJS(String onLoadJS) {
232: this .onLoadJS = onLoadJS;
233: }
234:
235: /**
236: * Topic names to post an event to after the form has been submitted.
237: * @ww.tagattribute required="false" type="String"
238: */
239: public void setNotifyTopics(String notifyTopics) {
240: this .notifyTopics = notifyTopics;
241: }
242:
243: /**
244: * Set listenTopics attribute.
245: * @ww.tagattribute required="false" type="String"
246: */
247: public void setListenTopics(String listenTopics) {
248: this .listenTopics = listenTopics;
249: }
250:
251: /**
252: * Javascript code that will be executed before invokation. The format is preInvokeJS='yourMethodName(data,type)'.
253: * @ww.tagattribute required="false" type="String"
254: */
255: public void setPreInvokeJS(String preInvokeJS) {
256: this .preInvokeJS = preInvokeJS;
257: }
258:
259: /**
260: * Supply a submit button text apart from submit value. Will have no effect for <i>input</i> type submit, since button text will always be the value parameter. For the type <i>image</i>, alt parameter will be set to this value.
261: * @ww.tagattribute required="false"
262: */
263: public void setLabel(String label) {
264: super .setLabel(label);
265: }
266:
267: /**
268: * Supply an image src for <i>image</i> type submit button. Will have no effect for types <i>input</i> and <i>button</i>.
269: * @ww.tagattribute required="false"
270: */
271: public void setSrc(String src) {
272: this.src = src;
273: }
274: }
|