I try to code a TexField that fire an event (a search) on every key press.
But the event should have a debounce option so that it triggers only after a given time without pressing a key.
I follow this documention: https://vaadin.com/docs/v13/flow/creating-components/tutorial-component-events.html
But I struggle to understand how to add the @DebouceEvent to my TextField...
The event:
@DomEvent(value = "input",
debounce = @DebounceSettings(
timeout = 250,
phases = DebouncePhase.TRAILING))
public class InputEvent extends ComponentEvent<TextField> {
private String value;
public InputEvent(TextField source, boolean fromClient,
@EventData("element.value") String value) {
super(source, fromClient);
this.value = value;
}
public String getValue() {
return value;
}
}
The TextField:
TextField searchField= new TextField("my search");
I tried:
searchField.addInputListener(new InputEvent(searchField, true, "input"));
erro:
Error:(41, 38) java: incompatible types: nc.unc.importparcoursup.view.AdmisDetailView.InputEvent cannot be converted to com.vaadin.flow.component.ComponentEventListener<com.vaadin.flow.component.InputEvent>
There are two problems with this line
searchField.addInputListener(new InputEvent(searchField, true, "input"));
addInputListener
is not for your event, it just happens to be named similarlyIn order to add your custom event, you need to extend the TextField
class (or build your own text field that extends Component
).
I call my field SearchField
public class SearchField extends TextField {
public SearchField(String caption) {
super(caption);
}
}
Next, we can create the event class. I changed the name to SearchEvent
to avoid confusion. I also made the delay larger so that it would be easier to test if it works. Lastly, here it extends ComponentEvent<TextField>
, but it could also extend ComponentEvent<SearchField>
.
@DomEvent(value = "input",
debounce = @DebounceSettings(
timeout = 1000,
phases = DebouncePhase.TRAILING))
public class SearchEvent extends ComponentEvent<TextField> {
private String value;
public SearchEvent(TextField source, boolean fromClient,
@EventData("element.value") String value) {
super(source, fromClient);
this.value = value;
}
public String getValue() {
return value;
}
}
Now we can create a method for adding a listener of this event type in the SearchField class
.
public class SearchField extends TextField {
...
public Registration addSearchListener(ComponentEventListener<SearchEvent> listener) {
return addListener(SearchEvent.class, listener);
}
}
And finally we can try it out
@Route
public class SearchView extends VerticalLayout {
public SearchView() {
SearchField searchField = new SearchField("Search");
searchField.addSearchListener(event -> {
Notification.show("You searched for [" + event.getValue() + "]");
});
add(searchField);
}
}
In Vaadin 14, which is currently in pre-release and should be released shortly, you can simply do
TextField textField = new TextField();
textField.setValueChangeMode(ValueChangeMode.LAZY);