Turning a Tree into a Navigation Aid
I haven’t had much use for Trees in APEX in the past. However, when trying to decide on a navigational aid in our new development project I’ve turned to Trees as a possible solution. We’ve taken the decision to use one of the built in themes and customise it for our purpose. Once we had decided on the theme it was quickly decided that the breadcrumb region took up too much space and wasn’t really fit for purpose so wouldn’t be used. We needed a solution so that users could quickly navigate to different areas of the application and also see how they got to the page they’re on and where they are within the application. The Tree style seemed like the ideal solution but a basic Tree would not do what we wanted, so some thought was required.
Trees in APEX are used to navigate to a specific page in the application passing relevant information to items in this page. A classic example is a company’s organisational chart. The top of the Tree is the Managing Director, expanding the tree shows his direct reports e.g. department directors. Expanding further shows team leaders and further still shows the members of each team. Clicking on any of the links in the team could pass the employee id to a page in the application which then provides more details on that person, such as a photo, how long they’ve been with the company and telephone number etc.
To be a navigational aid we needed each link in the tree to navigate to a different page, for the current page to be highlighted in bold and for some pages to simply be listed in the tree but not linked. Some pages are part of a process so navigating straight to step two for example, would mean that any information from step one would be missing.
First I created a simple table to store details of the page:
CREATE TABLE "APEX_PAGES" ( "IDENTIFIER" NUMBER(10,0) NOT NULL ENABLE, "PAGE_NO" NUMBER(10,0) NOT NULL ENABLE, "PARENT_PAGE_NO" NUMBER(10,0), "NAME" VARCHAR2(100) NOT NULL ENABLE, "NAVIGATION" VARCHAR2(1) NOT NULL ENABLE, CONSTRAINT "APEX_PAGES_PK" PRIMARY KEY ("IDENTIFIER") ENABLE ) / SQL> desc apex_pages Name Null? Type ------------------------------- -------- ---- IDENTIFIER NOT NULL NUMBER(10) PAGE_NO NOT NULL NUMBER(10) PARENT_PAGE_NO NUMBER(10) NAME NOT NULL VARCHAR2(100) NAVIGATION NOT NULL VARCHAR2(1)
This table will hold the page number and name, the parent page number and “navigation” will determine whether or not you can navigate directly to that page.
Then insert some values into this table, for example:
Now create a new tree from the Shared Components page. To create a new tree you have to create it on a new page, however you can then use that tree on a different page and delete this page. Accept the defaults on the first 2 pages of the tree wizard, then give the tree a name of Navigation and select ‘Static Value’. Accept the default on the next page and set the static value to be 1. The table/view should be your APEX_PAGES table, the ID is PAGE_NO, the Parent ID is PARENT_PAGE_NO, Leaf Node Text is NAME and Link Option should be ‘Existing Application Item’ (this sets the values in the tree to be links). Select any page as the link page and any item as the link item, we’ll later modify the tree so that these are no longer used. Don’t specify a where clause or order by, click finish to create your tree and page.
Running this page now should display a tree showing Home Page, Employee Details and Edit Employee. However, clicking any of these will take you to the page you selected in the wizard.
If your application doesn’t already have one, create a page zero. On this page create a new region, select Tree, give the region a name e.g Navigation Tree and select the Navigation tree you have just created. You will also need to create a new hidden item on page zero called P0_TREE_ROOT with a static value of 1. You can now delete the extra page that was created when you used the Tree wizard to create the tree. From Page Zero, click the Tree link in the Regions section. This will display a page showing the Tree Query. Change this query to be:
select PAGE_NO id, PARENT_PAGE_NO pid, NAME name, 'f?p=&APP_ID.:'||page_no||':&SESSION.' link, null a1, null a2 from #OWNER#.APEX_PAGES WHERE page_no <> :APP_PAGE_ID AND nvl(navigation,'N') = 'Y' UNION select PAGE_NO id, PARENT_PAGE_NO pid, '<b>'||NAME||'</b>' name, 'f?p=&APP_ID.:'||page_no||':&SESSION.' link, null a1, null a2 from #OWNER#.APEX_PAGES WHERE page_no = :APP_PAGE_ID AND nvl(navigation,'N') = 'Y' UNION select PAGE_NO id, PARENT_PAGE_NO pid, '<div fontfamily="Arial">'||NAME||'</div>' name, null link, null a1, null a2 from #OWNER#.APEX_PAGES WHERE page_no <> :APP_PAGE_ID AND nvl(navigation,'N') = 'N' UNION select PAGE_NO id, PARENT_PAGE_NO pid, '<div fontfamily="Arial"><b>'||NAME||'</b></div>' name, null link, null a1, null a2 from #OWNER#.APEX_PAGES WHERE page_no = :APP_PAGE_ID AND nvl(navigation,'N') = 'N'
On the same page also change the Application Item to be P0_TREE_ROOT. The select statement above sets the link for each item in the tree to be to the page in the select statement where you can navigate directly to that page and ensures there isn’t a link for those that you can’t. It also ensures that regardless of whether or not you can navigate directly to the page the page you are on is displayed in bold.
Now if you run your application, on every page there will be a tree that allows you to navigate to pages 1, 2 or 3. You can add to this by including it in a sidebar and having a conditional display which enables users to hide and show the sidebar.