Tuesday, March 10, 2015

ADF: Bookmark taskflows

Problem description:
In ADF bookmarking a task flow is always a problem. We can only bookmark pages but not regions (embedded task-flow) in those pages. Let say we have a HR page, its shows lots of information and one corner of this shows a task-flow with employees in tabular format

Now if I select employee id = 2 row, inner task-flow will start shwoing details of that employee. Technically we have navigated to new fragment in task-flow. Page would look something like

Now what if we want to bookmark employee detail page directly. Because url has not changed our bookmark will save http://127.0.0.1:7101/ADFBookmarking-ViewController-context-root/faces/pages/MyLandingPage.jspx url only. Next time when we load url again, we will get employee list page first. User needs to again select employee id =2. But our requirement is we want to bookmark a url so that we can directly go to employee detail page, without employee-list page.

This blog is to solve this problem only.

If we closely look there are two problems
1. How to change url when user selects an employee: Everything that needs to be bookmarkeable should have a unique url. So we need to change url on selection of employee row. We can add some parameter in url to modify it. For example ?page=empDetails&empId=2
BUT BUT at any cost url change should not fire a new complete request to server. Otherwise full page refresh will happen, which is not needed. In modern browser we can use
window.history.replaceState to change url of current page without refreshing page completely. We are going to use this approach.

2. If we launch url later with extra parameter (?page=empDetails&empId=2), task-flow should jump to appropriate fragment (employee-details in this case): To solve this problem we will call a bean method from task-flow and read request parameter in it. Based on request parameter we will navigate to appropriate page.


Here is the code snippet to see complete solution

1. MyLandingPage.jspx: This page has some static text and also Employee-flow as a region


2. Employee-Flow: This is a task-flow which is appearing on MyLandingPage.jspx as a region. This task-flow has two pages EmpList.jsff and EmpDetails.jsff. EmpList.jsff shows complete list of employees in tabular format. On selection of employee we select employee record in model and then navigate to EmpDetails.jsff page. EmpDetails.jsff page show currently selected employee record in tabular format.


Now let us modify this application so that we can bookmark EmpDetails page as well.

We will do following modification for that
a. Use JavaScript to change url on employee selection: For this purpose we will modify EmpList.jsff. We will add below javascript



Also change link code to call this javascript.
b. Modify task-flow to accept parameter for request and navigate to appropriate fragment:
We can create a bean and register it in task-flow backingbeanscope as
 We can implement prepareBookmarking method in bean. This method will read request parameter and then put them in pageFlowScope appropriately. Router will use these pageFlowScope parameters to decide, which page to navigate.
Now we can call this method from taskflow by using method call activity. We can make this activity as default activity for taskflow so that task-flow starts from here.

We can use a router activity to decide which page to call based on pageFlowScope parameter.


With that our coding is over.

Now if we see end result
1. Initial page:

2. Click on id=2 and navigate to empDetails page
3. Bookmark complete url [http://127.0.0.1:7101/ADFBookmarking-ViewController-context-root/faces/pages/MyLandingPage.jspx?page=empDetails&empId=2]. Now open url in new tab

RESULT: We have a bookmarkeable url for employee detail page and whenever we load it we will see employee detail page directly.

Thats all. But there is a catch here. What if I drop same task-flow twice on a page? May be I will try to resolve it in my next blog.