I was testing P11 web block events and other stuff when I noticed a behaviour that is possibly done on purpose, but was still a bit unexpected one.

I created a web block with:

  • 3 radio buttons
  • 3 input variables attached to radio button "Value" properties
  • one local variable to hold the selected value ("Variable" property for all buttons)
  • 3 placeholders to give labels to buttons
  • 2 events to test the interaction between block and parent screen
    • ResetSelection event is not used anywhere and it's "Is Mandatory" property is set to "No"
    • ValueChanged event is triggered from each radio button's OnChange event (input parameter is set to screen local variable "selection" on all these events)

Web block's Preparation action outputs web block local variable contents to UI:

When I refresh this web block from parent screen, I'd expect: 

  1. "selection" local variable value being reset to default
  2. radio button selection being cleared

...as neither of these are not explicitly set from any of web block's input variables or by application code.

Why? This tutorial video says web blocks have their own scope, which I'd figured would re-set all block variables to defaults when ajax refresh on web block is called.

This does not happen even though web block's preparation action is called and block is re-rendered. If web block local variable has been set at any point of parent screen's lifecycle, it will not return to default even if block is refreshed. Only parent screen reload resets the web block as well.

I can do the extra application logic in Preparation to reset the web block to any values I wish (or parametrize this to happen/not happen), but I'm wondering why this happens.

Is this a bug or a feature? 

I cannot comment on whether its a bug or intended feature.

However, I can confirm I experience the same behaviour.  The preparation still runs, but the defaults are not applied, the values remain the same as they were.

I believe this is because the values in the webblock scope are stored in the viewstate that is maintained for the page.

Another behaviour is that if you have a webblock with a form to edit an entity and you change the identifier passed into the webblock then refresh, the aggregate will run correctly with the new identifier, but the form record will not update.  You have to manually assign the form record to the entity on the aggregate.

I am comfortable with the behaviour now, but it can be a little unintuitive.

Interestingly, if you hide the webblock then reshow it using an "If" widget, the defaults are applied.  I assume this is because the webblock's viewstate is removed from the pages viewstate, then reinitialised when the webblock is shown again.

But if you hide and show it using a Container's Display=True/False the webblock is still there just hidden with "display:none" so its viewstate is maintained.

I hope this helps!

Stuart Harris wrote:

I believe this is because the values in the webblock scope are stored in the viewstate that is maintained for the page.

Another behaviour is that if you have a webblock with a form to edit an entity and you change the identifier passed into the webblock then refresh, the aggregate will run correctly with the new identifier, but the form record will not update.  You have to manually assign the form record to the entity on the aggregate.

Thank you for your quick response! This would most definitely make sense, but IMHO it's still a bit evil. Especially if web block form data is not reflecting what is stored in viewstate.

To highlight / further test the behaviour:

I wrapped my web block radio buttons with form and changed the "selection" local variable to be a "record of text" (also tested with default value other than datatype default by creating a structure). This created a situation where web block's local variable default value(s) are restored on web block refresh, but UI is not reflecting the missing selection (still showing the previous selection).

Immediate idea was to signal the parent screen by triggering my web block ValueChange event from web block's Preparation, but events cannot be triggered from Preparation...

I'm glad that I started fiddling with this one.

Hello,


I can confirm what Stuart Harris said:

"Whenever you refresh a web block its preparation still runs, but the local variables are not reset, the values remain the same as they were".

In your case, having the variables reset will be your expected behavior, however lots of times, the use case is precisely the opposite: The user started fiddling with the contents of the web block and you don't want to mess with what the use did. If we didn't store the local variables of the web block that will be very hard to achieve.


The workaround for your use case (you want the reset the variables) is to re-assign the variables in the preparation like you suggested.


Hope this helps,

Rui Eugénio

Solution

Hi all,

This is a feature and it is related to the submit method to the screen action, not to the Ajax Refresh itself.

Local variables (including input parameters) and Form Records are never automatically reset on a submit, be it a Submit or an Ajax Submit. 

This is valid even if the data is inside Web Blocks. Refresh a Web Block, be it because the screen action ended on an END node and it was a Submit method (everything will be rebuilt) or you did an Ajax Refresh on the Web Block inside a Screen Action called with Ajax Submit method, all local variables (and Form record) will keep their state.

This happens even if you make the Web Block "disappear" from the screen changing its visibility through changing the condition of an IF around it.

So, if you need, on a submit (Submit or Ajax Submit) to reset a local variable (including input parameters and Form's record), you need to do it explicitly. 

You saw this on the online training when you had to use an "Empty" local variable to clear a Form's record (through an Assignment) on a "Save & New" action.

Hope this helps make things more understandable.

Cheers.

Solution

Stuart Harris wrote:

Interestingly, if you hide the webblock then reshow it using an "If" widget, the defaults are applied.  I assume this is because the webblock's viewstate is removed from the pages viewstate, then reinitialised when the webblock is shown again.

Hi Stuart,

This is not entirely true.

There are situations where this "reset" happens, but once the web block is shown for the first time in the screen, this "reset" on hiding the web block is a bug and was already reported to the OutSystems team, as it goes against the expected behaviour.

Cheers.

Lots of good info here, thanks for replies!