web-dev-qa-db-fra.com

Gestionnaire de changement de valeur instantané sur une zone de texte GWT

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? 

25
Jla

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.

32
z00bs

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.

2
zolv

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. 

1

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.

0
Ashwin Prabhu

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!"));
0
Daniel De León
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`

    }
    }
0
Bikas Katwal