Apache Struts 2 Documentation > Home > Guides > Tag Developers Guide > Struts Tags > Tag Reference > UI Tag Reference > autocompleter
Added by Musachy Barroso, last edited by Musachy Barroso on Sep 20, 2007  (view change)

To use this tag, the head tag must be included on the page

Description

The autocomplete tag is a combobox that can autocomplete text entered on the input box. If an action is used to populate the autocompleter, the output of the action must be a well formed JSON string.

The autocompleter follows this rule to find its datasource:

1. If the response is an array, assume that it contains 2-dimension array elements, like:

[
     ["Alabama", "AL"],
     ["Alaska", "AK"]
]

2. If a value is specified in the "dataFieldName" attribute, and the response has a field with that name, assume that's the datasource, which can be an array of 2-dimension array elements, or a map, like (assuming dataFieldName="state"):

{
     "state" : [
          ["Alabama","AL"],
          ["Alaska","AK"]
     ]
}     

or

{ "state" : { "Alabama" : "AL", "Alaska" : "AK" } }

3. If there is a field that starts with the value specified on the "name" attribute, assume that's the datasource, like (assuming name="state"):

{
     "states" : [
          ["Alabama","AL"],
          ["Alaska","AK"]
     ]
}

4. Use first array that is found, like:

{
     "anything" : [
           ["Alabama", "AL"],
           ["Alaska", "AK"]
    ]       
}

5. If the response is a map, use it (recommended as it is the easiest one to generate):

{
     "Alabama" : "AL",
     "Alaska" : "AK"
}

Parameters

Name

Required

Default

Evaluated

Type

Description

accesskey false false String Set the html accesskey attribute on rendered html element
afterNotifyTopics false false String Comma delimmited list of topics that will published after the request(if the request succeeds)
autoComplete false false false Boolean Whether autocompleter should make suggestion on the textbox
beforeNotifyTopics false false String Comma delimmited list of topics that will published before the request
cssClass false false String The css class to use for element
cssStyle false false String The css style to use for element
dataFieldName false Value specified in 'name' false String Name of the field in the returned JSON object that contains the data array
delay false 100 false Integer Delay before making the search
disabled false false false Boolean Enable or disable autocompleter
dropdownHeight false 120 false Integer Dropdown's height in pixels
dropdownWidth false same as textbox false Integer Dropdown's width
emptyOption false false String Decide if an empty option is to be inserted. Default false.
errorNotifyTopics false false String Comma delimmited list of topics that will published after the request(if the request fails)
forceValidOption false false false Boolean Force selection to be one of the options
formFilter false false String Function name used to filter the fields of the form
formId false false String Form id whose fields will be serialized and passed as parameters
headerKey false false String Set the header key for the header option.
headerValue false false String Set the header value for the header option.
href false false String The URL used to load the options
iconPath false false String Path to icon used for the dropdown
id false false String The id to use for the element
indicator false false String Id of element that will be shown while request is made
javascriptTooltip false false false Boolean Use JavaScript to generate tooltips
key false false String Set the key (name, value, label) for this particular component
keyName false false String Name of the field to which the selected key will be assigned
label false false String Label expression used for rendering a element specific label
labelSeparator false : false String String that will be appended to the labe
labelposition false false String Define label position of form element (top/left)
list false false String Iteratable source to populate from.
listKey false false String Set the key used to retrive the option key.
listValue false false String Set the value used to retrive the option value.
listenTopics false false String Topic that will trigger a reload
loadMinimumCount false 3 false Integer Minimum number of characters that will force the content to be loaded
loadOnTextChange false true false Boolean Options will be reloaded everytime a character is typed on the textbox
maxLength false false Integer Deprecated. Use maxlength instead.
maxlength false false Integer HTML maxlength attribute
name false false String The name to set for element
notifyTopics false false String Topics that will be published when content is reloaded
onblur false false String Set the html onblur attribute on rendered html element
onchange false false String Set the html onchange attribute on rendered html element
onclick false false String Set the html onclick attribute on rendered html element
ondblclick false false String Set the html ondblclick attribute on rendered html element
onfocus false false String Set the html onfocus attribute on rendered html element
onkeydown false false String Set the html onkeydown attribute on rendered html element
onkeypress false false String Set the html onkeypress attribute on rendered html element
onkeyup false false String Set the html onkeyup attribute on rendered html element
onmousedown false false String Set the html onmousedown attribute on rendered html element
onmousemove false false String Set the html onmousemove attribute on rendered html element
onmouseout false false String Set the html onmouseout attribute on rendered html element
onmouseover false false String Set the html onmouseover attribute on rendered html element
onmouseup false false String Set the html onmouseup attribute on rendered html element
onselect false false String Set the html onselect attribute on rendered html element
preload false true false Boolean Load options when page is loaded
readonly false false false Boolean Whether the input is readonly
required false false false Boolean If set to true, the rendered element will indicate that input is required
requiredposition false false String Define required position of required form element (left|right)
resultsLimit false 30 false String Limit how many results are shown as autocompletion options, set to -1 for unlimited results
searchType false stringstart false String how the search must be performed, options are: 'startstring', 'startword' and 'substring'
showDownArrow false true false Boolean Show or hide the down arrow button
size false false Integer HTML size attribute
tabindex false false String Set the html tabindex attribute on rendered html element
template false false String The template (other than default) to use for rendering the element
templateCssPath false false String Template css path
templateDir false false String The template directory.
title false false String Set the html title attribute on rendered html element
tooltip false false String Set the tooltip of this particular component
tooltipConfig false false String Deprecated. Use individual tooltip configuration attributes instead.
tooltipCssClass false StrutsTTClassic false String CSS class applied to JavaScrip tooltips
tooltipDelay false Classic false String Delay in milliseconds, before showing JavaScript tooltips
tooltipIconPath false false String Icon path used for image that will have the tooltip
transport false XMLHTTPTransport false String Transport used by Dojo to make the request
value false false String Preset the value of input element
valueNotifyTopics false false String Comma delimmited list of topics that will published when a value is selected

Examples

Get list from an action:

<p>Autocompleter that gets its list from an action:</p>
<pre>
<sx:autocompleter name="autocompleter1" href="%{jsonList}"/>
</pre>

Uses a list:

<p>Autocompleter that uses a list:</p>
<pre>
<s:autocompleter name="test"  list="{'apple','banana','grape','pear'}" autoComplete="false"/>
</pre>

Autocompleter that reloads its content everytime the text changes (and the length of the text is greater than 3):

<p>Autocompleter that reloads its content everytime the text changes (and the length of the text is greater than 3):</p>
<pre>
<sx:autocompleter name="mvc" href="%{jsonList}" loadOnTextChange="true" loadMinimumCount="3"/>

The text entered on the autocompleter is passed as a parameter to the url specified in "href", like (text is "struts"):
 
http://host/example/myaction.do?mvc=struts
</pre>

Linking two autocompleters:

<p>Linking two autocompleters:</p>
<form id="selectForm">
     <sx:autocompleter  name="select" list="{'fruits','colors'}"  valueNotifyTopics="/changed" />
</form>  
<sx:autocompleter  href="%{jsonList}" formId="selectForm" listenTopics="/changed"/>

Set/Get selected values using JavaScript:

<p>Set/Get selected values using JavaScript</p>
<sx:autocompleter  href="%{jsonList}" id="auto"/>
<script type="text/javascript">
  function getValues() {
     var autoCompleter = dojo.widget.byId("auto");
     
     //key (in the states example above, "AL")
     var key = autoCompleter.getSelectedKey();
     alert(key);
     
     //value (in the states example above, "Alabama")
     var value = autoCompleter.getSelectedValue();
     alert(value);
     
     //text currently on the textbox (anything the user typed)
     var text = autoCompleter.getText();
     alert(text);
  }

  function setValues() {
     var autoCompleter = dojo.widget.byId("auto");
     
     //key (key will be set to "AL" and value to "Alabama")
     autoCompleter.setSelectedKey("AL");
     
     //value (key will be set to "AL" and value to "Alabama")
     autoCompleter.setAllValues("AL", "Alabama");
  }
</script>

<p>Using beforeNotifyTopics:</p>
<script type="text/javascript">
dojo.event.topic.subscribe("/before", function(event, widget){
    alert('inside a topic event. before request');
    //event: set event.cancel = true, to cancel request
    //widget: widget that published the topic
});
</script>         

<sx:autocompleter beforeNotifyTopics="/before" href="%{#ajaxTest} />

<p>Using afterNotifyTopics:</p>
<script type="text/javascript">
dojo.event.topic.subscribe("/after", function(data, request, widget){
    alert('inside a topic event. after request');
    //data : JavaScript object from parsing response
    //request: XMLHttpRequest object
    //widget: widget that published the topic
});
</script>        

<sx:autocompleter afterNotifyTopics="/after" href="%{#ajaxTest}" />

<p>Using errorNotifyTopics:</p>
<script type="text/javascript">
dojo.event.topic.subscribe("/error", function(error, request, widget){
    alert('inside a topic event. on error');
    //error : error object (error.message has the error message)
    //request: XMLHttpRequest object
    //widget: widget that published the topic
});
</script>

<sx:autocompleter errorNotifyTopics="/error" href="%{#ajaxTest}" />

<p>Using valueNotifyTopics and indicator:</p>
<script type="text/javascript">
dojo.event.topic.subscribe("/value", function(value, key, text, widget){
    alert('inside a topic event. after value changed');
    //value : selected value (like "Florida" in example above)
    //key: selected key (like "FL" in example above)
    //text: text typed into textbox
    //widget: widget that published the topic
});
</script>   

<sx:autocompleter valueNotifyTopics="/value" href="%{#ajaxTest}" />

rutsTag(name="autocompleter", tldTagClass="org.apache.struts2.dojo.views.jsp.ui.AutocompleterTag", description="Renders a combobox with autocomplete and AJAX capabilities")
lic class Autocompleter extends ComboBox {
 public static final String TEMPLATE = "autocompleter";
 final private static String COMPONENT_NAME = Autocompleter.class.getName();

 protected String forceValidOption;
 protected String searchType;
 protected String autoComplete;
 protected String delay;
 protected String disabled;
 protected String href;
 protected String dropdownWidth;
 protected String dropdownHeight;
 protected String formId;
 protected String formFilter;
 protected String listenTopics;
 protected String notifyTopics;
 protected String indicator;
 protected String loadOnTextChange;
 protected String loadMinimumCount;
 protected String showDownArrow;
 protected String templateCssPath;
 protected String iconPath;
 protected String keyName;
 protected String dataFieldName;
 protected String beforeNotifyTopics;
 protected String afterNotifyTopics;
 protected String errorNotifyTopics;
 protected String valueNotifyTopics;
 protected String resultsLimit;
 protected String transport;
 protected String preload;
 
 public Autocompleter(ValueStack stack, HttpServletRequest request,
         HttpServletResponse response) {
     super(stack, request, response);
 }

 protected String getDefaultTemplate() {
     return TEMPLATE;
 }

 public String getComponentName() {
     return COMPONENT_NAME;
 }


 public void evaluateExtraParams() {
     super.evaluateExtraParams();

     if (forceValidOption != null)
         addParameter("forceValidOption", findValue(forceValidOption,
                 Boolean.class));
     if (searchType != null) {
         String type =  findString(searchType);
         if(type != null)
             addParameter("searchType", type.toUpperCase());
     }
     if (autoComplete != null)
         addParameter("autoComplete", findValue(autoComplete, Boolean.class));
     if (delay != null)
         addParameter("delay", findValue(delay, Integer.class));
     if (disabled != null)
         addParameter("disabled", findValue(disabled, Boolean.class));
     if (href != null) {
         addParameter("href", findString(href));
         addParameter("mode", "remote");
     }
     if (dropdownHeight != null)
         addParameter("dropdownHeight", findValue(dropdownHeight, Integer.class));
     if (dropdownWidth != null)
         addParameter("dropdownWidth", findValue(dropdownWidth, Integer.class));
     if (formFilter != null)
       addParameter("formFilter", findString(formFilter));
     if (formId != null)
       addParameter("formId", findString(formId));
     if (listenTopics != null)
       addParameter("listenTopics", findString(listenTopics));
     if (notifyTopics != null)
       addParameter("notifyTopics", findString(notifyTopics));
     if (indicator != null)
         addParameter("indicator", findString(indicator));
     if (loadOnTextChange != null)
         addParameter("loadOnTextChange", findValue(loadOnTextChange, Boolean.class));
     if (loadMinimumCount != null)
         addParameter("loadMinimumCount", findValue(loadMinimumCount, Integer.class));
     if (showDownArrow != null)
         addParameter("showDownArrow", findValue(showDownArrow, Boolean.class));
     else
         addParameter("showDownArrow", Boolean.TRUE);
     if (templateCssPath != null)
         addParameter("templateCssPath", findString(templateCssPath));
     if (iconPath != null)
         addParameter("iconPath", findString(iconPath));
     if (dataFieldName != null)
         addParameter("dataFieldName", findString(dataFieldName));
     if (keyName != null)
         addParameter("keyName", findString(keyName));
     else {
         keyName = name + "Key";
         addParameter("keyName", findString(keyName));
     }
     if (transport != null)
         addParameter("transport", findString(transport));
     if (preload != null)
         addParameter("preload", findValue(preload, Boolean.class));
     
     String keyNameExpr = "%{" + keyName + "}";
     addParameter("key", findString(keyNameExpr));
     
     if (beforeNotifyTopics != null)
         addParameter("beforeNotifyTopics", findString(beforeNotifyTopics));
     if (afterNotifyTopics != null)
         addParameter("afterNotifyTopics", findString(afterNotifyTopics));
     if (errorNotifyTopics != null)
         addParameter("errorNotifyTopics", findString(errorNotifyTopics));
     if (valueNotifyTopics != null)
         addParameter("valueNotifyTopics", findString(valueNotifyTopics));
     if (resultsLimit != null)
         addParameter("searchLimit", findString(resultsLimit));
     
     boolean generateId = !(Boolean)stack.getContext().get(Head.PARSE_CONTENT);
     addParameter("pushId", generateId);
     if ((this.id == null || this.id.length() == 0) && generateId) {
         Random random = new Random();
         this.id = "widget_" + Math.abs(random.nextInt());
         addParameter("id", this.id);
     }
 }

 @Override
 @StrutsTagSkipInheritance
 public void setTheme(String theme) {
     super.setTheme(theme);
 }
 
 @Override
 public String getTheme() {
     return "ajax";
 }
 
 protected Object findListValue() {
     return (list != null) ? findValue(list, Object.class) : null;
 }

 @StrutsTagAttribute(description="Whether autocompleter should make suggestion on the textbox", type="Boolean", defaultValue="false")
 public void setAutoComplete(String autoComplete) {
     this.autoComplete = autoComplete;
 }

 @StrutsTagAttribute(description="Enable or disable autocompleter", type="Boolean", defaultValue="false")
 public void setDisabled(String disabled) {
     this.disabled = disabled;
 }

 @StrutsTagAttribute(description="Force selection to be one of the options", type="Boolean", defaultValue="false")
 public void setForceValidOption(String forceValidOption) {
     this.forceValidOption = forceValidOption;
 }

 @StrutsTagAttribute(description="The URL used to load the options")
 public void setHref(String href) {
     this.href = href;
 }

 @StrutsTagAttribute(description="Delay before making the search", type="Integer", defaultValue="100")
 public void setDelay(String searchDelay) {
     this.delay = searchDelay;
 }

 @StrutsTagAttribute(description="how the search must be performed, options are: 'startstring', 'startword' " +
             "and 'substring'", defaultValue="stringstart")
 public void setSearchType(String searchType) {
     this.searchType = searchType;
 }

 @StrutsTagAttribute(description="Dropdown's height in pixels", type="Integer", defaultValue="120")
 public void setDropdownHeight(String height) {
     this.dropdownHeight = height;
 }

 @StrutsTagAttribute(description="Dropdown's width", type="Integer", defaultValue="same as textbox")
 public void setDropdownWidth(String width) {
     this.dropdownWidth = width;
 }

 @StrutsTagAttribute(description="Function name used to filter the fields of the form")
 public void setFormFilter(String formFilter) {
   this.formFilter = formFilter;
 }

 @StrutsTagAttribute(description="Form id whose fields will be serialized and passed as parameters")
 public void setFormId(String formId) {
   this.formId = formId;
 }

 @StrutsTagAttribute(description="Topic that will trigger a reload")
 public void setListenTopics(String listenTopics) {
   this.listenTopics = listenTopics;
 }

 @StrutsTagAttribute(description="Topics that will be published when content is reloaded")
 public void setNotifyTopics(String onValueChangedPublishTopic) {
   this.notifyTopics = onValueChangedPublishTopic;
 }

 @StrutsTagAttribute(description="Id of element that will be shown while request is made")
 public void setIndicator(String indicator) {
     this.indicator = indicator;
 }

 @StrutsTagAttribute(description="Minimum number of characters that will force the content to be loaded", type="Integer", defaultValue="3")
 public void setLoadMinimumCount(String loadMinimumCount) {
     this.loadMinimumCount = loadMinimumCount;
 }

 @StrutsTagAttribute(description="Options will be reloaded everytime a character is typed on the textbox", type="Boolean", defaultValue="true")
 public void setLoadOnTextChange(String loadOnType) {
     this.loadOnTextChange = loadOnType;
 }

 @StrutsTagAttribute(description="Show or hide the down arrow button", type="Boolean", defaultValue="true")
 public void setShowDownArrow(String showDownArrow) {
     this.showDownArrow = showDownArrow;
 }

 // Override as not required
 @StrutsTagAttribute(description="Iteratable source to populate from.")
 public void setList(String list) {
     super.setList(list);
 }
 
 @StrutsTagAttribute(description="Template css path")
 public void setTemplateCssPath(String templateCssPath) {
     this.templateCssPath = templateCssPath;
 }
 
 @StrutsTagAttribute(description="Path to icon used for the dropdown")
 public void setIconPath(String iconPath) {
     this.iconPath = iconPath;
 }
 
 @StrutsTagAttribute(description="Name of the field to which the selected key will be assigned")
 public void setKeyName(String keyName) {
    this.keyName = keyName;
 }

 @StrutsTagAttribute(description="Name of the field in the returned JSON object that contains the data array", defaultValue="Value specified in 'name'")
 public void setDataFieldName(String dataFieldName) {
     this.dataFieldName = dataFieldName;
 }
 
 @StrutsTagAttribute(description="The css class to use for element")
 public void setCssClass(String cssClass) {
     super.setCssClass(cssClass);
 }

 @StrutsTagAttribute(description="The css style to use for element")
 public void setCssStyle(String cssStyle) {
     super.setCssStyle(cssStyle);
 }

 @StrutsTagAttribute(description="The id to use for the element")
 public void setId(String id) {
     super.setId(id);
 }

 @StrutsTagAttribute(description="The name to set for element")
 public void setName(String name) {
     super.setName(name);
 }

 @StrutsTagAttribute(description="Preset the value of input element")
 public void setValue(String arg0) {
     super.setValue(arg0);
 }
 
 @StrutsTagAttribute(description="Comma delimmited list of topics that will published after the request(if the request succeeds)")
 public void setAfterNotifyTopics(String afterNotifyTopics) {
     this.afterNotifyTopics = afterNotifyTopics;
 }

 @StrutsTagAttribute(description="Comma delimmited list of topics that will published before the request")
 public void setBeforeNotifyTopics(String beforeNotifyTopics) {
     this.beforeNotifyTopics = beforeNotifyTopics;
 }

 @StrutsTagAttribute(description="Comma delimmited list of topics that will published after the request(if the request fails)")
 public void setErrorNotifyTopics(String errorNotifyTopics) {
     this.errorNotifyTopics = errorNotifyTopics;
 }

 @StrutsTagAttribute(description="Comma delimmited list of topics that will published when a value is selected")
 public void setValueNotifyTopics(String valueNotifyTopics) {
     this.valueNotifyTopics = valueNotifyTopics;
 }
 
 @StrutsTagAttribute(description="Limit how many results are shown as autocompletion options, set to -1 for unlimited results", defaultValue="30")
 public void setResultsLimit(String resultsLimit) {
     this.resultsLimit = resultsLimit;
 }
 
 @StrutsTagAttribute(description="Transport used by Dojo to make the request", defaultValue="XMLHTTPTransport")
 public void setTransport(String transport) {
     this.transport = transport;
 }
 
 @StrutsTagAttribute(description="Load options when page is loaded", type="Boolean", defaultValue="true")
 public void setPreload(String preload) {
     this.preload = preload;
 }

Using beforeNotifyTopics:

<p>Using beforeNotifyTopics:</p>
<script type="text/javascript">
dojo.event.topic.subscribe("/before", function(event, widget){
    alert('inside a topic event. before request');
    //event: set event.cancel = true, to cancel request
    //widget: widget that published the topic
});
</script>         

<sx:autocompleter beforeNotifyTopics="/before" href="%{#ajaxTest} />

Using errorNotifyTopics:

<p>Using afterNotifyTopics:</p>
<script type="text/javascript">
dojo.event.topic.subscribe("/after", function(data, request, widget){
    alert('inside a topic event. after request');
    //data : JavaScript object from parsing response
    //request: XMLHttpRequest object
    //widget: widget that published the topic
});
</script>        

<sx:autocompleter afterNotifyTopics="/after" href="%{#ajaxTest}" />

Using errorNotifyTopics:

<p>Using errorNotifyTopics:</p>
<script type="text/javascript">
dojo.event.topic.subscribe("/error", function(error, request, widget){
    alert('inside a topic event. on error');
    //error : error object (error.message has the error message)
    //request: XMLHttpRequest object
    //widget: widget that published the topic
});
</script>

<sx:autocompleter errorNotifyTopics="/error" href="%{#ajaxTest}" />

Using valueNotifyTopics:

<script type="text/javascript">
dojo.event.topic.subscribe("/value", function(value, key, text, widget){
    alert('inside a topic event. after value changed');
    //value : selected value (like "Florida" in example above)
    //key: selected key (like "FL" in example above)
    //text: text typed into textbox
    //widget: widget that published the topic
});
</script>   

<sx:autocompleter valueNotifyTopics="/value" href="%{#ajaxTest}" />