001: /*
002: * $Id: Autocompleter.java 529622 2007-04-17 14:24:01Z musachy $
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 javax.servlet.http.HttpServletRequest;
024: import javax.servlet.http.HttpServletResponse;
025:
026: import org.apache.struts2.views.annotations.StrutsTag;
027: import org.apache.struts2.views.annotations.StrutsTagAttribute;
028:
029: import com.opensymphony.xwork2.util.ValueStack;
030:
031: /**
032: * <!-- START SNIPPET: javadoc -->
033: * <p>The autocomplete tag is a combobox that can autocomplete text entered on the input box.
034: * When used on the "simple" theme, the autocompleter can be used like the ComboBox.
035: * When used on the "ajax" theme, the list can be retieved from an action. </p>
036: * <B>THE FOLLOWING IS ONLY VALID WHEN AJAX IS CONFIGURED</B>
037: * <ul>
038: * <li>href</li>
039: * <li>errorText</li>
040: * <li>listenTopics</li>
041: * <li>notifyTopics</li>
042: * <li>listenTopics</li>
043: * <li>formId</li>
044: * <li>formFilter</li>
045: * <li>indicator</li>
046: * <li>loadOnTextChange</li>
047: * <li>loadMinimumCount</li>
048: * <li>showDownArrow</li>
049: * <li>searchType</li>
050: * </ul>
051: * 'dropdownWidth' width in pixels of the drodpdown, same as autocompleter's width by default<p/>
052: * 'dropdownHeight' height in pixels of the drodown, 120 px by default<p/>
053: * 'forceValidOption' if invalid option is selected, clear autocompleter's text when focus is lost<p/>
054: * 'autoComplete', if true, make suggestions on the textbox<p/>
055: * 'formId' is the id of the html form whose fields will be seralized and passed as parameters
056: * in the request.<p/>
057: * 'formFilter' is the name of a function which will be used to filter the fields that will be
058: * seralized. This function takes as a parameter the element and returns true if the element
059: * should be included.<p/>
060: * 'listenTopics' comma separated list of topics names, that will trigger a request
061: * 'indicator' element to be shown while the request executing
062: * 'showErrorTransportText': whether errors should be displayed (on 'targets')<p/>
063: * 'loadOnTextChange' options will be reloaded everytime a character is typed on the textbox<p/>
064: * 'loadMinimumCount' minimum number of characters that will force the content to be loaded<p/>
065: * 'showDownError' show or hide the down arrow button<p/>
066: * 'searchType' how the search must be performed, options are: "startstring", "startword" and "substring"<p/>
067: * 'keyName' name of the field to which the selected key will be assigned<p/>
068: * 'iconPath' path of icon used for the dropdown<p/>
069: * 'templateCssPath' path to css file used to customize Dojo's widget<p/>
070: * 'dataFieldName' name of the field to be used as the list in the returned JSON string<p/>
071: * 'notifyTopics' comma separated list of topics names, that will be published. Three parameters are passed:<p/>
072: * <ul>
073: * <li>data: selected value when type='valuechanged'</li>
074: * <li>type: 'before' before the request is made, 'valuechanged' when selection changes, 'load' when the request succeeds, or 'error' when it fails</li>
075: * <li>request: request javascript object, when type='load' or type='error'</li>
076: * <ul>
077: *<!-- END SNIPPET: javadoc -->
078: *<!-- START SNIPPET: example -->
079: *<p>Autocompleter that gets its list from an action:</p>
080: *<s:autocompleter name="test" href="%{jsonList}" autoComplete="false"/>
081: *<br/>
082: **<p>Autocompleter that uses a list:</p>
083: *<s:autocompleter name="test" list="{'apple','banana','grape','pear'}" autoComplete="false"/>
084: *<br/>
085: *<!-- END SNIPPET: example -->
086: */
087: @StrutsTag(name="autocompleter",tldTagClass="org.apache.struts2.views.jsp.ui.AutocompleterTag",description="Renders a combobox with autocomplete and AJAX capabilities")
088: public class Autocompleter extends ComboBox {
089: public static final String TEMPLATE = "autocompleter";
090: final private static String COMPONENT_NAME = Autocompleter.class
091: .getName();
092:
093: protected String forceValidOption;
094: protected String searchType;
095: protected String autoComplete;
096: protected String delay;
097: protected String disabled;
098: protected String href;
099: protected String dropdownWidth;
100: protected String dropdownHeight;
101: protected String formId;
102: protected String formFilter;
103: protected String listenTopics;
104: protected String notifyTopics;
105: protected String indicator;
106: protected String loadOnTextChange;
107: protected String loadMinimumCount;
108: protected String showDownArrow;
109: protected String templateCssPath;
110: protected String iconPath;
111: protected String keyName;
112: protected String dataFieldName;
113: protected String resultsLimit;
114:
115: public Autocompleter(ValueStack stack, HttpServletRequest request,
116: HttpServletResponse response) {
117: super (stack, request, response);
118: }
119:
120: protected String getDefaultTemplate() {
121: return TEMPLATE;
122: }
123:
124: public String getComponentName() {
125: return COMPONENT_NAME;
126: }
127:
128: public void evaluateExtraParams() {
129: super .evaluateExtraParams();
130:
131: if (forceValidOption != null)
132: addParameter("forceValidOption", findValue(
133: forceValidOption, 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,
141: Boolean.class));
142: if (delay != null)
143: addParameter("delay", findValue(delay, Integer.class));
144: if (disabled != null)
145: addParameter("disabled", findValue(disabled, Boolean.class));
146: if (href != null) {
147: addParameter("href", findString(href));
148: addParameter("mode", "remote");
149: }
150: if (dropdownHeight != null)
151: addParameter("dropdownHeight", findValue(dropdownHeight,
152: Integer.class));
153: if (dropdownWidth != null)
154: addParameter("dropdownWidth", findValue(dropdownWidth,
155: Integer.class));
156: if (formFilter != null)
157: addParameter("formFilter", findString(formFilter));
158: if (formId != null)
159: addParameter("formId", findString(formId));
160: if (listenTopics != null)
161: addParameter("listenTopics", findString(listenTopics));
162: if (notifyTopics != null)
163: addParameter("notifyTopics", findString(notifyTopics));
164: if (indicator != null)
165: addParameter("indicator", findString(indicator));
166: if (loadOnTextChange != null)
167: addParameter("loadOnTextChange", findValue(
168: loadOnTextChange, Boolean.class));
169: if (loadMinimumCount != null)
170: addParameter("loadMinimumCount", findValue(
171: loadMinimumCount, Integer.class));
172: if (showDownArrow != null)
173: addParameter("showDownArrow", findValue(showDownArrow,
174: Boolean.class));
175: else
176: addParameter("showDownArrow", Boolean.TRUE);
177: if (templateCssPath != null)
178: addParameter("templateCssPath", findString(templateCssPath));
179: if (iconPath != null)
180: addParameter("iconPath", findString(iconPath));
181: if (dataFieldName != null)
182: addParameter("dataFieldName", findString(dataFieldName));
183: if (keyName != null)
184: addParameter("keyName", findString(keyName));
185: else {
186: keyName = name + "Key";
187: addParameter("keyName", findString(keyName));
188: }
189:
190: String keyNameExpr = "%{" + keyName + "}";
191: addParameter("key", findString(keyNameExpr));
192: if (resultsLimit != null)
193: addParameter("searchLimit", findString(resultsLimit));
194: }
195:
196: protected Object findListValue() {
197: return (list != null) ? findValue(list, Object.class) : null;
198: }
199:
200: @StrutsTagAttribute(description="Whether autocompleter should make suggestion on the textbox",type="Boolean",defaultValue="false")
201: public void setAutoComplete(String autoComplete) {
202: this .autoComplete = autoComplete;
203: }
204:
205: @StrutsTagAttribute(description="Enable or disable autocompleter",type="Boolean",defaultValue="false")
206: public void setDisabled(String disabled) {
207: this .disabled = disabled;
208: }
209:
210: @StrutsTagAttribute(description="Force selection to be one of the options",type="Boolean",defaultValue="false")
211: public void setForceValidOption(String forceValidOption) {
212: this .forceValidOption = forceValidOption;
213: }
214:
215: @StrutsTagAttribute(description="The URL used to load the options")
216: public void setHref(String href) {
217: this .href = href;
218: }
219:
220: @StrutsTagAttribute(description="Delay before making the search",type="Integer",defaultValue="100")
221: public void setDelay(String searchDelay) {
222: this .delay = searchDelay;
223: }
224:
225: @StrutsTagAttribute(description="how the search must be performed, options are: 'startstring', 'startword' " + "and 'substring'",defaultValue="stringstart")
226: public void setSearchType(String searchType) {
227: this .searchType = searchType;
228: }
229:
230: @StrutsTagAttribute(description="Dropdown's height in pixels",type="Integer",defaultValue="120")
231: public void setDropdownHeight(String height) {
232: this .dropdownHeight = height;
233: }
234:
235: @StrutsTagAttribute(description="Dropdown's width",type="Integer",defaultValue="same as textbox")
236: public void setDropdownWidth(String width) {
237: this .dropdownWidth = width;
238: }
239:
240: @StrutsTagAttribute(description="Function name used to filter the fields of the form")
241: public void setFormFilter(String formFilter) {
242: this .formFilter = formFilter;
243: }
244:
245: @StrutsTagAttribute(description="Form id whose fields will be serialized and passed as parameters")
246: public void setFormId(String formId) {
247: this .formId = formId;
248: }
249:
250: @StrutsTagAttribute(description="Topic that will trigger a reload")
251: public void setListenTopics(String listenTopics) {
252: this .listenTopics = listenTopics;
253: }
254:
255: @StrutsTagAttribute(description="Topics that will be published when content is reloaded")
256: public void setNotifyTopics(String onValueChangedPublishTopic) {
257: this .notifyTopics = onValueChangedPublishTopic;
258: }
259:
260: @StrutsTagAttribute(description="Id of element that will be shown while request is made")
261: public void setIndicator(String indicator) {
262: this .indicator = indicator;
263: }
264:
265: @StrutsTagAttribute(description="Minimum number of characters that will force the content to be loaded",type="Integer",defaultValue="3")
266: public void setLoadMinimumCount(String loadMinimumCount) {
267: this .loadMinimumCount = loadMinimumCount;
268: }
269:
270: @StrutsTagAttribute(description="Options will be reloaded everytime a character is typed on the textbox",type="Boolean",defaultValue="true")
271: public void setLoadOnTextChange(String loadOnType) {
272: this .loadOnTextChange = loadOnType;
273: }
274:
275: @StrutsTagAttribute(description="Show or hide the down arrow button",type="Boolean",defaultValue="true")
276: public void setShowDownArrow(String showDownArrow) {
277: this .showDownArrow = showDownArrow;
278: }
279:
280: // Override as not required
281: @StrutsTagAttribute(description="Iteratable source to populate from.")
282: public void setList(String list) {
283: super .setList(list);
284: }
285:
286: @StrutsTagAttribute(description="Template css path")
287: public void setTemplateCssPath(String templateCssPath) {
288: this .templateCssPath = templateCssPath;
289: }
290:
291: @StrutsTagAttribute(description="Path to icon used for the dropdown")
292: public void setIconPath(String iconPath) {
293: this .iconPath = iconPath;
294: }
295:
296: @StrutsTagAttribute(description="Name of the field to which the selected key will be assigned")
297: public void setKeyName(String keyName) {
298: this .keyName = keyName;
299: }
300:
301: @StrutsTagAttribute(description="Name of the field in the returned JSON object that contains the data array",defaultValue="Value specified in 'name'")
302: public void setDataFieldName(String dataFieldName) {
303: this .dataFieldName = dataFieldName;
304: }
305:
306: @StrutsTagAttribute(description="Limit how many results are shown as autocompletion options",defaultValue="30")
307: public void setResultsLimit(String resultsLimit) {
308: this.resultsLimit = resultsLimit;
309: }
310: }
|