Instant value change handler on a GWT textbox

前端 未结 6 1606
清酒与你
清酒与你 2020-12-08 07:25

I would like to update a text field instantly when typing in a GWT TextBox. My problem is that ValueChangeEvent and ChangeEvent handlers only fire when the TextBox loses foc

相关标签:
6条回答
  • 2020-12-08 08:04

    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.

    0 讨论(0)
  • 2020-12-08 08:04
    Just saw this question. Because I was facing the similar problem. 
    

    Did some hack and it worked for me. You can use KeyUpHandler but use it with additional if block that checks for length of textbox. If length of text box is > 0, do your thing. Ex:

    textBox.addKeyUpHandler(new KeyUpHandler() {
        @Override
        public void onKeyUp(KeyUpEvent keyUpEvent) {
        if (textBox.getText().length() > 0) {
        //do your stuff`enter code here`
    
        }
        }
    
    0 讨论(0)
  • 2020-12-08 08:19

    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...

    0 讨论(0)
  • 2020-12-08 08:22

    Why not use combination of both KeyUpHandler and a ChangeHandler on the TextBox? Should take care of immediate feedback on each keystroke as well as copy paste case as well.

    0 讨论(0)
  • 2020-12-08 08:24

    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.

    0 讨论(0)
  • 2020-12-08 08:25

    I prefer use Elements than Widgets so this my way to handler.

        Element input = Document.get().getElementById("my-input");
        DOM.sinkBitlessEvent(input, "input");
        DOM.setEventListener(input, event -> GWT.log("Event!"));
    
    0 讨论(0)
提交回复
热议问题