Sunday, July 31, 2011

How To Handle Web Browser Buttons in ADF/WebCenter Applications

ADF/WebCenter technology typically is used to implement transactional logic and transfer desktop applications functionality into web browser. Based on this, many questions can be asked, for example - what will happen if user press browser Refresh button during pending transaction or what will happen if browser will be closed at all during transaction. We are not asking same questions for pure web type applications, but ADF/WebCenter is different case.

There is no 100% working option to control web browser buttons and to disable them from inside of our application, this would break browser security and allow hackers to lock users into specific web site. We can try to clear browser cache, etc. - but this is not working with ADF/WebCenter applications. However, there is option to inform user proactively about browser related even, that can potentially break application functionality, for example - browser will be closed, page will be refreshed by Refresh button, etc. We can catch these events and warn user from ADF/WebCenter application. I will describe in this blog post, how to implement such warning.

Download sample application for this post - EnterprisePortalApp_v5.zip.

Sample application is based on WebCenter 11g navigation model, it loads ADF task flows and external resources:


When authentication is succeeded, default home page is loaded. Browser Back button becomes active, because it indicates user can go back to login page. We would like to avoid this, so we can inform user with warning implemented by sample application:


This is standard browser warning dialog and is supported by all browsers. Two options are given - to stay or to continue browser navigation. If user will choose to stay on current page, will be able to continue his work. If "Leave this Page" option will be selected - we can't guarantee correct application behavior.

This warning works well when navigating between pages. However, it behaves a bit different with ADF dynamic regions or when WebCenter navigation model is loading ADF task flows, external resources into internal frame. Let's load external resource by clicking on WebCenter menu:


Make sure you have noticed that "Reuters Global News" menu item was selected. Now press browser Back button - page content remains the same, but menu item selection moves and makes previously selected menu item as current:


This is logical, because we were not using separate page to display "Reuters Global News", but it was rendered inside frame - sample application didn't catch any change in navigation. However, if we press browser Back button one more time, it would try to navigate away from home page and we would receive navigation warning:


Press - "Stay on this Page" and open another menu item - "Jobs". Try to close browser, same navigation warning dialog will appear and ask user to confirm his action. This is good, because user is warned before closing page without doing actual logout:


Navigation warning doesn't affect internal navigation between ADF regions, because this navigation doesn't change current page - press Edit button:


Another ADF region will be opened, without giving any navigation warning:


But if user will press "Administration" link, this will invoke navigation to new physical page, user will be warned:


"Logout" link also navigates to another physical page, however it will not give navigation warning - I will explain how to handle this with JavaScript:


Let's do one more test and press browser Refresh button, while "Departments" menu item is opened. Press "Leave this Page" when navigation dialog will be opened:


ADF/WebCenter application will reload, but will fail to render correct data - it will show "Fetching Data..." message constantly. Also menu item selection becomes wrong. If user would choose to "Stay on this Page", it would work well - it's user responsibility to choose action. Now user would need to press previously selected menu item "Departments", but all pending data will be lost:


It works to control navigation in this way with all browsers, or at least with those I have tested - IE, Firefox, Google Chrome. IE test:


Firefox test:


I will explain now, how to enable such navigation warning dialog. We need to invoke JavaScript function, during application home page load. In ADF/WebCenter applications we can invoke onload JavaScript function, simply by calling it from main af:form binding method:


I'm loading JavaScript from navigation-renderer.jspx page, because ADF/WebCenter application is using this page to load page content into frame. You are free to do the same from your home page.

Form binding method, programmatically loads window.onbeforeunload JavaScript function. This function allows us to control browser navigation, and is loaded only once - on home page initialization. If we want to skip navigation check for some page, we should leave function body empty (if check for logoutAction == 0):


If we need to skip navigation check for specific link, we can add af:clientListener method and set JavaScript variable flag:


Flag value will be set through JavaScript and later evaluated from window.onbeforeunload method (see above):


7 comments:

Gieofkkskfofd said...

Great post although I would suggest one tweak.

You're setting a handler for window.onunload but this would replace any existing handler that might have been put there by some other component or ADF itself.

I would suggest to first get a handle on the existing window.onunload and then invoke that function in your onunload handler. That why you ensure you're still calling any existing onload function

Andrej Baranovskij said...

Hi Wilfred,

Yes, good suggestion. Thanks.

Andrejus

ಆಶ್ವಿನ್ ಆಲ್ಮೆಡ (Ashwin Almeida) said...

Hi Andrejus,

We are developing an ADF application, but are noticing strange behaviour when browser back button is clicked. Some times it loads the previous page, and some times it loads the "Error 403--Forbidden". Not sure why this happens could you suggest some approach to avoid this. Even we are fine if we can provide a user with generic page when this occurs.

Thanks
Ashwin

Andrej Baranovskij said...

Did you tried approach documented in this post?

Andrejus

Anonymous said...

Hi Andrejus,

I have a scenario where a session should end as soon as the user clicks the browser back button and is navigated to the login page.

At present when I click the browser bck button in Mozilla and login again it gives the below error

OracleJSP error: java.io.FileNotFoundException:

Set the init-param debug_mode to "true" to see the complete exception message.

Could you please help me with the same.

Thanks in advance,
Karthik

Unknown said...

Hi Andrejus,

I have a scenario where I 'm Using More than one Session Scope for each Fragments. if i want one page to Another Page Like(edit or add Pages)
close the Browser or click of browser Back Button session has been maintained so kindly provide gud Solution

Thanks
Suresh Venkatachalam

amit said...

Hi Andrejus,

It seems the sample - EnterprisePortalApp_v5.zip is not available.

Thanks,
Amit