View Javadoc

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