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();
    }
    pt_history.save();
}

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);

32 comments:

  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

    ReplyDelete
    Replies
    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.

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

    ReplyDelete
  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

    ReplyDelete
    Replies
    1. Hi William - The details for that topic should be here:
      https://pe0ples0ft.blogspot.com/2016/08/pt-855-flu-drop-down-menu-vs-navigator.html

      You can also use this meta-blog for an index of all branding posts:
      https://pe0ples0ft.blogspot.com/2014/11/peopletools-854-branding-part-1.html#index

      Delete
  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?

    Cheers
    Manoj

    ReplyDelete
    Replies
    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?

      Delete
    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.
      UPdate PS_PTAI_LIST SET PTAI_AGRENDERTYPE = 'VNSP' where PTAI_LIST_ID LIKE 'PTAI_AGTMP%'

      2. Modifiy the PTAI_CREATE_LIST.GBL SavePostChange to redirect to the Fluid AG Component instead of the Classic Component
      At the end,
      REPLACE
      &url = GenerateComponentPortalURL(%Portal, %Node, MenuName.PTAI_MENU, %Market, Component.PTAI_AGSTARTPAGE, Page.PTAI_AGSTARTPAGE, "U") | "&CONTEXTIDPARAMS=TEMPLATE_ID:PTAI_AGTMP&CONTEXTIDPARAMS=PTAI_TEMPLATE_ID:" | &currentList.ListId | "&CONTEXTIDPARAMS=PTAI_OPENSERVICEID:PTAI_AGPROPERTIES&replaceCurrentTopWindow=Y";
      WITH
      &url = GenerateComponentPortalURL(%Portal, %Node, MenuName.NUI_FRAMEWORK, %Market, Component.PT_AGSTARTPAGE_NUI, Page.PT_AGSTARTPAGE_NUI, "U") | "&CONTEXTIDPARAMS=TEMPLATE_ID:PTAI_AGTMP&CONTEXTIDPARAMS=PTAI_TEMPLATE_ID:" | &currentList.ListId | "&CONTEXTIDPARAMS=PTAI_OPENSERVICEID:PTAI_AGPROPERTIES&replaceCurrentTopWindow=Y";

      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
      /psp//EMPLOYEE//c/NUI_FRAMEWORK.PT_AGSTARTPAGE_NUI.GBL?Page=PT_AGSTARTPAGE_NUI&Action=U&Template=True&CONTEXTIDPARAMS=TEMPLATE_ID:PTAI_AGTMP&CONTEXTIDPARAMS=PTAI_TEMPLATE_ID:PTAICREATE&CONTEXTIDPARAMS=PTAI_OPENSERVICEID:PTAI_AGPROPERTIES

      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?

      Delete
    3. If you want to communicate better outside the forum, you can reach out to me through manojonline@gmail.com.

      Cheers
      Manoj

      Delete
    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.

      Delete
  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.

    Thanks,
    Joe

    ReplyDelete
  6. Hi Sasank - Thank you for this blog post. I'm currently looking into adding navigation to the delivered back button in order to give users a way to get back to our custom portal. Do you know if this is possible with your approach?

    I would like to read a url from a query string parameter with "%Request.GetParameter" in the user's session and store that URL as navigation in the back button. Any advice would be greatly appreciated.

    Regards,

    -Adriane

    ReplyDelete
    Replies
    1. Also, I'm attempting to do this using your initial approach, not with the delivered PeopleCode function.

      Delete
    2. @Adriane Williams,

      I am sorry for the delay in responding.

      You are right, your requirement might need you to use a similar approach as option 1. I don't have a working solution for you at this point. You might have to write your own code to do this. You could start writing a similar javscript function that executing and iterates through the pt_history object. Then use console.log message to see how the code is flowing.

      The you could manipulate the history array to introduce your link in the history. This is just a high level approach that I would take if I was working on this requirement.

      That said, I am very interested in this requirement, as I find time I will try to work on this and might even create a separate blog post on this topic.

      Thank you for the comment.

      Delete
    3. Hi Sasank,

      Thanks for getting back to me! I've been able to make some progress since my last comment, and I'm fairly close to a stable solution. Instead of using the AddToHistory function in my custom JS, I'm using the "UpdateHistory" and "UpdateLastHistoryItemUrl" in the delivered PT_HISTORY object. I'm currently working on forcing the back button to display and update on initial load of a PeopleSoft page (the back button only updates when I refresh a page after the initial load), as these functions only work if the pt_history object already has information stored in it. I will probably make modified versions of the two functions I found.

      I'll update this thread as I come up with a more stable solution (hopefully) next week.

      -Adriane

      Delete
    4. Vaijayanthi VyakaranamAugust 22, 2018 at 2:25 PM

      Hi Adriane
      Were you able to come up with a solution to show the backbutton We are actually calling the fluid pages from the native IOS app and the back button is not showing up. We are also not going to the fluid tile page but to the worklist view page of the approvals. Any idea how you accomplished would be really helpful. Thanks

      Vaij

      Delete
  7. Hi Sasank, We have recently cloned a peoplesoft environment and looks like we did a typo somewhere as the Fluid Back button is taking us to the wrong URL 'pspolab-2', instead of 'pscolab-2'. We looked in all the files on middleware and could not find the wrong entry, neither anywhere in the node definitions.
    Any idea where we can see and correct the wrong entry?
    Much appreciate your help.
    Thanks,
    Gyan

    ReplyDelete
    Replies
    1. Gyan - If you already checked the node properties in the portal tab, nothing else comes to mind.

      This may be a good question for Oracle Support.

      If you happen to find out what caused this issue, please do let us know. It will be useful for the community. I am very much interested in learning where this typo is persisting. Thanks!

      Delete
  8. Hi Sasank,

    I need to update delivered back button to redirect to homepage rather than the last page. Any idea, how we can implement it?

    Thanks,
    Punam

    ReplyDelete
    Replies
    1. Thank you Shashank. I resolved my problem by using viewurl function in custom fieldchange.

      Delete
  9. Hi Sasank,

    I am new to Fluid PS, we have a requirement to design custom self service page, when we open the page in small device it is responsive but looks same like laptop one, did you got a chance to create any custom page of ESS from scratch, if so can you let me know how to change header for that page like it shows in Personal details or Benefits summary page. Thank you for all your posts in this blog it is so helpful.

    ReplyDelete
  10. Hi shasank.

    We are not able to see the back button when navigating from find object navigation link. But the same page when viewed directly we are able to see the back button

    ReplyDelete
  11. Are there any updates to this thread? I'm trying to work around the same issue as Manoj described above. Thanks!

    ReplyDelete
    Replies
    1. Unfortunately, I don't have any further updates on that thread.

      Delete
  12. Hi Sasank,

    We have an issue that when we hit back button instead of going to component page with details, it takes to search page of component. Is it expected behavior or do we need to add any parameters to SetTransferAttributes function.

    ReplyDelete
    Replies
    1. Not entirely sure without knowing how this component works. But you may not need to pass any additional parameters in the SetTransferAttributes. You may need to pass any necessary parameters (based on component search behavior) in the Transfer function that is subsequent to the SetTransferAttributes function.

      Delete

  13. I have a search Page N_RNAVM_MAIN
    That will list entries ,
    And then Based on selection it went to the Maintenance Component , Thus when they completed , Using Back Button it went Back to Search Page … Easy

    But I created a notification
    Initially that Notification went directly to the Maintenance Page , Worked. Problem there was no back to search page…..

    SO I am trying to send the Search page … with the ID as a parameter ..
    Thus if I see a parameter I go directly to Maintenance Page and Back Button SHOULD Show search Page But it does not.

    I have tried a couple of things .. But it seems simple… transfer, viewurl etc… what am I missing .. or is it the placement I tred pre and post display

    ReplyDelete

  14. I have a search Page N_RNAVM_MAIN
    That will list entries ,
    And then Based on selection it went to the Maintenance Component , Thus when they completed , Using Back Button it went Back to Search Page … Easy

    But I created a notification
    Initially that Notification went directly to the Maintenance Page , Worked. Problem there was no back to search page…..

    SO I am trying to send the Search page … with the ID as a parameter ..
    Thus if I see a parameter I go directly to Maintenance Page and Back Button SHOULD Show search Page But it does not.

    I have tried a couple of things .. But it seems simple… transfer, viewurl etc… what am I missing .. or is it the placement I tred pre and post display

    ReplyDelete
    Replies
    1. The search page N_RNAVM_MAIN should have a button/link which the users click to go to the Maintenance Component, correct?
      - Use the RowInit event of that field.
      - In the RowInit, check if your ID parameter exists.
      - If it does, then execute the same code that you execute on the FieldChange to navigate to the Maintenance page.

      This should work in theory. If you are still running into issues, try using %Response.RedirectURL(...);

      Delete
  15. I found the issue....
    I was using GenerateComponentContentURL to create the URL and then View it. Thus it was a direct transfer
    I changed GenerateComponentPortalURL ... And the flow works out well Search page directly to Maintenance page , And the Back Button is setup to go back to search component
    And with a small tweak

    Local array of array of string &l_arrStrQueryParas = CreateArray(CreateArray("N_RESTART", "Y"));

    SetTransferAttributes( False, True, "Interface list", "", &l_arrStrQueryParas);

    Since the Back Button takes me back with all the parameters (Initial ID that was used to transfer to detail) , I added a flag it to reset and ignore the send to maintenance

    ReplyDelete