Friday, April 1, 2016

Fluid UI - Custom Development - Back Button History

I recently came across a requirement that made me aware of a new and interesting design consideration for Fluid development. When we design and develop Classic pages, we never had to worry about a 'Back' button and how it behaves in the context of user navigation.

Fluid 'Back' Button:

Let us say that we made a customization to the 'Personal Details' page so that on page load, we redirect/transfer the users to a custom component/page and then once done with custom activity we redirect/transfer them back to the 'Personal Details' page. Now if the user clicks on the 'Back' button on the 'Personal Details' page, we expect them to go back to the Fluid Home Page. But since we had an additional custom navigation, the user navigation 'History' alters the behavior of the 'Back' button. Sometimes, it may be desirable but what if it is not how we wanted the navigation to flow? How do we control the 'Back' button behavior and user navigation 'History'?

In my example, the 'Personal Details' page redirects to 'Custom Activity' page. Once we click 'Continue' (custom activity) the user gets redirected to the 'Personal Details' page.

There is a very simple solution to this problem and it involves just invoking a delivered function. But before I provide that solution, I wanted to share what I learned in the process. It is interesting to know how it works behind the scenes. This is just for informational purposes and it is not recommended unless you have a really complex requirement!

My Initial Approach:

Since, I could tell that there is some javascript that is tracking the user navigation, my first thought was to write some custom javascript to manipulate the 'History'.

Basically, I realized that we had to either prevent or clean up behind this AddToHistory function in the page javascript.

After digging into delivered javascripts, I found the clearHistory() function in the delivered PT_COMMON HTML object.

If we use the delivered clearHistory function, then it would clear the entire 'History' except the last navigation. So, I created a custom function (cskClearHistory) based on the delivered code. My custom function removes everything from the 'pt_history' object except for the first item (which should be the Home Page). I am sure there could be a better way to manipulate the 'History' and make the javascript more efficient but this seems to work for a proof of concept!

Javascript for Reference:

function cskClearHistory() //can be called by app component
    var pt_history = getHistoryObject();
    if (!pt_history ||  pt_history.size() <=1) return;

    // Pop everything out except first item (Home Page)   
    while(pt_history.size() > 1) {
       var lastRec = pt_history.pop();

I just invoked this javascript on my custom page activate peoplecode event as follows:

Now, when I navigate the same route (Employee Self Service (Home Page) > Personal Details --redirect--> Custom Activity --continue--> Personal Details, the 'Back' button points back to the 'Home Page' as expected/desired.

After writing this javascript and getting this to work as expected, I realized that this is still not a very efficient way of managing the user navigation 'History'. Sure, the javascript manipulation of the 'History' might be useful for some more complex scenarios (which was the purpose of my demonstration above) but definitely not a great idea for simple page transfers. Eventually, after digging into some of the existing Fluid pages, I found that there is a delivered function called SetTransferAttributes that helps us with these sort of transfers.

PeopleBooks Reference

Recommended Approach:

I got rid off all the custom javascript that I injected on page activate peoplecode. I just added this one line of code to my 'Continue' button before the transfer to set the transfer attributes appropriately.

PeopleCode: SetTransferAttributes(False, False);


  1. Thanks Sasank for the explanation . This is very helpful . I tried this myself but on click of the button it wasn't taking me back to the homepage, there was no action at all. Is there any thing I may have missed apart from adding the JavaScript on page activate

    1. The custom JS function and the page activate peoplecode is all that is needed (if you are trying out my custom approach to manipulate the history).

      You may want to add a console.log message in the javascript to see if it is actually getting executed. Once you know the JS is executing, you can look into it further. Otherwise, this should be pretty straight forward.

  2. Just an update - I saw this issue on PUM 18 and not in PUM 20. Looks like this has been addressed.

  3. Sasank
    I noticed you had some code to automaticly open the navigation in 1 click instead of 2. But Cant find it..
    p.s. I noticed it is doing that now randomly .. But cant reason out why

    1. Hi William - The details for that topic should be here:

      You can also use this meta-blog for an index of all branding posts:

  4. Sasank, Great Post.
    Have you worked with the Fluid Activity Guides, which automatically props up an 'Exit' button.

    Similar to 'Back' button. the AG Exit also seems to remember the Nav Stack history. In situations where we move between one instance of AG to another instance (using redirection), 'Exit' button gives us an issue. Instead of going back to our dashboard, it goes to the previous instance of the AG.

    Do you know of a way of controlling the history for the AG exit too?


    1. Hi Manoj - I am assuming you already tried the SetTransferAttributes function and it did not work?

      Is this a delivered Fluid Activity Guide which I can look at in a PUM Image?

    2. Sorry for the late response, for some reason, I don't get notified.

      It is indeed delivered Activity guide and from our research it is using the 'AddToHistory' javascript function to build the stack as well, but SetTransferAttributes doesn't seem to work.

      It can be replicatedwith the Activity Guide built for creating Activity Guide (i was the primary member of the team which enhanced the AG framework in 8.54, not selling myself, its the truth!!! XD).
      But some customizations need to be done

      Steps to Replicate:
      1. Update the existing template to a newer Rendering type to make it easier.

      2. Modifiy the PTAI_CREATE_LIST.GBL SavePostChange to redirect to the Fluid AG Component instead of the Classic Component
      At the end,

      2. Create a New AG Template (Main Menu > PeopleTools > Portal > Activiy Guides > Maintain Templates)
      When you create a new Activity Guide, a new instance is created for the template PTAI_AGTMP with the context parameter (PTAI_TEMPLATE_ID=PTAICREATE).
      But when you save it for the first time, a new instance of the AG will be created with PTAI_TEMPLATE_ID = . When the user saves, he is directed from the 'Create' instance to the 'Named' instance, but to the user it is seemless

      We can make use of this 'internal redirection' to simulate my problem.

      3. Render the Activity guide in Fluid

      You should see the instance in Fluid Mode, with a Exit button on the LHS.

      4. Now, Enter basic information about the Template Properties and Save.
      You should be redirected to the new instance (from the 'Create' instance)

      5. Click Exit.
      User expects to go back to the 'Dashboard'' (or from where he landed)
      But, it takes you back to the 'Create' instance instead, since there was an internal redirection

      Hope this makes sense?

    3. If you want to communicate better outside the forum, you can reach out to me through


    4. I see the problem. It may be something to do with how the Activity Guide pages are rendered.

      Not able to pinpoint the issue. Will Let you know if I find anything useful.

  5. Hi Sasank,

    Thanks for sharing. The post has been very useful. I ended up using the custom clear history method you shared, since I needed just the Homepage link along in my scenario. It was very helpful of you in sharing your learning.


    1. @Joe - Glad to hear that. Thank you! :)