Instant value change handler on a GWT textbox
As a general solution, what works for me (thx to gal-bracha comment):
Generally, GWT does not have classes to handle input event (described here and here). So we need to implement it by ourselves:
Handler class:
import com.google.gwt.event.shared.EventHandler;
public interface InputHandler extends EventHandler {
void onInput(InputEvent event);
}
Event class:
import com.google.gwt.event.dom.client.DomEvent;
public class InputEvent extends DomEvent<InputHandler> {
private static final Type<InputHandler> TYPE = new Type<InputHandler>("input", new InputEvent());
public static Type<InputHandler> getType() {
return TYPE;
}
protected InputEvent() {
}
@Override
public final Type<InputHandler> getAssociatedType() {
return TYPE;
}
@Override
protected void dispatch(InputHandler handler) {
handler.onInput(this);
}
}
Usage:
box.addDomHandler(new InputHandler() {
@Override
public void onInput(InputEvent event) {
text.setText(box.getText());
}
},InputEvent.getType());
It works on every TextBox value change including pasting using context menu. It does not react on arrows, ctrl, shift etc...
This has been a major issue for me in the past. The keyupHandler wont work because the copy paste requires a second key press on the paste option which does not fire the event. the best i have been able to do is use the old changelistener not ideal but it does work.
You could catch the ONPASTE
event and manually fire a ValueChangeEvent
. Something like this:
public void onModuleLoad() {
final Label text = new Label();
final ExtendedTextBox box = new ExtendedTextBox();
box.addValueChangeHandler(new ValueChangeHandler<String>() {
@Override
public void onValueChange(ValueChangeEvent<String> event) {
text.setText(event.getValue());
}
});
box.addKeyUpHandler(new KeyUpHandler() {
@Override
public void onKeyUp(KeyUpEvent event) {
text.setText(box.getText());
}
});
RootPanel.get().add(box);
RootPanel.get().add(text);
}
private class ExtendedTextBox extends TextBox {
public ExtendedTextBox() {
super();
sinkEvents(Event.ONPASTE);
}
@Override
public void onBrowserEvent(Event event) {
super.onBrowserEvent(event);
switch (DOM.eventGetType(event)) {
case Event.ONPASTE:
Scheduler.get().scheduleDeferred(new ScheduledCommand() {
@Override
public void execute() {
ValueChangeEvent.fire(ExtendedTextBox.this, getText());
}
});
break;
}
}
}
Tested on firefox 3.6.1.