Based on Oracle Application Express (formerly HTML DB) version 1.5
After completing this How-To, you should be able to understand:
The sections include:
A tree is a hierarchical navigation or display mechanism. It is based upon a table that contains a hierarchical relationship. The tree is created as a query that specifies the relationship by identifying the ID and parent ID columns in a table or view. The tree definition also contains the starting point. A tree is displayed in a region on a page. Once a tree is created, it can be referenced by multiple regions.
This How-To will use an Employee table and the hierarchical Manager/Employee relationship within the table. The report created will display the hierarchy within the organization and allow for navigation to edit employees.
To use a tree purely for navigation, you need a navigation table containing the data to display along with a page number for each topic that requires navigation. To display the tree on every page of your application you create the tree on page 0 of your application. Alternately, you could create the tree on a menu page that can be easily navigated to by users.
Oracle HTML DB contains tree navigation. To view tree navigation for an application, navigate to the Page Definition. Select Page Reports in the left navigation page and then select Tree View. This displays all the objects on the current page in a hierarchical format with links to allow creation and editing. The image below is that report for page 200 in the Sample Application.
Image 1 - Tree View of Page

The discussion walks you through the process of creating a tree, modifying the defaulted tree, and then including that tree in another page. Also discussed are advanced tree concepts, such as displaying additional links. Next are the specific instructions to follow to create the objects used in this How-To in your own environment so that you can replicate this lesson. Lastly is the DDL for the objects used in this How-To.
For this exercise, the demonstration application Sample Application will be used as the base application. This application is included when a new workspace is provisioned.
When a tree is created, it can either be included on a new page or added to an existing page. The instructions below walk through the process of creating a new tree on a new page. For more information on creating trees, see chapter 8, "Building Application Components" in the Oracle HTML DB User's Guide.
To create the initial tree:
Image 2 - Identify Page Attributes
Image 3 - Identify Tabs
Image 4 - Identify Tree Attributes
Image 5 - Identify Tree Template

Image 6 - Identify Tree Start

Any or all of the buttons can be included within the region that will reference your tree. These buttons are part of the resulting region, not the Tree Definition. If the tree is referenced by another region, the buttons selected here will not be automatically created.
Image 7 - Identify Expand/Collapse
Image 8 - Identify Table/View Owner
Image 9 - Identify Table/View Name
Image 10 - Identify Query
Image 11 - Identify Link
The image below shows the tree being restricted to the people in the SALES department and being ordered by EMP_LAST_NAME.
Image 12 - Identify Where and Order by
Image 13 - Tree Confirmation

Image 14 - Running Defaulted Tree
Once a tree has been created, it can be modified. The sections below detail the changes that can be made to the tree definition versus those that need to be made to the page displaying the tree.
Looking at Image 14 above, the display could be more attractive. Specifically, the buttons need to be modified to look like the application. The buttons are part of the page that was created. They were defaulted because of the selection to include them in Step 10 above, Identify Expand/Collapse. These buttons were created as HTML buttons and placed at the top of the region.
To modify the tree definition:
Image 15 - Page Definition

Image 16 - Button Definition

Tree navigation is not always self-evident to users. To solve this, include a hint to explain how to navigate to the employee details from the tree. To create a hint:
Image 17 - Region Definition
You can change the Start Tree from the Page Definition. The Tree Definition points to the item that stores the starting point of the tree. The item itself exists on the page created for the tree and the value of the item is calculated on that page. As mentioned earlier, if the Start Tree was an Item with a Popup LOV, the resulting item will be displayed and will contain a locally defined LOV. If the Start Tree was based on a Query, the resulting item will be hidden and the Item Source would be set to SQL Query with the provided query as the Source value. In this example, the Start Tree was a Static Value. The resulting item, P901_TREE_ROOT, is hidden and the Item Source is statically assigned to 1.
Image 18 - Start Tree Item Source
With the changes described above, the page will now look like the Image below.
Image 19 - After Page Changes
Looking at Image 19 above, only the last name is displayed. More details can be displayed by editing the Tree Definition. The Tree Definition can be edited from Trees under the Application tab or by selecting the T to the left of the region referencing the tree from the Page Definition.
To modify a Tree Definition:
The first four items in the select list are used to display the tree. The fifth and sixth items, a1 and a2, are used for substitution strings. You can use these items to select additional columns from the table, or to select static values that they can be referenced in the tree template. They would be referenced as #a1# and #a2#, respectively.
Change the third item to include the Employee's First Name.
Image 20 - Tree Definition
The Tree Definition contains a number of additional sections including Before and After Tree HTML, Static Tree Node Templates, Dynamic Expand and Contract Tree Node Templates, Node Text Templates, and Hyper Text Link Templates. This information defaults from your tree template selection. You can change the look of a tree by changing these attributes.
With the change to the displayed item, the page will now look like the Image below. In this display, Expand All has been used to display all the data.
Image 21 - After Tree Change
A tree can be referenced by more than one region. It is supported, but not suggested because when you reference a tree more than once, the page that contains the Start Tree controls the display on all pages (recall that the Start Tree item is specified in the Tree Definition). Also, when you contract the tree on one page, it contracts on all. This can be very confusing to users. To display a tree on multiple pages, it is recommended, as discussed in the Introduction, to create it on Page 0. If there are specific pages where it should not display, these can be coded into a Conditional Display or a Security Scheme that would then be applied to the region on Page 0.
If you create a tree and then remove the region or page that references it, the tree will still exist. You can reference this tree in a new region but you must be careful with the Start Tree. If the page has been deleted then the Start Tree item will have also been deleted. A new item must be created and then added to the Tree Definition.
To reference an existing tree from a new page:
Image 22 - Region Details for Referenced Tree
Image 23 - Source for Referenced Tree
If the page were run now, the tree would be blank. This is because the Start Tree item will have no value. To make the tree display on this page, a Before Header Computation needs to be created that will set the Start Tree item, P901_TREE_ROOT, to 1. With that in place, the tree would now display.
This section will be added at a later date.
To create the HT_EMP table and associated objects:
This procedure creates a table with insert and update triggers, a sequence to populate the primary key and will insert several rows into the table.
The following is the code to replicate the table used in the example. If this table already exists from another How-To, you must delete both the HT_EMP table and the HT_EMP_SEQ sequence.
create table ht_emp (
emp_id number primary key,
emp_first_name varchar2(30) not null,
emp_middle_initial varchar2(1),
emp_last_name varchar2(45) not null,
emp_part_or_full_time varchar2(1) not null check (emp_part_or_full_time in ('P','F')),
emp_salary number,
emp_dept varchar2(20) check (emp_dept in ('SALES','ACCOUNTING','MANUFACTURING','HR')),
emp_hiredate date,
emp_manager number references ht_emp,
emp_special_info varchar2(2000),
emp_telecommute varchar2(1) check (emp_telecommute in ('Y')),
rec_create_date date not null,
rec_update_date date)
/
insert into ht_emp
(emp_id, emp_first_name, emp_middle_initial, emp_last_name, emp_part_or_full_time,
emp_salary, emp_dept, emp_hiredate, emp_manager, emp_special_info, emp_telecommute,
rec_create_date)
values
(1,'Larry','R','CEO','F',
100000,'SALES',sysdate,null,'cell phone number is xxx.xxx.xxxx
home phone is yyy.yyy.yyyy',null,
sysdate)
/
commit
/
insert into ht_emp
(emp_id, emp_first_name, emp_middle_initial, emp_last_name, emp_part_or_full_time,
emp_salary, emp_dept, emp_hiredate, emp_manager, emp_special_info, emp_telecommute,
rec_create_date)
values
(2,'Joe',null,'Manager','F',
80000,'SALES',sysdate,1,'cell phone number is 123.456.7777',null,
sysdate)
/
commit
/
insert into ht_emp
(emp_id, emp_first_name, emp_middle_initial, emp_last_name, emp_part_or_full_time,
emp_salary, emp_dept, emp_hiredate, emp_manager, emp_special_info, emp_telecommute,
rec_create_date)
values
(3,'Jane','I','Boss','F',
80000,'SALES',sysdate,1,null,null,
sysdate)
/
commit
/
insert into ht_emp
(emp_id, emp_first_name, emp_middle_initial, emp_last_name, emp_part_or_full_time,
emp_salary, emp_dept, emp_hiredate, emp_manager, emp_special_info, emp_telecommute,
rec_create_date)
values
(4,'Scott','N','Tiger','F',
70000,'SALES',sysdate,1,'Tech Guru','Y',
sysdate)
/
commit
/
insert into ht_emp
(emp_id, emp_first_name, emp_middle_initial, emp_last_name, emp_part_or_full_time,
emp_salary, emp_dept, emp_hiredate, emp_manager, emp_special_info, emp_telecommute,
rec_create_date)
values
(5,'Sally',null,'Sales','F',
60000,'SALES',sysdate,2,null,null,
sysdate)
/
commit
/
insert into ht_emp
(emp_id, emp_first_name, emp_middle_initial, emp_last_name, emp_part_or_full_time,
emp_salary, emp_dept, emp_hiredate, emp_manager, emp_special_info, emp_telecommute,
rec_create_date)
values
(6,'Joe','M','Software','F',
60000,'SALES',sysdate,2,null,null,
sysdate)
/
commit
/
insert into ht_emp
(emp_id, emp_first_name, emp_middle_initial, emp_last_name, emp_part_or_full_time,
emp_salary, emp_dept, emp_hiredate, emp_manager, emp_special_info, emp_telecommute,
rec_create_date)
values
(7,'Peter','O','Phone','P',
40000,'SALES',sysdate,6,'Assistant to Joe',null,
sysdate)
/
commit
/
insert into ht_emp
(emp_id, emp_first_name, emp_middle_initial, emp_last_name, emp_part_or_full_time,
emp_salary, emp_dept, emp_hiredate, emp_manager, emp_special_info, emp_telecommute,
rec_create_date)
values
(8,'Anita','A','Hardware','F',
80000,'SALES',sysdate,1,null,'Y',
sysdate)
/
commit
/
insert into ht_emp
(emp_id, emp_first_name, emp_middle_initial, emp_last_name, emp_part_or_full_time,
emp_salary, emp_dept, emp_hiredate, emp_manager, emp_special_info, emp_telecommute,
rec_create_date)
values
(9,'Mike','Q','Resource','F',
70000,'HR',sysdate,1,'Head of HR',null,
sysdate)
/
commit
/
create sequence ht_emp_seq
start with 20
/
create or replace trigger bi_ht_emp
before insert on ht_emp
for each row
begin
select ht_emp_seq.nextval
into :new.emp_id
from dual;
:new.rec_create_date := sysdate;
end;
/
create or replace trigger bu_ht_emp
before update on ht_emp
for each row
begin
:new.rec_update_date := sysdate;
end;
/