View Javadoc

1   /*
2    * $Id: Autocompleter.java 529622 2007-04-17 14:24:01Z musachy $
3    *
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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   *&lt;s:autocompleter name="test"  href="%{jsonList}" autoComplete="false"/&gt;
81   *<br/>
82   **<p>Autocompleter that uses a list:</p>
83   *&lt;s:autocompleter name="test"  list="{'apple','banana','grape','pear'}" autoComplete="false"/&gt;
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     // Override as not required
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 }