Immediate mode not working

Hello,

I tried to make a very simple login page with dynamic components ; the login button is disabled until both the textfield and the passwordfield are filled in.

Here is the code :
http://pastebin.com/Frd6Wgs5

Everything is working except for loginValueListener ; he is only fired when I click out of the TextField, and not at every keystroke as it should be ; I added setImmediate(true) to every textfield and their parent components, but it’s not working…

Do you have any solution ?
Thanks !

Probably, you’re using one instance of the ValueChangeListener in all text fields. You cannot do that.

I already changed it (to test) and it’s not fixing anything =/

OK. I did some changes in your code. Take a look:

public class TestUI extends UI {

    PasswordField passwordTextField;
    TextField usernameTextField;
    Button submitButton;

    @Override
    protected void init(VaadinRequest vaadinRequest) {
        Panel panel = new Panel("Se connecter au tableau de bord");
        panel.setImmediate(true);
        panel.setWidth("450px");

        FormLayout form = new FormLayout();
        form.setImmediate(true);

        usernameTextField = new TextField();
        usernameTextField.setWidth("100%");
        usernameTextField.setInputPrompt("Nom d'utilisateur");
        usernameTextField.setTextChangeEventMode(AbstractTextField.TextChangeEventMode.EAGER);
        usernameTextField.setImmediate(true);
        usernameTextField.addTextChangeListener(new FieldEvents.TextChangeListener() {
            @Override
            public void textChange(FieldEvents.TextChangeEvent event) {
                validate(event.getText(), passwordTextField.getValue());
            }
        });
        usernameTextField.setRequired(true);
        form.addComponent(usernameTextField);

        passwordTextField = new PasswordField();
        passwordTextField.setWidth("100%");
        passwordTextField.setImmediate(true);
        passwordTextField.setTextChangeEventMode(AbstractTextField.TextChangeEventMode.EAGER);
        passwordTextField.addTextChangeListener(new FieldEvents.TextChangeListener() {
            @Override
            public void textChange(FieldEvents.TextChangeEvent event) {
                validate(usernameTextField.getValue(), event.getText());
            }
        });
        passwordTextField.setInputPrompt("Mot de passe");
        passwordTextField.setRequired(true);
        form.addComponent(passwordTextField);

        submitButton = new Button("Se connecter !", new Button.ClickListener() {
            @Override
            public void buttonClick(Button.ClickEvent event) {
                //TODO Connexion si on est activé (pour entrer)
            }
        });

        submitButton.setWidth("100%");
        submitButton.setImmediate(true);
        submitButton.addStyleName(ValoTheme.BUTTON_PRIMARY);
        submitButton.setClickShortcut(ShortcutAction.KeyCode.ENTER);
        submitButton.setEnabled(false);
        form.addComponent(submitButton);

        panel.setContent(form);
        setContent(panel);
    }

    void validate(String username, String password) {
        System.out.println("checksubmit");
        if (username.isEmpty() || password.isEmpty())
        {
            submitButton.setEnabled(false);
        }
        else
        {
            submitButton.setEnabled(true);
        }
        //       push();
    }
}

First, instead of use ValueChangeListener I use textChangeListener in Eager mode. This change forces all input fields to immediately notify server about text changes.

Although, this solution works, I suggest you do some JS validation at client side. This solution may have generate sluggish performance when connection between client and server is bad.

It works, thanks a lot !

How can I do this on JS part ? It’s true that it would be better since I don’t really need to poll the server just to update a button…

Hi,

I wouldn’t use the “eager” mode for text change listeners. This doesn’t affect usability that much but there is no communication between each and every keypress.

I wouldn’t consider the client side optimization, untill you really find it a problem. The the network is so bad that small server visits are slow, then your web app will be whole anyways. Ensuring your hosting setup supports keep-alive with decent timeout or, even better, WebSockets (push) will help if there is lots of latency in the network.

cheers,
matti