1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.struts2.components;
22
23 import javax.servlet.http.HttpServletRequest;
24 import javax.servlet.http.HttpServletResponse;
25
26 import org.apache.struts2.views.annotations.StrutsTag;
27 import org.apache.struts2.views.annotations.StrutsTagAttribute;
28
29 import com.opensymphony.xwork2.util.ValueStack;
30
31 /***
32 * <!-- START SNIPPET: javadoc -->
33 * <p>The autocomplete tag is a combobox that can autocomplete text entered on the input box.
34 * When used on the "simple" theme, the autocompleter can be used like the ComboBox.
35 * When used on the "ajax" theme, the list can be retieved from an action. </p>
36 * <B>THE FOLLOWING IS ONLY VALID WHEN AJAX IS CONFIGURED</B>
37 * <ul>
38 * <li>href</li>
39 * <li>errorText</li>
40 * <li>listenTopics</li>
41 * <li>notifyTopics</li>
42 * <li>listenTopics</li>
43 * <li>formId</li>
44 * <li>formFilter</li>
45 * <li>indicator</li>
46 * <li>loadOnTextChange</li>
47 * <li>loadMinimumCount</li>
48 * <li>showDownArrow</li>
49 * <li>searchType</li>
50 * </ul>
51 * 'dropdownWidth' width in pixels of the drodpdown, same as autocompleter's width by default<p/>
52 * 'dropdownHeight' height in pixels of the drodown, 120 px by default<p/>
53 * 'forceValidOption' if invalid option is selected, clear autocompleter's text when focus is lost<p/>
54 * 'autoComplete', if true, make suggestions on the textbox<p/>
55 * 'formId' is the id of the html form whose fields will be seralized and passed as parameters
56 * in the request.<p/>
57 * 'formFilter' is the name of a function which will be used to filter the fields that will be
58 * seralized. This function takes as a parameter the element and returns true if the element
59 * should be included.<p/>
60 * 'listenTopics' comma separated list of topics names, that will trigger a request
61 * 'indicator' element to be shown while the request executing
62 * 'showErrorTransportText': whether errors should be displayed (on 'targets')<p/>
63 * 'loadOnTextChange' options will be reloaded everytime a character is typed on the textbox<p/>
64 * 'loadMinimumCount' minimum number of characters that will force the content to be loaded<p/>
65 * 'showDownError' show or hide the down arrow button<p/>
66 * 'searchType' how the search must be performed, options are: "startstring", "startword" and "substring"<p/>
67 * 'keyName' name of the field to which the selected key will be assigned<p/>
68 * 'iconPath' path of icon used for the dropdown<p/>
69 * 'templateCssPath' path to css file used to customize Dojo's widget<p/>
70 * 'dataFieldName' name of the field to be used as the list in the returned JSON string<p/>
71 * 'notifyTopics' comma separated list of topics names, that will be published. Three parameters are passed:<p/>
72 * <ul>
73 * <li>data: selected value when type='valuechanged'</li>
74 * <li>type: 'before' before the request is made, 'valuechanged' when selection changes, 'load' when the request succeeds, or 'error' when it fails</li>
75 * <li>request: request javascript object, when type='load' or type='error'</li>
76 * <ul>
77 *<!-- END SNIPPET: javadoc -->
78 *<!-- START SNIPPET: example -->
79 *<p>Autocompleter that gets its list from an action:</p>
80 *<s:autocompleter name="test" href="%{jsonList}" autoComplete="false"/>
81 *<br/>
82 **<p>Autocompleter that uses a list:</p>
83 *<s:autocompleter name="test" list="{'apple','banana','grape','pear'}" autoComplete="false"/>
84 *<br/>
85 *<!-- END SNIPPET: example -->
86 */
87 @StrutsTag(name="autocompleter", tldTagClass="org.apache.struts2.views.jsp.ui.AutocompleterTag", description="Renders a combobox with autocomplete and AJAX capabilities")
88 public class Autocompleter extends ComboBox {
89 public static final String TEMPLATE = "autocompleter";
90 final private static String COMPONENT_NAME = Autocompleter.class.getName();
91
92 protected String forceValidOption;
93 protected String searchType;
94 protected String autoComplete;
95 protected String delay;
96 protected String disabled;
97 protected String href;
98 protected String dropdownWidth;
99 protected String dropdownHeight;
100 protected String formId;
101 protected String formFilter;
102 protected String listenTopics;
103 protected String notifyTopics;
104 protected String indicator;
105 protected String loadOnTextChange;
106 protected String loadMinimumCount;
107 protected String showDownArrow;
108 protected String templateCssPath;
109 protected String iconPath;
110 protected String keyName;
111 protected String dataFieldName;
112 protected String resultsLimit;
113
114 public Autocompleter(ValueStack stack, HttpServletRequest request,
115 HttpServletResponse response) {
116 super(stack, request, response);
117 }
118
119 protected String getDefaultTemplate() {
120 return TEMPLATE;
121 }
122
123 public String getComponentName() {
124 return COMPONENT_NAME;
125 }
126
127
128 public void evaluateExtraParams() {
129 super.evaluateExtraParams();
130
131 if (forceValidOption != null)
132 addParameter("forceValidOption", findValue(forceValidOption,
133 Boolean.class));
134 if (searchType != null) {
135 String type = findString(searchType);
136 if(type != null)
137 addParameter("searchType", type.toUpperCase());
138 }
139 if (autoComplete != null)
140 addParameter("autoComplete", findValue(autoComplete, Boolean.class));
141 if (delay != null)
142 addParameter("delay", findValue(delay, Integer.class));
143 if (disabled != null)
144 addParameter("disabled", findValue(disabled, Boolean.class));
145 if (href != null) {
146 addParameter("href", findString(href));
147 addParameter("mode", "remote");
148 }
149 if (dropdownHeight != null)
150 addParameter("dropdownHeight", findValue(dropdownHeight, Integer.class));
151 if (dropdownWidth != null)
152 addParameter("dropdownWidth", findValue(dropdownWidth, Integer.class));
153 if (formFilter != null)
154 addParameter("formFilter", findString(formFilter));
155 if (formId != null)
156 addParameter("formId", findString(formId));
157 if (listenTopics != null)
158 addParameter("listenTopics", findString(listenTopics));
159 if (notifyTopics != null)
160 addParameter("notifyTopics", findString(notifyTopics));
161 if (indicator != null)
162 addParameter("indicator", findString(indicator));
163 if (loadOnTextChange != null)
164 addParameter("loadOnTextChange", findValue(loadOnTextChange, Boolean.class));
165 if (loadMinimumCount != null)
166 addParameter("loadMinimumCount", findValue(loadMinimumCount, Integer.class));
167 if (showDownArrow != null)
168 addParameter("showDownArrow", findValue(showDownArrow, Boolean.class));
169 else
170 addParameter("showDownArrow", Boolean.TRUE);
171 if(templateCssPath != null)
172 addParameter("templateCssPath", findString(templateCssPath));
173 if(iconPath != null)
174 addParameter("iconPath", findString(iconPath));
175 if(dataFieldName != null)
176 addParameter("dataFieldName", findString(dataFieldName));
177 if(keyName != null)
178 addParameter("keyName", findString(keyName));
179 else {
180 keyName = name + "Key";
181 addParameter("keyName", findString(keyName));
182 }
183
184 String keyNameExpr = "%{" + keyName + "}";
185 addParameter("key", findString(keyNameExpr));
186 if(resultsLimit != null)
187 addParameter("searchLimit", findString(resultsLimit));
188 }
189
190 protected Object findListValue() {
191 return (list != null) ? findValue(list, Object.class) : null;
192 }
193
194 @StrutsTagAttribute(description="Whether autocompleter should make suggestion on the textbox", type="Boolean", defaultValue="false")
195 public void setAutoComplete(String autoComplete) {
196 this.autoComplete = autoComplete;
197 }
198
199 @StrutsTagAttribute(description="Enable or disable autocompleter", type="Boolean", defaultValue="false")
200 public void setDisabled(String disabled) {
201 this.disabled = disabled;
202 }
203
204 @StrutsTagAttribute(description="Force selection to be one of the options", type="Boolean", defaultValue="false")
205 public void setForceValidOption(String forceValidOption) {
206 this.forceValidOption = forceValidOption;
207 }
208
209 @StrutsTagAttribute(description="The URL used to load the options")
210 public void setHref(String href) {
211 this.href = href;
212 }
213
214 @StrutsTagAttribute(description="Delay before making the search", type="Integer", defaultValue="100")
215 public void setDelay(String searchDelay) {
216 this.delay = searchDelay;
217 }
218
219 @StrutsTagAttribute(description="how the search must be performed, options are: 'startstring', 'startword' " +
220 "and 'substring'", defaultValue="stringstart")
221 public void setSearchType(String searchType) {
222 this.searchType = searchType;
223 }
224
225 @StrutsTagAttribute(description="Dropdown's height in pixels", type="Integer", defaultValue="120")
226 public void setDropdownHeight(String height) {
227 this.dropdownHeight = height;
228 }
229
230 @StrutsTagAttribute(description="Dropdown's width", type="Integer", defaultValue="same as textbox")
231 public void setDropdownWidth(String width) {
232 this.dropdownWidth = width;
233 }
234
235 @StrutsTagAttribute(description="Function name used to filter the fields of the form")
236 public void setFormFilter(String formFilter) {
237 this.formFilter = formFilter;
238 }
239
240 @StrutsTagAttribute(description="Form id whose fields will be serialized and passed as parameters")
241 public void setFormId(String formId) {
242 this.formId = formId;
243 }
244
245 @StrutsTagAttribute(description="Topic that will trigger a reload")
246 public void setListenTopics(String listenTopics) {
247 this.listenTopics = listenTopics;
248 }
249
250 @StrutsTagAttribute(description="Topics that will be published when content is reloaded")
251 public void setNotifyTopics(String onValueChangedPublishTopic) {
252 this.notifyTopics = onValueChangedPublishTopic;
253 }
254
255 @StrutsTagAttribute(description="Id of element that will be shown while request is made")
256 public void setIndicator(String indicator) {
257 this.indicator = indicator;
258 }
259
260 @StrutsTagAttribute(description="Minimum number of characters that will force the content to be loaded", type="Integer", defaultValue="3")
261 public void setLoadMinimumCount(String loadMinimumCount) {
262 this.loadMinimumCount = loadMinimumCount;
263 }
264
265 @StrutsTagAttribute(description="Options will be reloaded everytime a character is typed on the textbox", type="Boolean", defaultValue="true")
266 public void setLoadOnTextChange(String loadOnType) {
267 this.loadOnTextChange = loadOnType;
268 }
269
270 @StrutsTagAttribute(description="Show or hide the down arrow button", type="Boolean", defaultValue="true")
271 public void setShowDownArrow(String showDownArrow) {
272 this.showDownArrow = showDownArrow;
273 }
274
275
276 @StrutsTagAttribute(description="Iteratable source to populate from.")
277 public void setList(String list) {
278 super.setList(list);
279 }
280
281 @StrutsTagAttribute(description="Template css path")
282 public void setTemplateCssPath(String templateCssPath) {
283 this.templateCssPath = templateCssPath;
284 }
285
286 @StrutsTagAttribute(description="Path to icon used for the dropdown")
287 public void setIconPath(String iconPath) {
288 this.iconPath = iconPath;
289 }
290
291 @StrutsTagAttribute(description="Name of the field to which the selected key will be assigned")
292 public void setKeyName(String keyName) {
293 this.keyName = keyName;
294 }
295
296 @StrutsTagAttribute(description="Name of the field in the returned JSON object that contains the data array", defaultValue="Value specified in 'name'")
297 public void setDataFieldName(String dataFieldName) {
298 this.dataFieldName = dataFieldName;
299 }
300
301 @StrutsTagAttribute(description="Limit how many results are shown as autocompletion options", defaultValue="30")
302 public void setResultsLimit(String resultsLimit) {
303 this.resultsLimit = resultsLimit;
304 }
305 }