Maintaining AJAX Page State

Maintaining AJAX Page State

  

I have a page where the user clicks a link and a new widget is displayed via AJAX. That new content has links in it to a NEW web page.

If the user clicks the browser BACK button from that new page, the previous page no longer displays the widget from which the user clicked to see the new page.

What are best practices for maintaining the users' view when adding content via AJAX? Outside Outsystems, I would use a #HASH variable in the URL and then check that value and load content accordingly. I do not know how to implement such functionality in OS though.


Hi PJ,

The browser's back button is evil. You can never hope to code in such a way it always works. That said, in an OutSystems application it is typical to use Session Variables to store values of filters etc. to maintain state between pages.

It's not evil, it's just a button AND not only can I hope to make it work, I actually HAVE made it work many times in many web apps. It's a very common web development concern when building AJAX capabilities into an app. But I digress.

Your suggestion of using Session Variables won't work because the page isn't reloaded from the server.

The "internet" solution, and the solution I've implemented countless times before Outsystems is to use the # hash of the location, but OutSystems doesn't give us access to it, nor do they let us set it.

See all these references for more information on how everyone else in the world solves this problem:

https://stackoverflow.com/questions/9009858/preserve-page-state-for-revisiting-using-browser-back-button

https://www.safaribooksonline.com/library/view/javascript-cookbook/9781449390211/ch08s10.html

Hello PJ

The only reason to the session variables to not work is if the browser, on a back button action, is fetching the page from its cache.

So, you just have to guarantee that it doesn't do that. :)

Take a look here, as they implement something similar:

https://success.outsystems.com/Documentation/Development_FAQs/How_to_save_and_restore_the_active_tab_on_SilkUIFramework

Like Kilian said, it's a matter for session variables.

Cheers

P.S. It seems that this is the reason why the rest of the World is getting behind...?? :D

Solution

Thanks for the help guys, I kept at it and made it work perfectly! Here's how:

1) Add an Extended Property to the element that, when clicked, runs the Server Action via Ajax Submit that you want to repeat when the user clicks BACK. This will let our JavaScript described in further steps know which element on the page was clicked (See the NOTE: below about capitalization).

You can use whatever names and variables you choose, just be sure the value is unique so you can find it with a jQuery selector (see below).



2) In the Screen Action behind the Ajax Submit, add a RunJavaScript action from the HTTPRequestHandler Extension like this, you can learn more about how to do this here:

https://success.outsystems.com/Documentation/10/Extensibility_and_Integration/JavaScript/Extend_Your_Web_Application_Using_JavaScript/Define_and_Run_JavaScript_Code#RunJavaScript_Action_Example

SyntaxEditor Code Snippet

"location.hash='Payment" + PaymentId + "';"



This will modify the location.hash to be something like this when the user clicks the link:


I'm working with payments here, so that's why you see Payment, but all you need to do is keep the naming conventions the same throughout this exercise. PaymentId is a variable local to the PaymentView WebBlock containing the Ajax Submitting link.




3) Add javascript like below to the web page where the Ajax Submitting widget is to re-click it when the user clicks BACK.

NOTE: You'll notice in step 1, my extended property was "Payment" and in the JavaScript, I reference the attribute as "payment" with a lower case p, because OutSystems forces the extended properties to lowercase. Be aware of that. 



TROUBLESHOOTING:

Right-click on the element in your browser and choose > Inspect element.

Make sure OutSystems adds the extended property and verify the capitalization. Here you can see the property for my link:

Be sure this matches the JavaScript on your web page, go to the network tab and look for the JS file for your page, mine is called "UnappliedPayments" so that's the .js file I need to examine:


If you are unfamiliar with the $('[attribute=value]') selector in jQuery I am using to find the element to "click", you can learn more about that here:

https://api.jquery.com/attribute-equals-selector/


I hope this helps someone else!


Solution

Using a session variable is so much simpler, but hey, whatever works for you. :)

What works for me is what actually works and using a session variable would not work. Using a session variable also is not simpler -- a mathematical fact.

Hello PJ,

For the sake of the Forum, I did a small application to demonstrate how to do this "the OutSystems way".

https://jauch.outsystemscloud.com/BackButtonExample/

Here is what I did, for each page I don't want to be retrieved from cache on browsers back button (or from history):

1. Add a call to the AddHeader action (from HTTPRequestHandler).
2. Set property as follow:

That's it.
The rest is a matter of using session variables for the information you want to keep between requests, or save it in database if you need to keep a lot of information (best practices).

You can find information about the possible values for cache-control in a net search, but the link that I posted earlier have a couple links with more information. 

This was tested on Chrome, Firefox, Edge and Opera.

Cheers.

P.S. Not saying your method does not work, PJ, or that you never shouldn't use it (may exist some situations, I don't know), but the "OutSystems" approach (that you can found as recommendation on many places over the net, on a fast search), is much simpler than yours. So, in most situations (at least), it is a better approach.

Oh, and it works :)

Frankly, Eduardo, I think you do not understand my solution. If you did, you'd know it is simpler and better than your solution for many reasons. Deleting my posts and threatening me won't make you right.

Hi PJ,

As moderator I don't believe that was Eduardo that deleted your post. Nevertheless this topic discussion is old and you can't find related forums threads like this one in particular or another one like this.

@Eduardo, thank you for pin point the solution used on SilkUI doc:

https://success.outsystems.com/Documentation/Development_FAQs/How_to_save_and_restore_the_active_tab_on_SilkUIFramework

@PJ M please consider to use the nocache approach or keep up with your solution, I'm glad that you were able to overpass the issue.


Best regards,

Daniel Martins

I did consider the NO-CACHE option and disabling the back button. Using no-cache and server variables to handle all this has been a solution for years and an AJAX approach using the browser # is better for all the reasons AJAX is better. The other two are pre-AJAX solutions to this problem. Using the # is modern, snappy, AJAX compatible. It eliminates server variables that take up memory for every user who uses it. The page reloads faster providing a better user experience. The state of the page is encapsulated in the #hash which allows it to be bookmarked and shared via link. It takes fewer steps to implement. The changes required are isolated to content on the page itself making it easier to maintain.

It's just an all around better solution. In my mind, there's really no question about that. I encourage you and the community to evaluate the differences and have a discussion.