2010-07-06 6 views
25

Me gustaría actualizar un campo de texto al instante al escribir en un cuadro de texto GWT. Mi problema es que los manejadores ValueChangeEvent y ChangeEvent solo se activan cuando el TextBox pierde el foco. Pensé en usar KeyPressEvent pero luego no pasaría nada al realizar una copia pegar con el mouse.Controlador de cambio de valor instantáneo en un cuadro de texto GWT

¿Cuál es la forma más sencilla de hacerlo?

Respuesta

32

Puede ver el evento ONPASTE y disparar manualmente un ValueChangeEvent. Algo como esto:

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; 
     } 
    } 
} 

Probado en firefox 3.6.1.

+1

Gracias. Esto funcionó para mí. Una cosa que los demás deben tener en cuenta es que se requiere el comando diferido porque el TextBox aún no contiene el texto de interés cuando se maneja el evento pegar. Si está intentando filtrar el contenido del cuadro de texto (en mi caso, para caracteres válidos), tenga en cuenta que un usuario verá momentáneamente el texto pegado. Alguien sabe alguna forma de evitar esto? Según lo que he leído, FF no permite la inspección del portapapeles, ¿pero IE y Webkit sí? – ShabbyDoo

+0

Lo que podría hacer es ocultar el contenido de 'TextBox' hasta que se complete la validación. Es realmente un truco, pero 'color: transparent' haría el truco ... – z00bs

+0

@ z00bs ¿Es esto posible sin extender TextArea y usar UiBinder? – alexandroid

0

¿Por qué no utilizar la combinación de KeyUpHandler y ChangeHandler en el TextBox? Debe encargarse de recibir comentarios inmediatos sobre cada pulsación de tecla y también copiar el caso de pegar.

+0

Como dije, ChangeHandler solo se dispara una vez que el TextBox pierde el foco, pero me gustaría actualizar mi campo de forma instantánea (mientras el usuario escribe). – Jla

+0

Hmmm ... ¿Has descubierto una forma? Comparte la solución cuando lo hagas :) Gracias –

+0

Después de todo, se aceptó el cambio de comportamiento en la pérdida de foco para la aplicación en la que estaba trabajando. Entonces nunca encontré una solución y la dejé de lado por el momento. Pero actualizaré la pregunta si alguna vez encuentro una. – Jla

1

Esto ha sido un problema importante para mí en el pasado. KeyupHandler no funcionará porque copiar y pegar requiere una segunda pulsación de tecla en la opción pegar que no desencadena el evento. lo mejor que he podido hacer es utilizar el antiguo changelistener no ideal, pero funciona.

+0

Además, copiar y pegar se puede hacer con el mouse. – Jla

+1

Es mejor utilizar el evento de entrada, pero no estoy seguro de cómo acceder desde gwt. Maneja tanto el pegado como el teclado, ya que aumenta cuando el valor realmente cambia.https://developer.mozilla.org/en/DOM/DOM_event_reference/input –

0
Just saw this question. Because I was facing the similar problem. 

Hice algunos hack y funcionó para mí. Puede usar KeyUpHandler pero usarlo con un bloque adicional que compruebe para la longitud del cuadro de texto. Si la longitud del cuadro de texto es> 0, haga lo suyo. Ex:

textBox.addKeyUpHandler(new KeyUpHandler() { 
    @Override 
    public void onKeyUp(KeyUpEvent keyUpEvent) { 
    if (textBox.getText().length() > 0) { 
    //do your stuff`enter code here` 

    } 
    } 
+0

Esto no tiene en cuenta el arrastre de valores en el cuadro, también se desencadena en la tecla izquierda/derecha, ctrl keyrelease – WORMSS

+0

cierto, esto será aplicable para escribir, que incluye texto. Supongo que servirá de propósito para esta pregunta. Es solo un truco;) –

1

como una solución general, lo que funciona para mí (gracias a Gal-berajá comentario):

En general, GWT no tiene clases para manejar evento de entrada (que se describe here y here) . Así que tenemos que ponerlo en práctica por nosotros mismos:

clase

Handler: Clase

import com.google.gwt.event.shared.EventHandler; 

public interface InputHandler extends EventHandler { 

    void onInput(InputEvent event); 

} 

Evento:

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); 
    } 

} 

Uso:

box.addDomHandler(new InputHandler() { 

    @Override 
    public void onInput(InputEvent event) { 
     text.setText(box.getText()); 
    } 
},InputEvent.getType()); 

Funciona en cada cambio de valor de cuadro de texto que incluye pegar usando el menú contextual. No reacciona con flechas, ctrl, shift, etc ...

+0

Falta "(" después del nuevo Tipo . – Alicia

+0

Solucionado, thx @Alicia – zolv

+0

Recibo este error durante la creación: exception 2 (String): Intentando hundir el tipo de evento desconocido. –

Cuestiones relacionadas