1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.struts2.components;
19
20 import javax.servlet.http.HttpServletRequest;
21 import javax.servlet.http.HttpServletResponse;
22
23 import com.opensymphony.xwork2.util.ValueStack;
24
25 /***
26 * <!-- START SNIPPET: javadoc -->
27 * Render a submit button. The submit tag is used together with the form tag to provide asynchronous form submissions.
28 * The submit can have three different types of rendering:
29 * <ul>
30 * <li>input: renders as html <input type="submit"...></li>
31 * <li>image: renders as html <input type="image"...></li>
32 * <li>button: renders as html <button type="submit"...></li>
33 * </ul>
34 * Please note that the button type has advantages by adding the possibility to seperate the submitted value from the
35 * text shown on the button face, but has issues with Microsoft Internet Explorer at least up to 6.0
36 * <!-- END SNIPPET: javadoc -->
37 *
38 * <p/> <b>Examples</b>
39 *
40 * <pre>
41 * <!-- START SNIPPET: example -->
42 * <s:submit value="%{'Submit'}" />
43 * <!-- END SNIPPET: example -->
44 * </pre>
45 *
46 * <pre>
47 * <!-- START SNIPPET: example2 -->
48 * Render an image submit:
49 * <s:submit type="image" value="%{'Submit'}" label="Submit the form" src="submit.gif"/>
50 * <!-- END SNIPPET: example2 -->
51 * </pre>
52 *
53 * <pre>
54 * <!-- START SNIPPET: example3 -->
55 * Render an button submit:
56 * <s:submit type="button" value="%{'Submit'}" label="Submit the form"/>
57 * <!-- END SNIPPET: example3 -->
58 * </pre>
59 *
60 * <!-- START SNIPPET: ajaxJavadoc -->
61 * <B>THE FOLLOWING IS ONLY VALID WHEN AJAX IS CONFIGURED</B>
62 * <ul>
63 * <li>resultDivId</li>
64 * <li>notifyTopics</li>
65 * <li>onLoadJS</li>
66 * <li>preInvokeJS</li>
67 * </ul>
68 * The remote form has three basic modes of use, using the resultDivId,
69 * the notifyTopics, or the onLoadJS. You can mix and match any combination of
70 * them to get your desired result. All of these examples are contained in the
71 * Ajax example webapp. Lets go through some scenarios to see how you might use it:
72 * <!-- END SNIPPET: ajaxJavadoc -->
73 *
74 * <!-- START SNIPPET: ajxExDescription1 -->
75 * Show the results in another div. If you want your results to be shown in
76 * a div, use the resultDivId where the id is the id of the div you want them
77 * shown in. This is an inner HTML approah. Your results get jammed into
78 * the div for you. Here is a sample of this approach:
79 * <!-- END SNIPPET: ajxExDescription1 -->
80 *
81 * <pre>
82 * <!-- START SNIPPET: ajxExample1 -->
83 * Remote form replacing another div:
84 * <div id='two' style="border: 1px solid yellow;">Initial content</div>
85 * <s:form
86 * id='theForm2'
87 * cssStyle="border: 1px solid green;"
88 * action='/AjaxRemoteForm.action'
89 * method='post'
90 * theme="ajax">
91 *
92 * <input type='text' name='data' value='Struts User' />
93 * <s:submit value="GO2" theme="ajax" resultDivId="two" />
94 *
95 * </s:form >
96 * <!-- END SNIPPET: ajxExample1 -->
97 * </pre>
98 *
99 *
100 * <!-- START SNIPPET: ajxExDescription2 -->
101 * Notify other controls(divs) of a change. Using an pub-sub model you can
102 * notify others that your control changed and they can take the appropriate action.
103 * Most likely they will execute some action to refresh. The notifyTopics does this
104 * for you. You can have many topic names in a comma delimited list.
105 * eg: notifyTopics="newPerson, dataChanged" .
106 * Here is an example of this approach:
107 * <!-- END SNIPPET: ajxExDescription2 -->
108 *
109 * <pre>
110 * <!-- START SNIPPET: ajxExample2 -->
111 * <s:form id="frm1" action="newPersonWithXMLResult" theme="ajax" >
112 * <s:textfield label="Name" name="person.name" value="person.name" size="20" required="true" />
113 * <s:submit id="submitBtn" value="Save" theme="ajax" cssClass="primary" notifyTopics="personUpdated, systemWorking" />
114 * </s:form >
115 *
116 * <s:div href="/listPeople.action" theme="ajax" errorText="error opps"
117 * loadingText="loading..." id="cart-body" >
118 * <s:action namespace="" name="listPeople" executeResult="true" />
119 * </s:div>
120 * <!-- END SNIPPET: ajxExample2 -->
121 * </pre>
122 *
123 * <!-- START SNIPPET: ajxExDescription3 -->
124 * Massage the results with JavaScript. Say that your result returns some h
125 * appy XML and you want to parse it and do lots of cool things with it.
126 * The way to do this is with a onLoadJS handler. Here you provide the name of
127 * a JavaScript function to be called back with the result and the event type.
128 * The only key is that you must use the variable names 'data' and 'type' when
129 * defining the callback. For example: onLoadJS="myFancyDancyFunction(data, type)".
130 * While I talked about XML in this example, your not limited to XML, the data in
131 * the callback will be exactly whats returned as your result.
132 * Here is an example of this approach:
133 * <!-- END SNIPPET: ajxExDescription3 -->
134 *
135 * <pre>
136 * <!-- START SNIPPET: ajxExample3 -->
137 * <script language="JavaScript" type="text/javascript">
138 * function doGreatThings(data, type) {
139 * //Do whatever with your returned fragment...
140 * //Perhapps.... if xml...
141 * var xml = dojo.xml.domUtil.createDocumentFromText(data);
142 * var people = xml.getElementsByTagName("person");
143 * for(var i = 0;i < people.length; i ++){
144 * var person = people[i];
145 * var name = person.getAttribute("name")
146 * var id = person.getAttribute("id")
147 * alert('Thanks dude. Person: ' + name + ' saved great!!!');
148 * }
149 *
150 * }
151 * </script>
152 *
153 * <s:form id="frm1" action="newPersonWithXMLResult" theme="ajax" >
154 * <s:textfield label="Name" name="person.name" value="person.name" size="20" required="true" />
155 * <s:submit id="submitBtn" value="Save" theme="ajax" cssClass="primary" onLoadJS="doGreatThings(data, type)" />
156 * </s:form>
157 * <!-- END SNIPPET: ajxExample3 -->
158 * </pre>
159 *
160 * @s.tag name="submit" tld-body-content="JSP" tld-tag-class="org.apache.struts2.views.jsp.ui.SubmitTag"
161 * description="Render a submit button"
162 */
163 public class Submit extends FormButton {
164 final public static String TEMPLATE = "submit";
165
166 protected String resultDivId;
167 protected String onLoadJS;
168 protected String notifyTopics;
169 protected String listenTopics;
170 protected String preInvokeJS;
171 protected String src;
172
173 public Submit(ValueStack stack, HttpServletRequest request, HttpServletResponse response) {
174 super(stack, request, response);
175 }
176
177 protected String getDefaultTemplate() {
178 return TEMPLATE;
179 }
180
181 public void evaluateParams() {
182 if (value == null) {
183 value = "Submit";
184 }
185 super.evaluateParams();
186 }
187
188 public void evaluateExtraParams() {
189 super.evaluateExtraParams();
190
191
192
193
194
195
196
197 if (null != src) {
198 addParameter("src", findString(src));
199 }
200
201 if (null != resultDivId) {
202 addParameter("resultDivId", findString(resultDivId));
203 }
204
205 if (null != onLoadJS) {
206 addParameter("onLoadJS", findString(onLoadJS));
207 }
208
209 if (null != notifyTopics) {
210 addParameter("notifyTopics", findString(notifyTopics));
211 }
212
213 if (null != listenTopics) {
214 addParameter("listenTopics", findString(listenTopics));
215 }
216
217 if (preInvokeJS != null) {
218 addParameter("preInvokeJS", findString(preInvokeJS));
219 }
220
221 }
222
223 /***
224 * Indicate whether the concrete button supports the type "image".
225 *
226 * @return <tt>true</tt> to indicate type image is supported.
227 */
228 protected boolean supportsImageType() {
229 return true;
230 }
231
232 /***
233 * The id of the HTML element to place the result (this can the the form's id or any id on the page.
234 * @s.tagattribute required="false" type="String"
235 */
236 public void setResultDivId(String resultDivId) {
237 this.resultDivId = resultDivId;
238 }
239
240 /***
241 * 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.
242 * @s.tagattribute required="false" type="String"
243 */
244 public void setOnLoadJS(String onLoadJS) {
245 this.onLoadJS = onLoadJS;
246 }
247
248 /***
249 * Topic names to post an event to after the form has been submitted.
250 * @s.tagattribute required="false" type="String"
251 */
252 public void setNotifyTopics(String notifyTopics) {
253 this.notifyTopics = notifyTopics;
254 }
255
256 /***
257 * Set listenTopics attribute.
258 * @s.tagattribute required="false" type="String"
259 */
260 public void setListenTopics(String listenTopics) {
261 this.listenTopics = listenTopics;
262 }
263
264 /***
265 * Javascript code that will be executed before invokation. The format is preInvokeJS='yourMethodName(data,type)'.
266 * @s.tagattribute required="false" type="String"
267 */
268 public void setPreInvokeJS(String preInvokeJS) {
269 this.preInvokeJS = preInvokeJS;
270 }
271
272 /***
273 * 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.
274 * @s.tagattribute required="false"
275 */
276 public void setLabel(String label) {
277 super.setLabel(label);
278 }
279
280 /***
281 * Supply an image src for <i>image</i> type submit button. Will have no effect for types <i>input</i> and <i>button</i>.
282 * @s.tagattribute required="false"
283 */
284 public void setSrc(String src) {
285 this.src = src;
286 }
287 }