I have an event listener attached to the window that runs when the target click is not inside a certain element. This event listener calls a client action X that sets some client variables.
I am on the same page using the 'JSON Pretty Format Reactive' component (https://www.outsystems.com/forge/component-overview/10136/json-pretty-format-reactive) and it seems like the fact that I am setting client variables in my action X is messing with it (the JSON component uses event listeners attached to the document and a lot of JS). I find that the JSON component loads and then disappears - very strange. And on closer inspection, if I disable the part of my action X that sets the client variables then this does not happen.
I tried looking at propagation and capturing etc and nothing worked except either removing my event listener which fires my action X or disabling inside of action X where I assign the client variables.
I looked online and couldn't find why this would happen when using local storage; which leads me to think that it is OutSystems that is doing something special when setting client variables and that that is causing this strange issue... And when I debug I can see that OutSystems is running JS and only once that JS is finished does the JSON component disappear - so I am fairly sure it's the OutSystems code...
Has anyone ever seen anything like this and/or have a suggestion?
Hi Nicholas,
I believe I have a solution for your problem. I've changed a little bit how the JSONPrettyFormat widget works and now the event listener associated with the window is triggered even when the user clicks on the JSON. The JSON does not disappear and can be collapsed as expected.
You can find the new version of the JSONPrettyFormat included in the OML attached in here. Please test it thoroughly with more complex JSON objects (including multiple elements within elements within elements) to make sure it works as expected in all cases. I've changed quite a lot the OutSystems part of the widget and also the Javascript file associated with it. I did not have the time to test it thoroughly. Let me know if you find any issues.
What are the main changes? I've split the conversion of the JSON into clickable HTML into two phases. In phase 1, the JSON is converted into static HTML. In phase 2, event listeners are associated with the HTML to make it clickable.
Phase 1 is executed in the OnReady and OnParametersChanged events of the JSONPrettyFormat widget. The static HTMLgenerated in this phase is stored into a local variable of the widget (the variable JsonAsHtml).
Phase 2 is executed in the OnRender event of the widget. It uses the local variable as input. Finally, the static HTML is updated whenever the user clicks on the widget to make sure that the collapsed state of part of the JSON is not lost. The end result is that the local variable has always the static HTML with the collapsed state of (parts of) the JSON presented on the screen up to date.
When the event listener associated with the window is triggered, the JSON shown on the page would disappear as a result of the client variable being changed (this is the behaviour you noticed). Now it does not disappear because the OnRender event of the JSONPrettyFormat runs immediately after the JSON disappears. The OnRender just puts the JSON back on the page and makes it clickable. Given that this happens quite fast, the user does not see the JSON disappearing and appearing again.
See if it works good enough for your case.
Hi Pedro
Thanks so much for this. Can you explain why the JSON disappears in the first place? Is it because changing client variables causes the screen to re-render and the JSON component does not hold the value because it uses JS rather than actual variables in which case the rendered content is lost each time the screen re-renders?
Thank you so much for the time you spent on this. I tried your oml and it is working perfectly for my use case which is just 1 level of JSON.
I have marked your answer as the solution.
Hi Nicholas, could you upload an application or module that exemplifies the problem? It makes it easier to pinpoint the cause of the problem and eventually come up with a solution.
Kim regards.
See attached the sample oml. I put all the required components into the file to make it easier.
Please let me know what you find. As I said, if you disable the assign that sets the client variable then it all works fine... strange.
However, I have also noted that when you try and collapse the JSON on the component the screen refreshes which is also strange and I don't think should be happening... so I wonder if the component could also be doing something wrong - but this could be a separate issue.
Thanks in advance.
Thanks for the oml. I’ll take a look at it as soon as I find some time. It might take a couple of days. I hope you are not in a hurry.
Kind regards
Many thanks for looking into it. I am on a deadline, but that is my problem to handle. I'm happy to wait a few days to hopefully get a solution.
Good luck! I'll share any new findings as I also continue to look into it.
I looked into it a bit today. No solution yet :( I was wondering if you want the event handler that you attach to the window to also be triggered when the user clicks on the json widget. That might make it easier to find a solution. Could you explain to mee what you are trying to achieve by adding the event handler to the window? What is the use case? Knowing the use case maybe we can come up with an alternative solution.
I also looked into what you mentioned about collapsing the json which is causing a page reload. This is an odd one. Never saw it happen before with this component. I also noticed that if the component is initialized to start collapsed that in the browser you see a continuous loop of page reloads. This is really odd. My hypothesis for now is that there is a strange interaction between the newest version of OutSystems UI and this component. I have to dig dipper to assess whether this hypothesis holds.
I’ll keep you posted if I run into new insights or an eventual solution.
Best regards.
I have one possible solution to the problem, assuming that clicking on the JSON widget should not trigger the event listener (for the 'click' event) associated with the window object. If this is acceptable for you, then check the file attached in here.
The idea is to wrap the JSONPrettyFormat into a container with width set to auto. The container is not visible but it wraps the JSONPrettyFormat widget. On this container, we set an event listener for the 'click' event which stops the propagation of the event. The click event does not reach any parent of the wrapper. The effect is that clicking anywhere outside the JSONPrettyFormat widget changes the value of the client variable. Clicking inside the container, it is possible to collapse/uncollapse the JSON and the value of the client variable remains unchanged.
Let me know if this is good enough for your use case.
I'll dig further to see if it I can also make it work when clicking within the JSONPrettyFormat widget should also trigger the event listener associated with the window object.
Thanks so much for the time you've spent on this. I will look at your solution and try and implement it to see if it resolves it. I'll let you know once done.
To answer the previous comment you made, the event listener on the window is part of a custom base theme that hides a particular component if it is open and the user clicks anywhere else on the screen besides that component - so it applies to all apps which means making a particular case in that code just for this single app is not going to be a good option.
So I am hoping your above solution works - at least as an interim solution.
The fix is working. Although not ideal, it is better than it was so thank you.
However, when I try the oml you sent, it seems like the issue isn't happening at all - whether I click on the placeholder or anywhere on the screen the JSON component stays there and open? So it seems like it's working 100% on your version - but I don't see any big differences...? Are you aware that yours seems to be working perfectly?
The JSON remains always visible but the event listener associated with the window object is not triggered when the user clicks on the json. It is only triggered when you click outside the json. In the oml I sent you see that the value of the client variable that is presented on the screen only changes when you click outside the json. Not when you click on the json.
Yes I saw that, but I noticed that even when you click on the screen away from on the JSON and the client variable does change, the JSON still stays there - which is what mine is not doing which is the issue.
So it seems like the original issue is somehow not an issue in yours?
I’m glad to hear this works good enough for you.
With respect to why the json disappears in the first place I didn’t manage yet to find out why. I’d have to spend more time on it and go through every step that takes place within the JavaScript code of OutSystems.
If you happen to find out why, let me know. I’m curious.
Best regards!