Question

I have an app that has editors for various database records. These records are referencing each other. I'm developing a new custom data-aware component that is based on ComboBox:

public abstract class CustomDbLookupField<T> extends CustomField<T> implements Field<T> 

Here is what I want:

  • the component looks like a combo box (I could do this easily)
  • when the corresponding field has a row id value, then the component displays the textual representation of that referenced record (I could also do this)
  • when the user starts typing text in the combobox, then I want to search for keywords in the database, and populate the combobox with those items, and let then
  • drop down the combo box for him and et him select from the results

I cannot seem to do the last two parts. I wanted to bind listener to the "text typed into combo box" event, but I cannot find any method for that. Moreover, I don't know how to get the text that was just typed in. I was trying this:

cmb.addListener(com.vaadin.event.FieldEvents.TextChangeEvent.class,target, method);

but I don't know what to pass for parameters target and method.

Was it helpful?

Solution

That's a good question, and one that cannot be answered in a few sentences. I'll try to give you a short answer upfront and will try to elaborate more on this later. I'm currently hacking a small example to demonstrate the feature you want to achieve. But I'll need some more time. I'll update my answer as soon as I have some results.

Until then, the short answer to your question is that if you register a listener for TextChangeEvents on a component, you'll need someone to actually fire these events. This typically happens on the client side, for example in a TextField. When you derive from CustomField you still need to provide some client side implemenation. CustomField is only a base implementation for your custom field implementation without an awful lot of ready-to-go client side functionality. So, in your case, the listener for TextChangeEvents will actually never be invoked.

You can do a lot easier by deriving from ComboBox. ComboBox already has built-in support for prefix filtering when typing in text into the ComboBox. The actual filter functionality is implemented in the Container which is data source to the ComboBox. The trick is to overwrite protected method ComboBox#getOptionsWithFilter(boolean) to filter in the database and use a custom Container implementation which provides the filtered items from the database.

Update: As promised, I have written a small demo application which shows how you can write a custom ComboBox whose items are dynamically populated from the database as the user types in text. This can be achieved with a simple hack by deriving from ComboBox and overwriting method com.vaadin.ui.ComboBox.buildFilter(String, FilteringMode). The overridden method will need to return a custom Container.Filter implementation that simply carries over the current filter String to a custom com.vaadin.data.Container implementation. The container is then responsible for fetching the filtered items from the database and populating itself with the query result. In my example, I derive from BeanItemContainer where I do the custom database filtering in the overridden method de.oio.vaadin.SuggestingContainer.addFilter(Filter)

You can check out the demo at my GitHub project. Don't hesitate to ask if there is anything unclear.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top