Disable buttons when commiting form

Hi,
I have some forms which have the button “Send” and “Cancel”. As the send is sometimes slow I need some way to disable both buttons when “Send” is clicked. I know about setDisableOnClick, but with that I can only disable one button.
Can you think of any workaround to be able to disable both when one is clicked?
Thanks

Enkara-

Within your click listener, simply disable the cancel button and visa versa if desired.

Regards,
Eric

Hi Eric, thank you for the suggestion, but the buttons don+t get disabled that way. I think it is because that happens in the server side and it doesn’t get to disable the button before performing the click action.

If the button is set to immediate and you are in the same thread, there should be no issue unless you expect someone to click as fast as they can multiple times on your button. If that is the case make a client side widget for the button to disable it or you can implement a atomic flagging mechanism on the server side that would mask your process if the operating flag is true.

i.e.

myButton.setDisableOnClick(true)
myButton.addClickListener(new Button.ClickListener()
{
    private static final long serialVersionUID = 1L;

    @Override
    public void buttonClick(ClickEvent event)
    {
        if (atomicRunningFlag == true)
                return;

        atomicRunningFlag = true;
        otherButton.setEnabled(false);
        
        try
        {
                myClickProcess();

        } finally {
        
                // All done, allow another click
                atomicRunningFlag = false;
        
                // Enable the buttons when the process has been completed
                otherButton.setEnabled(true);
​                myButton.setEnabled(true);
        }
    }
});

It may not be the best looking implementation, but it works. Both click listeners would have the atomicRunningFlag test.

Regards,
Eric

I must be doing something wrong because that doesn’t work for me. I had tried a similar solution before and now I tried yours but for some reason the cancel button never gets disabled. I debugged and it runs all the code, but it seems like the client is never aware of the disabled button. Both buttons are set to immediate.
Any ideas of what can be wrong?

Ive done some more testing, removing the part where we enable the buttons again. The result is that when the “myclickProcess()” is finished, then the buttons get disabled.

The server won’t and cannot send a response to the client until your processing is finished; this is fundamental to how HTTP works. So, the client will never know that the button was disabled for a while. You could make the processing asynchronous in order to send the disabling response quickly, but that has it’s own gotchas and, due to the inherent existing asynchronity between the client and the server, the user could still click twice while the request is being sent and processed.

Fortunately, Vaadin provides a solution for this problem. The Button.setDisableOnClick method makes it possible to disable buttons automatically on the client side when clicked. Then you can simply call Button.setEnabled(true) at the end of the processing to re-enable it (it will stay disabled until explicitly enabled.)

Hi Johannes, thank you for your explanation.
I know about disableOnClick, my problem is that I want to disable not only the button I click, but also the other buttons in the form (I have Send and Cancel buttons).

So, there is no way to solve my problem in Vaadin?

Enkara-

Of course there is.

You can disable something like my example above but instead of running the myclickProcess() within the same thread, send it to a runner like Johannes alluded to above. As he also stated, your user could still press it again by the time the communication does its rounds, so I would still use an atomic boolean to mask the extra presses. But doing it like this, the user should see the disables very soon after a button was pressed.

I tend to use another ‘processing thread’ everytime (unless it is a small process) for a better user experience anyways.

Again, you can possibly make a widget on the client side to do the disable process immediately. I do not have much experience in that, but there are examples to follow on the site.

Regards,
Eric

Oh ok I see now, sorry.
I’ll try it the way you say :slight_smile: Thank you for the help!

Hi again, I could get it to work using asynchronous calls and Push.
My problem now is that the default progressindicator doesn’t show. Is there any way to make it show?

I posted all my new problems with this solution in an another thread:
https://vaadin.com/forum#!/thread/9084237