ComboBox - AutoSuggestion / -Complete

I am using combo box as Suggestion/AutoComplete field as recommended in several threads.
However for one combo box there is a choice of 100000 projects. Loading the 100k projects will take some time. I know they are not sent to the client but what I’d like to do is:

  • empty combo box with no items
  • user has to enter at least 3 characters
  • after the 3 characters have been entered, excuting a SQL, something like from project where key like ‘%{user_input}%’

The only thing I need to know is whether I can listen to the ‘filter change’ event and whether I can add new items to the combo box from there.

I already noted that after each keypress an event is sent to ‘com.vaadin.terminal.gwt.client.ui.VFilterSelect’. I want to override this default behaviour or add a listener as I explained above.

Is that possible?

Cheers,
Rene

You have to subclass ComboBox and overwrite the changeVariables method.

public void changeVariables(Object source, Map variables)
{
  String filterString= (String) variables.get("filter");
  if (filterString!=null && filterString.length()>2)
  {
    items.removeAllItems();
    // TODO: setItems(filterString);
  }
  super.changeVariables(source,map);
}				

Then you have to implement the setItems method to add your items.

Thanks!

The AutoComplete became a little bit more complicated because the FilteringMode. I want to show items independent of filtering mode.
Example:
The project A has description “Important Project”, but item caption does not include the description. However my server side filter also finds Project A if user types “Important”. That item gets filtered out by the IndexedContainer/Select.

I found a solution which includes using an own container. If someone is intrested in the code, please let me know and I can post it.

I would like to see your solution.
Thanks!

I am also interested in your solution.

regards

Hi Rene,

would you mind to share your solution?

Regards

Andreas

Hi

i am also interested in knowing how you solved this. Can i have the code?

Hi Rene,

can you share your solution?

Regards

Rene,

I would love to see your solution please!

Thanks

Hi Rene, please share your solution. Thanks!

Hi Rene,

i am also interested in knowing how you solved this.
Would you mind to share your solution?

Thanks!

Hello everyone,

I think I have an answer on how to solve this problem. Here is my code that I used to solve a similar situation:

//The set up
String PROPERTYID = “property”;
comboBox.setImmediate(true);
comboBox.setFilteringMode(FilteringMode.STARTSWITH);
comboBox.setTextInputAllowed(true);
comboBox.setNullSelectionAllowed(true);
comboBox.setItemCaptionMode(ItemCaptionMode.PROPERTY);
comboBox.setItemCaptionPropertyId(PROPERTYID);
CustomLazyContainer customLazyContainer = new CustomLazyContainer(3,PROPERTYID);
customLazyContainer.addContainerProperty(PROPERTYID, String.class, null);
comboBox.setContainerDataSource(customLazyContainerCUSIP);

//the custom container class
import java.util.Iterator;
import java.util.List;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.data.util.filter.SimpleStringFilter;
import com.vaadin.data.util.filter.UnsupportedFilterException;

public class CustomLazyContainer extends IndexedContainer {

private final int subStringSize;
private final String propertyId;
private String querySubString;

public CustomLazyContainer(int prefixSize, String propertyId){
this.subStringSize = prefixSize;
this.propertyId = propertyId;
} // end two parameter constructor

public CustomLazyContainer() {
subStringSize = 0;
propertyId = “defualt”;
} // end no parameter constructor

public void addContainerFilter(Filter filter) throws UnsupportedFilterException {
//Check to see if the filter is equal to null
if (filter == null) {
//remove the items
removeAllItems();
querySubString = null;
} else{
//remove the items
removeAllItems();
//check to see what type of filter we have
if (filter instanceof SimpleStringFilter) {
//get the query subString from the filter
String newFilterString = ((SimpleStringFilter) filter).getFilterString();
//check to make sure the substring isn’t null and its not equal to the last one
if (newFilterString != null || !(newFilterString.equals(querySubString))){
//set the sub string
querySubString = newFilterString;
//check the size on the sub string
if(querySubString.length() >= subStringSize){
//get the results
queryDatabase();
//add the filter
super.addContainerFilter(filter);
} //end if the substring langth is long enough
}// end if newFilterString doesnt equal null and newFilterString doesnt equal last value
} // end if and instance of Simple Filter
} //end else
} // end addCoontainerFilter method

private void queryDatabase() {

//Query the database here with the code you want
//Store it how ever you want this example uses a list to demonstrate how to get the data to display
List dataList = data base results from query

//add the results to the container
int i = 0;
Iterator iterDataList = dataList.iterator();
while (iterDataList.hasNext()) {
addItem(i);
this.getContainerProperty(i, propertyId).setValue((Data)iterDataList.next());
i++;
}//end while iter has next

}// end queryDataBase method

} //end CustomLazyContainer class

I apologize if the code looks bad. Please feel free to ask me any questions about it. I will be more than happy to respond.

In
this blog post
I describe a solution how to tweak Vaadin’s ComboBox a bit so that you get an autocomplete feature that draws suggestions from the database without having to load all possible values into a com.vaadin.data.Container. There’s no need to write a custom client-side widget.