I have a checkbox to which I’ve bound a property included
from a data model to the Checked State Logic
. For the same checkbox, I’ve implemented some actions for the On Change Event
.
When clicking on the checkbox, the Checked State Logic
is correctly processed. Also, the property included
changes its value correctly.
However, if the property included
is changed by some other event, the checkbox visualize this change correctly, but the On Change Event
is not processed!
I would say this is a bug. How do you see this?
Regards,
Hi @Klaas_Klever
No, this is not a bug.
The On Change Event
fires only when a user toggles the checkbox in the UI.
Yes. You are describing my observation in other words. I feel it would be “more correct” if it does not depend on the cause why the checkbox is changing (user interaction, or data binding). But I can imagine, that there are technical restriction not to do so …
Regards,
yes, you are right, there is a reason why it works this way
let me describe the pattern, I’ve prepared a simple diagram to explain how it works now
as you can see you can change a component value (state) in 3 ways:
- using UI to modify the value (blue block)
- using Codeless block “Set Property (value/chacked/…)” to the component (red block)
- data-binding with a Data Model (yellow block)
and if there is a data binding (2-way data-binding) the new value goes to its DataModel
and all of them are independent
But, if we start running the “On Change event” when data-binding value is changed or you set the value directly using “Set Property block” we will have a loop and to break the loop you will be forced to compare the prev value with the new value, and you won’t be able to know what value (from data-binding/ui/codeless-block) is correct and should be displayed in the UI
Does it make sense?
Thank you for this detailed explanation. I understand the reason why there would be loops. This is caused by coupling the handler to an UI event only. To achieve what I’m looking for, one might do this:
There, the handler is trigger by the central action “update the component value”.
Regards,
I see, but adding this will break other app because all customers relay that the logic runs only when a user interacts with UI.
for instance: there could be two inputs with their own onChange logic and they are both linked to the same data binding and each of them in its own handler modify another component/data/etc only when the particular input is changed
I have a pattern for your issue
create a custom function “OnInputChange” and use it in the event handler and in all places where you change the value in a data model
will it work for you?
You hit the point, Vladimir . I thought about this pattern, but then I started our discussion first.
The issue for me with custom functions is, that they are global. I wish to have functions with page scope as well. Over time, I already collected a lot of global functions which are working in the context of a specific page only. Think of the case to save data to the database in the “On Checkbox Change” case we are discussing above. Such a reuse function only makes sense for my page, because some specific assumptions on page data are involved.
The flat list of global functions is very hard to manage. I have 44 of them! There is no “where-used” feature, or something which would help refactoring.
Maybe you can think about offering functions with page scope. At least the list of global custom functions should be much better manageable.
Regards,
I definitely agree with you, when there are lots of functions it’s hard to manage they
we’ve got in our plans the following improvements:
- add an ability to find all logic (page/handler/function) where a function is used with the ability to open a specific handler/function with the function
- before deleting a function show an alert if the function is used in other handlers/functions
- add a combobox to show functions for a particular page
- add a search input to filter the list of functions
- add an ability to specify labels for a function in order to highlight a scope/namespace of a function purpose
However, at this moment the UIBuilder team is focused on the CustomComponents feature, so all these improvements will come a little bit later
I can propose to you an approach I saw in a couple of our customer’s apps, they give names with some prefix, for instance:
- “p_order_validate_new_order”
- “p_order_create_new_order”
- “p_orders_find_new_orders”
- “p_orders_filter_archive_orders”
- “c_check_login”
- “c_logout”
where “p_” is a shortcut for “page”
where “c_” is a shortcut for “common”
so, all the functions are sorted by name and you can find a particular function much faster