Je souhaite mettre à jour instantanément un champ de texte lors de la saisie dans une zone de texte GWT. Mon problème est que les gestionnaires ValueChangeEvent et ChangeEvent ne sont déclenchés que lorsque la zone de texte perd le focus. J'ai pensé à utiliser KeyPressEvent, mais rien ne se produirait lors d'un copier-coller avec la souris.
Quel est le moyen le plus simple de faire ça?
Vous pouvez intercepter l'événement ONPASTE
et déclencher manuellement une ValueChangeEvent
. Quelque chose comme ça:
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;
}
}
}
Testé sur Firefox 3.6.1.
Comme solution générale, ce qui fonctionne pour moi (merci au commentaire de Gal-Bracha):
En règle générale, GWT ne dispose pas de classes pour gérer les événements d'entrée (décrit ici Et ici ). Nous devons donc le mettre en œuvre nous-mêmes:
Classe de gestionnaire:
import com.google.gwt.event.shared.EventHandler;
public interface InputHandler extends EventHandler {
void onInput(InputEvent event);
}
Classe de l'événement:
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());
Cela fonctionne à chaque changement de valeur dans TextBox, y compris le collage à l'aide du menu contextuel Il ne réagit pas sur les flèches, ctrl, shift, etc.
Cela a été un problème majeur pour moi dans le passé. KeyupHandler ne fonctionnera pas, car le copier-coller nécessite une seconde pression sur l'option Coller qui ne déclenche pas l'événement. le mieux que j'ai pu faire est d'utiliser l'ancien changelistener pas idéal, mais cela fonctionne.
Pourquoi ne pas utiliser la combinaison de KeyUpHandler et d'un ChangeHandler sur la zone de texte? Devrait s’occuper du retour immédiat de chaque frappe ainsi que du cas du copier-coller.
Je préfère utiliser Elements
que Widgets
donc c'est ma façon de le manipuler.
Element input = Document.get().getElementById("my-input");
DOM.sinkBitlessEvent(input, "input");
DOM.setEventListener(input, event -> GWT.log("Event!"));
Just saw this question. Because I was facing the similar problem.
Est-ce que quelques hack et ça a fonctionné pour moi. Vous pouvez utiliser KeyUpHandler, mais avec un bloc supplémentaire si vérifiant que Détermine la longueur de la zone de texte. Si la longueur de la zone de texte est> 0, faites votre chose. Ex:
textBox.addKeyUpHandler(new KeyUpHandler() {
@Override
public void onKeyUp(KeyUpEvent keyUpEvent) {
if (textBox.getText().length() > 0) {
//do your stuff`enter code here`
}
}