5 Replies Latest reply on May 7, 2009 6:29 PM by kiversen

    Newbie: Autocomplete rich:combobox

      Pls help.

      Quite new to richfaces and struggles to be familiar with the components. Currently running version 3.3.1-SNAPSHOT and are facing a problem with autocomplete. Have seen through the live demos but still, not able to implement the solution I want.


      Case:

      A user starts typing the letters for a country and a list of choices (countries matching the input) is presented, like the autocomplete function.
      I have seen the demos (https://www.redhat.com/apps/WebForm/richfaces_demo.html - you need to register) and suspects I should use either the rich:comboBox or the rich:suggestionBox.

      However, I want the value for the chosen country stored back in a variable, but for the user, the country should be listed with it's name, like the old value/label object.

      I have a List (java.util) and it's populated with some Country objects with getters and setters for the countryCode and countryName variables.

      So, how to get either the rich:comboBox or rich:suggestionBox to display the countryName as a label and store the countryCode (for the selected country) back to the backingbean?

      As long as I'm not using a Country object in the list, purely the country names as String, the rich:comboBox works fine, but naturally it won't give me the countryCode.

      In my mind I was thinking (and this is code that is not meant to actually work)

      <rich:comboBox id="someId" var="c" suggestionValues="#{countryBean.countries}"
      itemLabel="c.countryName" itemValue="c.countryCode" value="#{countryBean.selectedCountry}"
      </rich:comboBox>
      


      Maybe I am looking at the wrong component for all I know.

      All advices is highly appreciated!










        • 1. Re: Newbie: Autocomplete rich:combobox

          Just discovered that the rich:comboBox appearantly is not the component to use. It's not for select purposes.

          Can anyone pls post a code example for achieving this with the proper component? I was thinking richfaces had some nice solutions for this kind of operations since it's constantly in use when developing web-apps.

          • 2. Re: Newbie: Autocomplete rich:combobox
            ilya_shaikovsky

            how about inplace select component? It's the pure select component.

            • 3. Re: Newbie: Autocomplete rich:combobox

              Hi ilya and thanks for your reply.

              how about inplace select component?


              Yes, but that produces purely a dropdown, no?
              So, if you have, say a hundred options, it won't do any good, since a dropdown should consists of a small amount of choices as far I'm concerned.

              What I need, is the features the rich:comboBox provides with the autocomplete option, ajax way and navigating with the arrowkeys. You start typing in a textfield and the possible outcome appears and you can then narrow it down to the choice you are after and get hold of the corresponding value.






              • 4. Re: Newbie: Autocomplete rich:combobox
                ilya_shaikovsky

                then seems suggestion box will works for you. It will be more complicated solution but at least you'll be able to work with the objects instead of just strings. wiki contains article about passing additional param after suggestion selection and demo contains code of using objects selectino feature(this might be not needed.. start with just additional parameters on onselect and check if it enough for your case).

                • 5. Re: Newbie: Autocomplete rich:combobox

                  I think you are right ilya.

                  After spending some time with the rich:suggestionbox I came up with a solution that might be helpful for others aswell. It looks like the rich:combobox component, and you can either type your criteria in a textfield or select from a list, much the same as you do with the rich:combobox component. But, since it is a suggestionbox, you will be able to grab the itemvalue aswell. This is typically what's going on in most web-apps; present the choices with itemlabels but grab the itemvalue for further processing.
                  Please post comments on how this could be done more sophisticated.


                  ItemBean.java

                  package com.acme.web.view.bean;
                  
                  import java.util.ArrayList;
                  import java.util.List;
                  
                  public class ItemBean {
                  
                   private String selectedItemLabel;
                   private Long selectedItemValue;
                  
                  
                   public ItemBean() {}
                  
                   public String getSelectedItemLabel() {
                   return selectedItemLabel;
                   }
                  
                   public void setSelectedItemLabel(String selectedItemLabel) {
                   this.selectedItemLabel = selectedItemLabel;
                   }
                  
                   public void setSelectedItemValue(Long selectedItemValue) {
                   this.selectedItemValue = selectedItemValue;
                   }
                  
                   public Long getSelectedItemValue() {
                   return selectedItemValue;
                   }
                  
                  
                   /**
                   * Autocomplete handling
                   */
                   public List<Item> autocomplete(Object suggest) {
                   String pref = (String)suggest;
                   ArrayList<Item> result = new ArrayList<Item>();
                  
                   for (Item item : getItems()) {
                   if ((item.getLabel() != null && item.getLabel().toLowerCase().indexOf(pref.toLowerCase()) == 0) || "".equals(pref)) {
                   result.add(item);
                   }
                   }
                   return result;
                   }
                  
                   /**
                   * Simply populating a List with Item objects
                   *
                   */
                   public List<Item> getItems() {
                   List<Item> itemList = new ArrayList<Item>();
                   itemList.add(new Item(0L,"Item 0"));
                   itemList.add(new Item(1L,"Item 1"));
                   itemList.add(new Item(2L,"Item 2"));
                   itemList.add(new Item(3L,"Item 3"));
                   itemList.add(new Item(4L,"Item 4"));
                   itemList.add(new Item(5L,"Item 5"));
                   return itemList;
                   }
                  
                  
                   /**
                   * Using an inner class to make it simple
                   */
                   public class Item {
                   private Long value;
                   private String label;
                  
                   public Item(Long value, String label) {
                   this.value = value;
                   this.label = label;
                   }
                  
                   public Long getValue() {
                   return value;
                   }
                  
                   public String getLabel() {
                   return label;
                   }
                  
                   public void setValue(Long value) {
                   this.value = value;
                   }
                  
                   public void setLabel(String label) {
                   this.label = label;
                   }
                   }
                  
                  }
                  



                  Snippet from faces-config.xml
                   <managed-bean>
                   <description>ItemBean</description>
                   <managed-bean-name>itemBean</managed-bean-name>
                   <managed-bean-class>com.acme.web.view.bean.ItemBean</managed-bean-class>
                   <managed-bean-scope>request</managed-bean-scope>
                   </managed-bean>
                  


                  The jsp
                  Pay attention to the use of an image, this is how you can display all the choices. The rich:suggestionbox (out-of-the-box) simply provides an input field. BTW, you can download the image from the live demo examples, or make your own.
                  <!DOCTYPE html public "-//w3c//dtd html 4.0 transitional//en">
                  <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
                  <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
                  <%@ taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
                  <%@ taglib uri="http://richfaces.org/rich" prefix="rich"%>
                  
                  
                  <f:view>
                   <h:form id="test">
                   <h:panelGrid columns="2">
                   <h:outputText value="Select item: " />
                   <h:panelGrid columns="2" border="0" cellpadding="0" cellspacing="0">
                   <h:inputText id="iteminput" style="margin:0px;" value="#{itemBean.selectedItemLabel}" />
                   <h:graphicImage value="/images/arrow.png" onclick="#{rich:component('suggestion')}.callSuggestion(true)" alt="" />
                   </h:panelGrid>
                  
                   <rich:suggestionbox
                   height="200"
                   width="200"
                   nothingLabel="Not in list"
                   suggestionAction="#{itemBean.autocomplete}"
                   var="item"
                   for="iteminput"
                   fetchValue="#{item.label}"
                   id="suggestion">
                   <h:column>
                   <h:outputText value="#{item.label}" />
                   </h:column>
                   <a4j:support event="onselect">
                   <f:setPropertyActionListener value="#{item.value}" target="#{itemBean.selectedItemValue}" />
                   </a4j:support>
                   </rich:suggestionbox>
                   </h:panelGrid>
                   </h:form>
                  </f:view>