Undocumented change in set_enabled(...)
behavior
#4217
-
QuestionFollowing a brief hiatus on a project using NiceGUI I started updating code from using Consider the following example: from nicegui import ui
def handle_click(state, value):
if not state:
select.set_enabled(False)
select.set_value(value)
if not state:
select.set_enabled(True)
select = ui.select(options=[1, 2, 3], value=1, on_change=lambda v: ui.notify(v))
ui.button('Select Enabled', on_click=lambda: handle_click(True, 2))
ui.button('Select Disabled', on_click=lambda: handle_click(False, 3))
ui.run() When run using I couldn't identify anything in the documentation to pinpoint when this may have occurred or if it was an intended change. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 6 replies
-
Hi @thetableman, welcome back! 😀 I'm struggling to understand the exact problem. Can you, please, describe it step-by-step:
Can we reproduce the problem with the following simplified code snippet? select = ui.select(options=[1, 2, 3], value=1, on_change=ui.notify)
ui.button('Increment', on_click=lambda: select.set_value(select.value + 1))
ui.button('Decrement', on_click=lambda: select.set_value(select.value - 1))
ui.button('Enable', on_click=lambda: select.set_enabled(True))
ui.button('Disable', on_click=lambda: select.set_enabled(False)) Any maybe you can narrow down the NiceGUI version where the behavior changes. Last but not least: Do you think the new behavior is worse than the old one? Or do you primarily ask out of curiosity? |
Beta Was this translation helpful? Give feedback.
-
The rationale here is that there may be a need to change the value of an element without triggering the element's Consider the following example, changing the date triggers its related callback but also that of the select. from datetime import datetime
from nicegui import ui
def select_change():
ui_date.set_value(f'2025-01-{ui_select.value}')
common_change()
ui.notify('select triggered')
def date_change():
ui_select.set_value(datetime.strptime(ui_date.value, '%Y-%m-%d').day)
common_change()
ui.notify('date triggered')
def common_change():
"""Some process that calls data based on a date change"""
ui_date = ui.date(value='2025-01-15', on_change=date_change)
ui_select = ui.select(options=list(range(1,32)), value=15, on_change=select_change)
ui.run() Previously, to avoid this issue, I could simply apply Additionally, if you think about a I don't disagree with the need to allow an element to trigger its callback even when disabled (or invisible) as other users have noted, however, an ability to temporarily disable the callback is also useful. Perhaps a |
Beta Was this translation helpful? Give feedback.
Ok, I see. The "click" event is blocked by disabling the element, but the "change" event isn't. But I think the "change" event needs to always trigger, no matter how the value changes.
In your scenario you're disabling elements to avoid database updates being called multiple times. I don't fully understand how this works, but I don't think introducing yet another parameter like
disable_on_change
is the best way forward. Instead you can simply check the enabled state in your handler:Or you introduce a dedicated flag in your user code instead of using the
enabled
attribute.