I’m trying to avoid double execution of server functions when double clicking buttons. Possible solutions I’m thinking off right now are:
- Disabling the button when the button is clicked and re-enabling the button once the function is finished
- Working with a state variable that allows/disallows functions getting executed.
Any best practices for this?
Thank you very much in advance.
I generally favor this approach:
because it tells the user exactly what’s expected of them. A disabled button is visibly different, and tells the user to not bother clicking it.
In some cases, I disable not just that button, but anything else that would cause mischief if clicked.
1 Like
Disabling the button is a good visual indicator for the user.
You might be able to modify the code from here Is there a way to handle double-click as single-click? - #2 to do that automatically for all buttons (assuming that you want that behavior for all buttons).
1 Like
In the past I have used an invisible <div>
floating above the UI, which becomes visible after the button is clicked and hidden after the server call returns. It works well, but the maintenance is difficult (it requires working with HTML and CSS) and it’s not flexible (it disables the whole form).
Now I like to create one self.enable_ui(context)
function that enables or disables all the buttons and components that need to be enabled or disabled, depending on the context. context
can be something like 'all'
, 'none'
, 'left side'
, 'right side'
, 'loading form'
, etc.
Using a string as argument may not be the best practice, perhaps an enum would be better, but I like to keep it simple, and a string works just fine.
The advantage here is that when you add or remove a button or a drop down or any interactive component, you only need to update this single function, rather than going all over your code and maintaining all the places that enable or disable components, and all the state variables.
1 Like
I have a decorator I import and apply to most of my buttons:
from functools import wraps
def disable_sender(fn):
@wraps(fn)
def wrapped(*args,**kwargs):
if kwargs.get('sender'):
kwargs['sender'].enabled=False
result= fn(*args,**kwargs)
if kwargs.get('sender'):
kwargs['sender'].enabled=True
return result
return wrapped
1 Like
Thank you all for the great suggestions!