# Building a Demo Project Application Using Oracle Application Express 5.0

## Overview

#### Purpose

This tutorial for Oracle® Application Express release 5.0 (Application Express) demonstrates how to build a working application for managing projects and tasks using some of the latest features of Application Express 5.0. This exercise assumes no prior knowledge of Application Express.

#### Time to Complete

Approximately 2.5 to 3 hours

#### Introduction

Application Express is a rapid web application development tool for the Oracle Database. Using only a web browser and limited programming experience, you can develop and deploy professional applications that are both fast and secure. Application Express is a fully supported, no cost option of the Oracle Database.

In this tutorial, you use Application Express to build a fully functioning database application to maintain team members and their tasks. Tasks may be assigned to milestones and are associated with a specific project.

#### Prerequisites

To run this tutorial, you need:

- Access to an Oracle Application Express 5.0.1 environment, such as an account on apex.oracle.com, or a local installation of Oracle Database 11g or later.
- An Application Express workspace and a development user.
- The files.zip file extracted into your working directory.

#### Videos

A video has been recorded for each topic covered below. To access the videos go to Application Express YouTube Playlists, then select the Building an APEX Demo Application playlist folder.
To watch the overview video, see this video.

## Creating the Initial Application

To create your initial application, you must load a script which defines the required database objects, populate the tables with sample data, and create the initial pages of your application with the Create Application Wizard.
To watch a video of the steps in this section, see this video.

1. Sign in to your Application Express development environment.

2. Application Express includes the SQL Workshop for application developers to maintain database objects, from the browser. This feature is particularly important when developing in hosted environments, or where the application developer does not have access to the underlying database, and can not use tools such as SQL Developer or SQL*Plus to manage the database objects.

   Click SQL Workshop and select SQL Scripts.

   Click Upload.

   Click Choose File, open the working directory that you extracted from `files.zip`, open the `files` folder, and select the Demo_Project_Tables.sql script.

   Click Upload.

3. Click the Run to the right of the script you uploaded.

   Click Run In Background.

4. Click the View Results icon for the script you just ran.

   At the bottom of the results page you should see "32" Statements Processed, "32" Successful, and "0" With Errors.

5. Use the Object Browser within SQL Workshop to review all of the database objects, such as the tables and packages you created, available in the underlying Oracle database schema which is associated with the Application Express workspace you logged into.

   At the top of the page, select SQL Workshop and then select Object Browser. In Object Browser, select the DEMO_TEAM_MEMBERS table, then click on the Data tab.

6. Now that you have created the underlying tables, you are ready to create a desktop application. You will be adding reports for those tables where you need a list of available records, and forms for tables to enable data to be inserted, updated, and deleted.
   Generally, when developing an application you will not know all of the pages required at the beginning, so will only generate a select number of pages initially, and then use the Create Page wizard to add additional pages as required. However, for this exercise you will generate most of the pages required for the application up front.

   Click Application Builder and select Create.

   Click Desktop.
   Note: Desktop is selected by default.

   In Name, enter `Demo Projects` and click Next.

   The Create Application Wizard creates a Home page automatically.

7. Next add pages for the following tables:
   1. DEMO_TEAM_MEMBER
   2. DEMO_PROJECTS
   3. DEMO_MILESTONES
   4. DEMO_TASKS
   5. DEMO_PROJECT_COMMENTS

   Any number of pages can be added into the initial application by simply clicking Add Page, and then selecting the appropriate details. Once the page(s) have been added, certain attributes, such as names, labels, and sequence, can be updated by clicking on the edit icon for that page.
   Individual pages can also be removed from the list by selecting the X to the right of each page.

   1. Add the DEMO_TEAM_MEMBERS report and form pages.
      Click Add Page.

      Add a report and form:

      - Select Page Type - Report and Form
      - Table Name - DEMO_TEAM_MEMBERS
      - Form Page Mode - Modal Dialog

      Click Add Page.

   2. Add the DEMO_PROJECTS report and form pages.
      Click Add Page.

      Add a report and form:

      - Select Page Type - Report and Form
      - Table Name - DEMO_PROJECTS
      - Form Page Mode - Modal Dialog

      Click Add Page.

   3. Add the DEMO_MILESTONES form page.
      Click Add Page.

      Add a form:

      - Select Page Type - Form
      - Table Name - DEMO_MILESTONES

      Click Add Page.

   4. Add the DEMO_TASKS form page.
      Click Add Page.

      Add a form:

      - Select Page Type - Form
      - Table Name - DEMO_TASKS

      Click Add Page.

   5. Add the DEMO_PROJECT_COMMENTS form page.
      Click Add Page.

      Add a form:

      - Select Page Type - Form
      - Table Name - DEMO_PROJECT_COMMENTS

      Click Add Page.

   Verify that your screen matches the next illustration. Click Create Application.

   Warning: You must create these pages in the order shown to ensure that they correspond with instructions later in this tutorial.
   If your screen does not look the same as the illustration, use the X icon to the right of each page to delete problem pages and restart Step 7. Do not delete the Home page.

   Click Create Application on the confirmation page.

8. Not all page types, such as calendars, can be created using the Create Application wizard. Therefore, to add a calendar you need to utilize the Create Page wizard

   Click Create Page.

   For Select Page Type, select Calendar.

   Verify the default selection is Calendar and click Next.

   The Page and Region Attributes page appears.

   For Page Name, enter `Calendar`. For Breadcrumb, select Breadcrumb. Click Next.
   Note: The Region Name and Breadcrumb - Entry Name both change to the value entered into the Page Name

   For Navigation Preference, select Create a new navigation menu entry and click Next.

   For Source Type, select SQL Query and copy-paste the following SQL statement:

   `select p.id
   , p.name
   , '[Project] ' || ' Project Lead: ' || (select full_name from demo_team_members tm where p.project_lead = tm.id) ||
   ' Description: ' || p.description ||
   ' {Note: Projects will only show if there are Tasks with no Milestone}' description
   , demo_projects_pkg.project_color
   ( p_project_id => p.id
   , p_completed_date => p.completed_date
   ) css_class
   , p.completed_date start_date
   , p.completed_date end_date
   from demo_projects p
   where p.completed_date is not null
   and p.id = nvl(:P9_PROJECT_ID, p.id)
   and exists (select 'Tasks with no Milestone'
   from demo_tasks t
   where p.id = t.project_id
   and t.milestone_id is null
   )
   UNION
   select m.id
   , m.name
   , '[Milestone] ' || m.description description
   , demo_projects_pkg.milestone_color
   ( p_milestone_id => m.id
   , p_due_date => m.due_date
   ) css_class
   , m.due_date start_date
   , m.due_date end_date
   from demo_milestones m
   where m.project_id = nvl(:P9_PROJECT_ID, m.project_id)
   and m.id = nvl(:P9_MILESTONE_ID, m.id)
   UNION
   select t.id
   , t.name
   , '[Task] ' || ' Assignee: ' || (select full_name from demo_team_members tm where t.assignee = tm.id) ||
   ' Complete? ' || decode(t.is_complete_yn, 'Y', 'Yes', 'No') ||
   ' Description: ' || t.description description
   , demo_projects_pkg.task_color
   ( p_task_id => t.id
   , p_completed_date => p.completed_date
   , p_due_date => null
   ) css_class
   , t.start_date start_date
   , t.end_date end_date
   from demo_tasks t
   , demo_projects p
   where p.id = t.project_id
   and t.project_id = nvl(:P9_PROJECT_ID, t.project_id)
   and t.milestone_id is null
   UNION
   select t.id
   , t.name
   , '[Task] ' || ' Assignee: ' || (select full_name from demo_team_members tm where t.assignee = tm.id) ||
   ' Complete? ' || decode(t.is_complete_yn, 'Y', 'Yes', 'No') ||
   ' Description: ' || t.description description
   , demo_projects_pkg.task_color
   ( p_task_id => t.id
   , p_completed_date => null
   , p_due_date => m.due_date
   ) css_class
   , t.start_date start_date
   , t.end_date end_date
   from demo_tasks t
   , demo_milestones m
   where m.id = t.milestone_id
   and t.project_id = nvl(:P9_PROJECT_ID, t.project_id)
   and t.milestone_id = nvl(:P9_MILESTONE_ID, t.milestone_id)
   `

   Note: This is a complex SQL query that returns records from different tables unioned together. Generally, you do not need to develop SQL this complex. Most developers would simply base the calendar region on the DEMO_TASKS table.
   Each record is optionally restricted in the where conditions by page items (`:P9_PROJECT_ID` and `:P9_MILESTONE_ID`). You add these items to Page 9 in a later section. The query also utilizes functions to return a CSS Class for the color and icon for each record.
   This complex SQL is included in this lab to show the power of SQL queries and what is possible.

   Click Next.

   For Display Column, select NAME. For End Date Column, select END_DATE. Click Next.

   On the confirmation page, click Create.

In this topic you used wizards to generate multiple pages. However, this is just the start of your application development, and the generated pages still need more work for your application to be ready for production.

## Updating the Home Page

In this topic, you create a dashboard by adding new components to the Home page of the application.
To watch a video of the steps in this section, see this video.

Note: If you have not completed the previous topic, import the Demo Projects App Export - Topic 2.sql file into your workspace to continue working from this topic forward. You can find the export file in the `/files` subdirectory where you unzipped the original file.

1. Within Application Express you can utilize plug-ins, which are custom components used to extend native functionality. The most coomon plug-ins are custom item types, and custom regions.
   The Application Express Development Team provides a number of plug-ins that you can readily utilize within your own application, by either importing it into your application, or subscribing to another application which has the plug-in installed. To access the Development Team plug-ins you can install the Packaged Apps, especially applications such as Sample Charts, or go to http://apex.oracle.com/plugins.
   There are also over 150 plug-ins developed by the Application Express community which you can utilize. To review the community developed plug-ins go to http://apex.world > Plug-Ins or http://www.apex-plugin.com/

   Install the Sample Charts application to import the badge list and D3 chart plug-ins:

   Click Packaged Apps and select Apps Gallery.

   Click the Sample Charts application.

   Click Install Application and then click Next.

   Click Install Application.

2. Add the required plug-ins, from the Sample Charts application, into your application:

   Click Application Builder. On the Application Builder home page, click the Demo Projects application.

   Click Shared Components.

   Click Plug-ins.

   Click Create.

   Select As a Copy of an Existing Plug-in and click Next.

   Select Sample Charts and click Next.

   At the bottom of the page, click Deselect All.

   Locate the Copy? column:

   - Badge List - select Copy and Subscribe.
   - D3 Bar Chart - select Copy and Subscribe.

   Click Copy Plug-ins.

3. Add components to Page 1, starting with the badge list component.

   On the toolbar, click Edit Page 1.
   Note: If you are not on Page 1, enter `1` into the Page Selector on the toolbar, and click Go.

   Right-click Content Body and select Create Region.

   The right-hand pane is called the Property Editor. Use the Property Editor to edit attributes for the currently selected component(s).

   In the Property Editor:

   - Title - enter `Summary`
   - Type - Badge List [Plug-in]
   - SQL Query - copy-paste the following: `select 'Open Projects' label
     , count(*) value
     , 'f?p='||:APP_ID||':4:'||:APP_SESSION||':::::' link
     from demo_projects
     where status != 'Completed'
     UNION ALL
     select 'Upcoming Milestones' label
     , count(*) value
     , 'f?p='||:APP_ID||':4:'||:APP_SESSION||':::::' link
     from demo_milestones
     where due_date > sysdate
     UNION ALL
     select 'Open Tasks' label
     , count(*) value
     , 'f?p='||:APP_ID||':4:'||:APP_SESSION||':::::' link
     from demo_tasks
     where is_complete_yn = 'N'
     `

   Note: This query has three sub-queries, seperated by UNION ALL, that will be displayed as three separate badges within the region.

   In the Property Editor, click the Template Options button (Use Template Defaults, Scroll - Default) and input the following:

   - General - enable Use Template Defaults (enabled by default) and Remove Body Padding
   - Header - Hidden but accessible

   Click OK.
   Note: The Template Options button display changes in the Property Editor to reflect its current settings.

   Locate the Rendering Tree in the left-hand pane. Under the Summary region, click Attributes.

   In the Property Editor, click the Link Builder button (No Link Defined) and input the following:

   - Type - URL
   - URL - enter `&LINK.`
     Warning: When you enter `&LINK.` ensure you include the period.

   Click OK.
   Note: the Link Builder button display changes in the Property Editor to reflect its current settings.

   For Label Column, select LABEL.
   For Value Column, select VALUE.

   Click Save.

4. Page Designer includes the Grid Layout in the middle pane. The Grid Layout is a representation of how the components will be positioned on the page. Existing regions, items, and buttons can be moved relative to other components by simply clicking on the component and dragging it to a new location. For example, items can be placed next to each other by dragging the second item to the end of the first item, and dropping it in the yellow box that appears when you hover in the desired location. New components can quickly be added to an existing page by dragging the component from the Gallery up to the desired position within the Grid Layout.

   Use Page Designer's drag-and-drop functionality to quickly add a D3 Bar Chart from the Gallery to the Grid Layout.

   In the Gallery (below the Grid Layout), click the Regions tab, and scroll down until you see D3 Bar Chart [Plug-In].

   Click and hold D3 Bar Chart [Plug-In] and drag it up into the Grid Layout at the bottom of the Summary region within Content Body. It should appear as a square tile before you finally drop it into place.
   Tip: To undo a previous action, press Ctrl+Z in Windows or click the Undo button on the top-right toolbar.

   In the Property Editor:

   - Title - enter `Tasks by Project`
   - SQL Query - copy-paste the following: `select p.id
     , p.name as label
     , (select count('x') from demo_tasks t
     where p.id = t.project_id
     and nvl(t.is_complete_yn,'N') = 'Y'
     ) value
     , 'Completed Tasks' series
     , p.created
     from demo_projects p
     UNION ALL
     select p.id
     , p.name as label
     , (select count('x') from demo_tasks t
     where p.id = t.project_id
     and nvl(t.is_complete_yn,'N') = 'N'
     ) value
     , 'Incompleted Tasks' series
     , p.created
     from demo_projects p
     order by 5`

   Note: The D3 Bar chart will use two series: Completed Tasks and Incomplete Tasks. The query uses two select statements (with different where conditions), joined using UNION ALL, to count the tasks for each project.

   Locate the Rendering Tree. Under the Tasks by Project region, click Attributes.

   In the Property Editor:

   - X Values Column - LABEL
   - Y Values Column - VALUE
   - Display - Horizontal, Stacked
   - Multiple Series - enable
   - Series Column - SERIES
   - Y-Axis Title - enter `Tasks`
   - Tooltips - enable Show series name and Show Y value
   - Legend - Below chart
   - Show Grid Lines - enable Y-Axis
   - Maximum Height - enter `240`
   - Color Scheme - Theme Default

   Click Save.

5. Create a Classic Report. This allows each Team Member to see their outstanding tasks.

   In the Gallery (directly below the Grid Layout), scroll down until you see Classic Report.

   Click and hold Classic Report drag it up into the Grid Layout, to just below the Tasks by Project (D3 Bar Chart) region, then release the mouse.

   In the Property Editor:

   - Title - enter `My Outstanding Tasks`
   - SQL Query - copy-paste the following: `select p.name project
     , t.name task
     , t.end_date
     from demo_tasks t
     , demo_projects p
     , demo_milestones m
     , demo_team_members tm
     where p.id = t.project_id
     and m.id = t.milestone_id (+)
     and tm.id = t.assignee and nvl(t.is_complete_yn, 'N') = 'N'
     and upper(tm.username) = upper(:APP_USER)
     order by t.end_date`

   Note: The where condition of `username = :APP_USER` restricts the records to those assigned to the person running the application.

   In the Property Editor, click the Template Options button. For General, enable Use Template Defaults (enabled by default) and Remove Body Padding, and for Body Height select 480px.

   Click OK.

   Locate the Rendering Tree. Under the My Outstanding Tasks region, click Attributes.

   Click the Template Options button. Enable Use Template Defaults (enabled by default) and Stretch Report. For Report Border, select No Outer Borders.
   Click OK.
   Note: There are significant differences between the Region template options, set in the previous step, and the Attribute template options set above. The region settings are used to modify how the region is displayed, whereas, attribute settings (where available) modify how the contents of the region are displayed.

   Click Save.

6. The last region to add to the Home page is a stylized classic report. It needs specific column names that are used by the Timeline region template.

   In the Rendering Tree, right-click My Outstanding Tasks region and select Duplicate.

   In the Property Editor, change the Title to `Recent Projects`, and replace the SQL Query with the following:

   `select p.id project_id
   , t.id
   , null event_modifiers
   , null event_attributes
   , null user_color
   , dbms_lob.getlength('PHOTO_BLOB') user_avatar
   , t.full_name user_name
   , nvl(p.completed_date, p.updated) event_date
   , (case p.status
   when 'Assigned' then 'is-removed'
   when 'In-Progress' then 'is-updated'
   when 'Completed' then 'is-new'
   end) event_status
   , p.status event_type
   , (case p.status
   when 'Assigned' then 'fa fa-clock-o'
   when 'In-Progress' then 'fa fa-refresh'
   when 'Completed' then 'fa fa-check'
   end) event_icon
   , p.name event_title
   , p.description event_desc
   from demo_projects p
   , demo_team_members t
   where p.project_lead = t.id
   order by p.updated desc`

   Note: The columns in this query use specific column names that are required in order to match those specified in the Timeline template.

   For Grid - Start New Row select No.
   Note: Once you select "No," the position of the Recent Projects region moves next to the My Outstanding Tasks region in the Grid Layout.

   Locate the Rendering Tree. Under the Recent Projects region, click Attributes and input the following:

   - Number of Rows - enter `5`
   - Template - Timeline
   - Pagination - Type - No Pagination (Show All Rows)

   Click the Template Options button. For Style select Compact and click OK.

7. Update the columns for this region to display an image and change the format mask of selected items.

   In the Rendering Tree, under the Recent Projects region, expand the Columns folder.

   Click USER_AVATAR and select the following in the Property Editor:

   - Type: Display Image
   - Table Name - DEMO_TEAM_MEMBERS
   - Blob Column - PHOTO_BLOB
   - Primary Key Column 1 - ID
   - Mime Type Column - PHOTO_MIMETYPE
   - Filename Column - PHOTO_FILENAME
   - Last Updated Column - PHOTO_LAST_UPDATED

   Click the EVENT_DATE column, for Format Mask enter `SINCE`, and click Save.

Run the application to see how the Home page looks now.
Note: You will need to enter your username and password credentials that you use to log into the Application Builder.

## Defining Shared Components

In this topic, you define shared components required for the application including an authentication scheme and list of values. You also update the Navigation Menu.
Gernerally, when developing an application you will not know all of the common components, such as list of values and menu entries, at the beginning of development. Instead, you will regualrly go into Shared Components to update these components as necessary. However, for this exercise you will create all of the components at this time.
To watch a video of the steps in this section, see this video.

Note: If you have not completed the previous topic, you can import the Demo Projects App Export - Topic 3.sql file into your workspace, and continue working from this topic forward. You can find the export file in the `/files` subdirectory where you unzipped the original file.

1. Shared Components are components that are used application wide, rather than being defined on a specific page. Some of the Shared Components, such as Authentication Schemes, Lists, Navigation Menu, and Themes, can only be defined as Shared Components, while others, such as List of Values, can be implemented directly on individual pages.
   Rather than replicating the same code on multiple pages, it is good programming practice to define the code once in a shared component where possible, and then reference that component on the different pages. Defining components, such as List of Values or Application Process, allows developers to maintain that code in a single component.

   On the toolbar, click the Shared Components button, which is located in the top-right and contains a triangle, circle, and square in its icon.

2. Application security is very important in the majority of applications, except for "Public" applications. You must ensure users enter valid credentials, generally username and password (Authentication), and that once logged in that each user has appropriate rights within the application (Authorization).
   Application Express provides a number of built-in Authentication Schemes, including Single Sign-On, LDAP, HTTP Header Based (for use with OAM / IDM), and Application Express Users. For this exercise you will be using the Application Express users, as this is default configuration.
   Application Express also makes it easy to define Authentication Schemes, that can be utilized to define access to almost every component within Application Express including pages, regions, items, report columns, buttons, and processes. If you review the Packaged Apps you will see that the "productivty" applications include the ability to switch on authentication with access defined for Administrators, Contributors, and Readers. In these applications, only users defined as Adinistrators can access any of the administration pages. Further, Readers can not access the buttons for creating or updating any records in the application.

   Create an authorization scheme to ensure only people entered as Team Members can log into the application.

   Click Authorization Schemes.

   Click Create.

   Select From Scratch (default) and click Next.

   In the Property Editor:

   - Name - enter `Team Members`
   - Schema Type - Exists SQL Query
   - SQL Query - copy-paste the following:

     `select 1
     from demo_team_members
     where upper(username) = upper(:APP_USER)`

   - Identify error message displayed when scheme violated - enter `You must be a team member to use this application.`

   Click Create Authorization Scheme.
   Note: `:APP_USER` is a built-in application item that returns the username of the currently logged in user.

3. When a database exception occurs an `ORA-xxxx` error message displays. This error message is not very informative for end users. You can replace this message with a more meaningful message by adding the error handling function.
   In the fir included in the package you loaded earlier.

   To add the error handling function and make the application utilize the authorization scheme, edit the Application Definition and Security Attributes.

   Click the Shared Components button on the toolbar. Under Application Logic, click Application Definition Attributes.

   Click the Error Handling tab. For Error Handling Function, enter `demo_projects_pkg.error_handling`.

   Click the Security tab.

   Click the Authorization tab. For Authorization scheme, select Team Members.

   Click Apply Changes.

4. When you have an item based on a Foreign Key column, you want the users to see and enter the name, rather than the underlying identifier that is stored in the table. To achieve this you need to define a select or pop-up List of Values (or LOV) - both display the descriptive field you specify but input the associated identifier into the item.

   Rather than defining LOVs multiple times on different pages, you add them once under Shared Components.
   Note: You do not define a LOV for milestones because each time the Milestone Id is input it is tied to the Project identifier on that specific page.

   Click the Shared Components button on the toolbar.

   Click Create.

   Select From Scratch and click Next.

   For Name enter `PROJECTS`, for Type select Dynamic, and click Next.

   For Query, copy-paste the following SQL:

   `select name d, id r
   from demo_projects
   order by 1`

   Click Create List of Values.

5. Click Create to create a second LOV.

   Select From Scratch (default) and click Next.

   For Name, enter `TEAM_MEMBERS`, for Type select Dynamic, and click Next.

   For Query, copy-paste the following SQL:

   `select full_name d, id r
   from demo_team_members
   order by 1`

   Click Create List of Values.

6. Click Create to create the final LOV.

   Select From Scratch (default) and click Next.

   For Name, enter `PROJECT_STATUS`, for Type select Static, and click Next.

   Enter the following list entries for Display Value and Return Value:

   `Assigned / Assigned
   In-Progress / In-Progress
   Completed / Completed`

   Warning: Enter the Return Values exactly as given above. There is a check constraint on the DEMO_PROJECTS table that only allows these three values (in mixed case).

   Verify that your screen matches the next illustration.

   Click Create List of Values.

7. When you generated the application, it created a Navigation Menu which lists all the pages specified in the Create Application Wizard. This list enables users to navigate to different pages in your application and is displayed on the left-hand side of all pages by default. However, some of the generated pages should not be displayed in the Navigation List.

   Update the list entries.

   Click the Shared Components button on the toolbar. Under Navigation, click Lists.

   Click Desktop Navigation Menu.

   Click Grid Edit.

   Select check boxes for entries with the following Link Text:

   - Demo Milestones
   - Demo Tasks
   - Demo Project Comments

   Click Delete.

   In the Link Text column, change the following entries as shown:

   - Demo Team Members - enter `Team Members`
   - Demo Projects - enter `Projects`

   In the Current for Pages column, change the entry for Projects:

   - 4,5 - enter `4,5,6,7,8`

   Verify that your screen matches the next illustration.

   Click Apply Changes.

8. Add images to the remaining list entries to improve visual aesthetics.

   Click Cancel and then click Home.

   For Image/Class, enter `fa-`, and click the Next button.

   For Image/Class, enter `fa-users`, and click the Next button.

   For Image/Class, enter `fa-folder`, and click the Next button.

   For Image/Class, enter `fa-calendar`, and click Apply Changes.

9. When you create an application, a Navigation Bar is created to allow entries to be placed on the top right of all pages (on the same line as the application name).

   Update the Navigation Bar list entries.

   Click the Lists tab.

   Click Desktop Navigation Bar.

   Click Create List Entry.

   Input the following:

   - Image/Class - enter `fa-user`
   - List Entry Label - enter `&APP_USER.`
   - Target Type - URL
   - URL Target - enter `#`
   - List Entry Label - enter `has-username`

   Click Create List Entry.

10. Place the Logout entry under the new Application User entry.

    Click the Log Out list entry.

    For Parent List Entry, select &APP_USER.. Click Apply Changes.

11. Define a list of Project Actions that users can perform on the page.

    Click the Lists tab.

    Click Create.

    Select From Scratch (default) and click Next.

    For Name, enter `Project Actions`, and click Next.

    Enter the following to the List Entry Label and Target Page ID columns:

    `Add Milestone / 6
    Add Task / 7
    Add Comment / 8`

    Click Next.

    Click Create List.

12. Configure each list entry (Add Milestone, Add Task, and Add Comment).

    Click Project Actions.

    Click Add Milestone.

    Input the following:

    - Image Class - enter `fa-flag`
    - Clear Cache - enter `6`
    - Set these items - enter `P6_PROJECT_ID`
    - With these values - enter `&P10_PROJECT_ID.`

    Click the Next button on the toolbar.

    For the Add Task list entry, input the following:

    - Image/Class - enter `fa-check-square-o`
    - Clear Cache - enter `7`
    - Set these items - enter `P7_PROJECT_ID`
    - With these values - enter `&P10_PROJECT_ID.`

    Click the Next button on the toolbar.

    For the Add Comment list entry, input the following:

    - Image/Class - enter `fa-comment`
    - Clear Cache - enter `8`
    - Set these items - enter `P8_PROJECT_ID`
    - With these values - enter `&P10_PROJECT_ID.`

    Click Apply Changes.

13. The default login page is boring so you are going to spruce it up with a few quick updates.

    Click Edit Page 1 on the toolbar.

    In the Page Number field on the toolbar, enter `101` and click Go.

    Click the Log In region and input the following in the Property Editor:

    - Title - enter `Demo Projects`
    - Template - Login
    - Icon CSS Classes - enter `fa-folder`

    Locate the Rendering Tree. Under Items, click P101_USERNAME. Input the following in the Property Editor:

    - Template - Hidden
    - CSS Classes - enter `icon-login-username`
    - Value Placeholder - enter `username`

    In the Rendering Tree, click on the P101_PASSWORD item, and input the following In the Property Editor:

    - Template - Hidden
    - CSS Classes - enter `icon-login-password`
    - Value Placeholder - enter `password`

    In the Rendering Tree, under Region Buttons, click the LOGIN button. For Button Position, select Next.

    Click Save.

    Click Save and Run Page.

You have defined all of the Shared Components and are ready to start improving the other pages you generated initially.

## Updating the Team Member Pages

In this topic, update the Team Member pages by adding a card region and improving the modal form page. This will provide a directory of your team members' contact info and roles as though you had a stack of your their business cards at hand.
To watch a video of the steps in this section, see this video.

Note: If you have not completed the previous topic, you can import the Demo Projects App Export - Topic 4.sql file into your workspace, and continue working from this topic forward. You can find the export file in the `/files` subdirectory where you unzipped the original file.

1. Click on the Page Finder on the toolbar and click 2 to navigate to Page 2 - Demo Team Members.

2. Update the page properties from Demo Team Members to Team Members.

   In the Property Editor:

   - Name - enter `Team Members`
   - Title - enter `Team Members`

   Note: The Page Title is displayed in the browser's title bar, therefore, it is important to ensure this attribute has a meaningful entry.
   You may also consider adding the application name to each title, for example `Demo Project - Team Members`

   For CSS - Inline, copy-paste the following code:

   `.t-Card-icon img {
   width: 48px;
   height: 48px;
   }`

   Note:This CSS ensures that the images are all the same size (48 pixels) irrespective of the size of the image uploaded.

   Click Save.

3. Breadcrumbs are very common within Web applications to allow users to easily traverse from the current page to a parent page. Use of the `Back` button is discouraged within Web applications, as this operation may display old ("stale") information to the user.

   Update the breadcrumb entry for the page.

   In the Rendering Tree, click the Shared Components tab.

   Expand the Breadcrumbs folder and click the Breadcrumb entry. In the Property Editor, click the Edit Component button.

   Click the Demo Team Members breadcrumb entry.

   For Short Name, enter `Team Members`, and click Apply Changes.

4. Interactive Reports are the default report type when generating report pages from the Create Application Wizard. However, for this page we want to convert the report type to a Classic Report type, so that we can utilize one of the built-in templates.

   Update the Interactive Report to a Classic Report, and apply the Cards template to display the team members in a more visually pleasing manner.

   Click Edit Page 2 on the toolbar.

   Click the DEMO_TEAM_MEMBERS region and input the following:

   - Title - enter `Team Members`
   - Type - Classic Report

   In the SQL Query attribute, click the Code Editor button.

   In the Code Editor window, delete the existing SQL Query and copy-paste the following code:

   `select id
   , full_name card_title
   , profile card_text
   , nvl(email,' ') card_subtext
   , dbms_lob.getlength('PHOTO_BLOB') card_initials
   , apex_util.prepare_url('f?p='||:APP_ID||':3:'||:APP_SESSION||'::::P3_ID:'||id) card_link
   , photo_filename
   , photo_mimetype
   , photo_charset
   , photo_last_updated
   from demo_team_members
   order by created`

   Note: This SQL query uses specific column names, such as card_title, which correspond to the columns required for the Card template.

   Click OK.

5. The report region has the required Type and SQL Source, now the report needs to be enhanced to display an image and utilize the correct report template.
   The `DEMO_TEAM_MEMBERS` table includes columns which store an image and the image's associated properties. You can use this information to show the team Member's stored image, instead of the member's initials in the cards report.

   Locate the Rendering Tree. Under Team Members, expand the Columns folder, click the CARD_INITIALS item, and input the following:

   - Type - Display Image
   - Table Name - DEMO_TEAM_MEMBERS
   - BLOB Column - PHOTO_BLOB
   - Primary Key Column 1 - ID
   - Mime Type Column - PHOTO_MIMETYPE
   - Filename Column - PHOTO_FILENAME
   - Last Updated Column - PHOTO_LAST_UPDATED

   Locate the Rendering Tree. Under Team Members, click Attributes, and input the following:

   - Template - Cards

   Click the Template Options button and select the following:

   - Style - Basic
   - Icons - Display Initials
   - Layout - 4 Columns
   - Body Text - 3 Lines

   Click OK and Save.

6. By default, buttons are positioned in the region they are associated with. Repositioning the CREATE button to the top of the page, within the Bredcrumbs region, will make the page look better and not waste vertical space.

   In the Rendering Tree, locate the CREATE button under Content Body. Click and hold the CREATE button and drag it up into the Breadcrumbs region. It will appear as a child within its own Region Buttons folder. In the Property Editor, input the following:

   - Label - enter `Add Team Member`
   - Button Position - Create
   - Hot - Yes

   Click Save and Run Page to see the new cards.

7. If you click on any of the cards, the modal form page displays.

   On the Developer Toolbar at the bottom of the page, click Edit Page 3 to jump to the modal page in Page Designer.

   In the Property Editor:

   - Name - enter `Maintain Team Member`
   - Title - enter `Maintain Team Member`

   Click the Edit DEMO_TEAM_MEMBERS region. In the Property Editor, click the Template Options button. For Item Width, select Stretch Form Fields and click OK.

8. The generated page includes a number of page items to allow users to enter details on a Team Member.
   As it is currenlty defined, none of the items must be entered when creating or updating a record. However, you need to ensure that the Username and Full Name fields are always entered, so you will make them mandatory. If one of these fields is left blank when the record is saved, then an error message will be displayed to the user.
   Users are expected to enter a few lines of information into the Profile field. Therefore, you will convert the item type to Textarea so multiple lines are provided for data entry.
   You will see that the Photo Blob field allows a file to be uploaded into the table. The other photo fields will be populated when a file is uploaded, so these items must be hidden from the users.

   In the Rendering Tree, under Content Body, expand the Items folder. Hold the Ctrl key and click P3_USERNAME and P3_FULL_NAME to select more than one item. In the Property Editor, select the following:

   - Template - Required
   - Value Required - Yes

   In the Rendering Tree, click the P3_PROFILE item and input the following:

   - Type - Textarea
   - Help Text - clear the Help Text

   Note: You should either add meaningful help text for all the displayed items, or remove the current text which is `No help available for this page item.`.

   In the Rendering Tree, click the P3_PHOTO_BLOB item. For Label, enter `Photo`.

   Click the divider between Grid Layout and the Gallery to collapse the Gallery.

   In the Grid Layout, hold the Ctrl key and click the following items to select more than one:

   - P3_PHOTO_FILENAME
   - P3_PHOTO_MIMETYPE
   - P3_PHOTO_CHARSET
   - P3_PHOTO_LAST_UPDATED

   In the Property Editor under Identification, click the Type Quick Pick button and select Hidden.

9. The tables you created earlier include audit columns for storing when and who created and last upadated each record. End users should never be allowed to enter data into these columns. Further, these columns should only not be displayed when the user is creating a new record. Given that audit information is only reviewed on occassion, it is preferable to add these columns into a separate, collapsible region, so they can be reviewed when necessary, but don't take up excessive screen real estate the majority of time.

   Reconfigure the audit columns to be Display Only and place them in a conditional sub-region.

   In the Rendering Tree, right-click Edit DEMO_TEAM_MEMBERS and select Create Sub Region.

   In the Property Editor:

   - Title - enter `Audit Details`
   - Template - Collapsible

   Click the Template Options button and input the following:

   - Default State - Collapsed
   - Style - Remove UI Decoration

   Click OK.

   In the Property Editor, click the Go To Group button in the top-right, select Condition, and select the following:

   - Type - Item is NOT NULL
   - Item - P3_ID

   From the Rendering Tree or Grid Layout, click the P3_CREATED column, hold the Ctrl key and click the following items to select more than one:

   - P3_CREATED_BY
   - P3_UPDATED
   - P3_UPDATED_BY

   In the Property Editor:

   - Type - Display Only
   - Region - Audit Details

   Click Save.

   Note: If you try and run a modal page directly from the builder, an error message displays because you can't run dialog pages directly from Page Designer. Modal pages must be invoked from a base page. When the modal page is closed it must have a target page to return to, being the page it was invoked from.

   Navigate to the tab or browser with the runtime application. Return to the Team Members page, refresh the browser, and click on one of the Team Member cards to see the improved modal page.

## Updating the Project Pages

In this topic, a new project master-details page will be created to show the project details, for a selected project, together with all of the child records for that project. Once complete this will be the most used page within the application, as users will be able to not only view project details, but also maintain Milestones, Tasks, and Comments. The previously generated project pages will be updated to link to this Project Details page.
To watch a video of the steps in this section, see this video.

Note: If you have not completed the previous topic, you can import the Demo Projects App Export - Topic 5.sql file into your workspace, and continue working from this topic forward. You can find the export file in the `/files` subdirectory where you unzipped the original file.

1. Create the Projects master-detail page.
   A master-detail page is simply a specific page template, which includes region posiitions for the master and detail regions, together with a right-side display position. Such page layouts are commonly used within the Packaged Apps as such pages provide large amounts of data in a single page layout, in a very simple and intuitive design, that is easy for end users to utilize.

   Navigate to Page Designer. On the toolbar at the top of the screen, click the Create button, which is a plus sign ( + ). Select Page.

   Click Report.

   Click Classic Report.

   In the Property Editor:

   - Page Name - enter `Project Details`
   - Region Name - enter `Master Project`
   - Report Template - template: 42. Value Attribute Pairs - Column
   - Breadcrumb - Breadcrumb
   - Parent Entry - Demo Projects (Page 4)

   Click Next.

   Instead of creating a new entry in the navigation menu, add to the pre-existing Projects list entry:

   - Navigation Preference - Identify an existing navigation menu entry for this page
   - Existing Navigation Menu Entry - Projects

   Click Next.

   For Source Type, select SQL Query, and copy-paste the following into SQL Query:

   `select p.description
   , (select full_name from demo_team_members tm where tm.id = p.project_lead) project_lead
   , p.completed_date
   , p.status
   , p.created
   , p.updated last_updated
   from demo_projects p
   where p.id = :P10_PROJECT_ID`

   Click Next.
   Note: This SQL Query limits the project using `:P10_PROJECT_ID` in the where condition. This page item will be created on this page, after the page has been generated.
   When creating a page item the name should always start with the page number, such as P10_xxx, to ensure every item has a unique name, and to make it easier for application maintenance. In an earlier step of this wizard, Page Attributes, the Page Number was specified as `10`, therefore, in the SQL Source we have specified `:P10_PROJECT_ID`.

   Select the following:

   - Column Heading Sorting - No
   - CSV Output - No

   Click Next.

   On the Confirmation Page, click Create.

2. Configure the Master Detail page properties.

   In the Property Editor:

   - Page Template - Master Detail
   - CSS - Inline - copy-paste the following code: `.a-MediaBlock-graphic img {
     width: 100%;
     }
     .t-Comments-userIcon {
     border-color: rgba(0,0,0,.25);
     }`

   Note: This CSS code is used to style the team member's image that will be displayed in the Comments report.

3. Configure the Master Project region and add hidden items required to drive this page.

   In the Rendering Tree, click Master Project. In the Property Editor, input the following:

   - Position - Master Detail
   - Template - Blank with Attributes

   In the Rendering Tree, under Master Project, click Attributes.
   In the Property Editor, for Pagination - Type select No Pagination (Show All Records).

   In the Rendering Tree, right-click the Master Project region and select Create Page Item.

   In the Property Editor:

   - Name - enter `P10_PROJECT_ID`
   - Type - select Hidden

   Note: This page item name must correspond to the item specified in the where condition for the Project Details SQL Source.

   In the Rendering Tree, under Master Project, right-click the P10_PROJECT_ID item and select Duplicate.

   In the Property Editor, for Name enter `P10_PROJECT_NAME`.

4. Define a computation to populate the Project Name item. This item will be used in the breadcrumb for the page, so that it dynamically displays th currently selected project.

   In the Rendering Tree, expand the Pre-Rendering folder. Right-click After Header and select Create Computation.

   In the Property Editor:

   - Item Name - P10_PROJECT_NAME
   - SQL Query - copy-paste the following code: `select name
     from demo_projects
     where id = :P10_PROJECT_ID`

   Click Save.

5. Instead of a static breadcrumb, update it to use the Project Name.

   In the Rendering Tree, click the Shared Components tab. Expand the Breadcrumbs folder, and click Breadcrumb.
   In the Property Editor, click the Edit Component button.

   Click the Project Details breadcrumb entry.

   For Short Name, enter `&P10_PROJECT_NAME.` and click Apply Changes.
   Warning: When entering `&P10_PROJECT_NAME.` ensure you include the period after the item name.
   Note: When referencing page items within SQL Source or PL/SQL Expression you need to use the `:P[page_number]_[item_name]` syntax.
   However, when specifying page items elsewhere, such as in breadcrumb or links, where they are not part of SQL, you need to use the `&P[page_number]_[item_name]`. syntax.

6. Modify the existing Projects Interactive Report (Page 4) and modify the SQL Query associated with the report to add some new columns.

   In the Application Builder breadcrumbs to the top-left, click Application #### (your application ID, such as Application 434).

   Click 4 - Demo Projects.

   In the Rendering Tree, under the Content Body region, expand DEMO_PROJECTS and click Attributes.
   In the Property Editor, for Link Column select Exclude Link Column.

   Click the DEMO_PROJECTS region.
   In the Property Editor, click the Code Editor: SQL Query button, and copy-paste the following SQL:

   `select id
   , name
   , description
   , (select full_name
   from demo_team_members tm
   where tm.id = p.project_lead
   ) project_lead
   , (select count('x')
   from demo_milestones m
   where m.project_id = p.id
   ) milestones
   , (select count('x')
   from demo_milestones m
   where m.project_id = p.id
   and m.due_date < sysdate
   and exists (select 'x' from demo_tasks t
   where t.milestone_id = m.id and t.end_date > m.due_date)
   ) missed_milestones
   , (select count('x')
   from demo_milestones m
   where m.project_id = p.id
   and m.due_date >= sysdate
   ) milestones_remaining
   , (select count('x')
   from demo_milestones m
   where m.project_id = p.id
   and m.due_date >= sysdate
   and exists (select 'x' from demo_tasks t
   where t.milestone_id = m.id and t.end_date > m.due_date)
   ) at_risk_milestones
   , (select count('x')
   from demo_tasks t
   where t.project_id = p.id
   ) tasks
   , ( (select count('x')
   from demo_tasks t
   , demo_milestones m
   where m.id = t.milestone_id
   and t.project_id = p.id
   and m.due_date < sysdate
   and nvl(is_complete_yn, 'N') = 'Y'
   and t.end_date > m.due_date
   )
   + (select count('x')
   from demo_tasks t
   where t.project_id = p.id
   and nvl(is_complete_yn, 'N') = 'Y'
   and t.milestone_id is null
   and t.end_date > nvl(p.completed_date, t.end_date)
   )
   ) missed_tasks
   , (select count('x')
   from demo_tasks t
   where t.project_id = p.id
   and nvl(is_complete_yn, 'N') = 'N'
   and t.end_date < sysdate
   ) incomplete_past_tasks
   , (select count('x')
   from demo_tasks t
   where t.project_id = p.id
   and nvl(is_complete_yn, 'N') = 'N'
   and t.end_date >= sysdate
   ) tasks_remaining
   , (select count('x')
   from demo_tasks t
   , demo_milestones m
   where m.id = t.milestone_id
   and t.project_id = p.id
   and m.due_date >= sysdate
   and t.end_date > m.due_date
   ) at_risk_tasks
   , completed_date
   , status
   , created
   , created_by
   , updated
   , updated_by
   from demo_projects p`

   Note: This SQL statement returns numerous statistics, using inner select statements, several of which are not displayed in the Primary Report. However, end users can alter the Interactive Report and display any of the columns included in the SQL.

   In the Code Editor, click OK.

   Click the Save and Run Page button on the toolbar.

   The Demo Projects runtime page opens in a new tab or window.

7. Reconfigure which columns are displayed by default in the Interactive Report.

   In the Interactive Report runtime window, click Actions and select Select Columns.

   The Select Columns window displays.

   In the Display Report column, hold the Ctrl key and click the following items to select them:

   - Id
   - Description
   - Completed Date
   - Created
   - Created By
   - Updated
   - Updated By
   - Milestones
   - Missed milestones
   - Tasks
   - Missed tasks

   Click the Remove button ( < ) in the center.

   In the Do Not Display column, double-click Project lead to move it from the Do Not Display list to the Display in Report list. Click the Up button ( ↑ ), on the right, until Project lead is below Status in the list.

   Click Apply.

   The column headings can be capitalized to make them consistent and more redable.

   To jump to the PROJECT_LEAD column in Page Designer, click Quick Edit in the Developer Toolbar, move the mouse cursor over Project Lead until the component is highlighted, and click Project lead.

   In the Property Editor, for Heading enter `Project Lead`.

   Repeat this for the other columns by selecting each in turn within the Rendering Tree and then updating their Heading in the Property Editor.

   Click Save.

8. Update the breadcrumb for Page 4.

   In the Rendering Tree, click the Shared Components tab. Expand the Breadcrumbs folder and click Breadcrumb.
   In the Property Editor, click the Edit Component button.

   Click the Demo Projects breadcrumb entry.

   For Short Name, enter `Projects` and click Apply Changes.

   On the toolbar, click Edit Page 4.

9. Reposition the CREATE button to the top of the page.

   In the Grid Layout, locate the Breadcrumbs region. Note that there are several elements surrounded by dotted lines. These are placeholders for buttons.

   Locate the DEMO_PROJECTS region. Click and hold the Create button and drag it up to the Breadcrumbs region and into the Create placeholder.
   Tip: To undo a previous action, press Ctrl+Z in Windows or click the Undo button on the top-right toolbar.

   In the Property Editor, for Label enter `Create Project`.

10. The previous edit icon for the Interactive Report has been removed. To navigate to the new Project Details page (Page 10), define a link on the Name column.

    In the Rendering Tree, under the Content Body region, expand DEMO_PROJECTS. Expand the Columns folder and click Name.

    In the Property Editor:

    - Type - Link

    Click the Link Builder button (No Link Defined) and input the following:

    - Page - enter `10`
    - Name - P10_PROJECT_ID
    - Value - #ID#
    - Clear Cache - enter `10`

    Click OK.
    Note: the Link Builder button display changes in the Property Editor to reflect its current configuration.

    For Link Text, select #NAME#.

    Click Save and Run Page on the toolbar.

11. Make the Interactive Report functional by adding some aggregations and save the report as the "Primary Report" in the Interactive Report runtime.

    In the Interactive Report page of the Demo Projects runtime window, click Actions, select Format, and select Aggregate.

    In the Aggregate window, select the following:

    - Function - Sum
    - Column - Milestones Remaining

    Click Apply.

    Repeat the above process (click Actions, select Format, and select Aggregate) to add sums for the following columns:

    - At Risk Milestones
    - Incomplete Past Tasks
    - Tasks Remaining
    - At Risk Tasks

    Once you have added aggregates to those five columns, save the "Primary Report" within the Interactive Report runtime:

    Click Actions and select Save Report.

    For Save select As Default Report Settings.
    Note: This option is only available to application developers, who have run the application from the application builder, and not to end users running the report.

    For Default Report Type, select Primary (selected by default) and click Apply.

    Page 4 is complete.

12. Time to enhance the Project Details page and add multiple regions for the detail records.

    Add the Region Display Selector region to Page 10.

    In the Demo Projects runtime window, click Projects in the top-left to navigate to the Projects page. Click Configure APEX Environment.

    On the Developer Toolbar, click Edit Page 10.

    Locate the divider at the bottom of the Grid Layout. Click the Restore button to redisplay the Gallery.

    In the Gallery, locate Region Display Selector. Click and hold Region Display Selector and drag it to the bottom of the Master Project region. It should appear as a long, shaded row in the Master Project region before you drop it into place.

    In the Property Editor:

    - Title - enter `Region Display Selector`
    - Template - Blank with Attributes

13. Add the Milestones report region to Page 10.

    In the Gallery, locate Classic Report. Click and hold Classic Report and drag it up into the Content Body section. It should appear as a square tile before you drop it into place.

    In the Property Editor:

    - Title - enter `Milestones`
    - SQL Query - copy-paste the following code: `select m.id
      , m.name
      , m.description
      , m.due_date
      from demo_milestones m
      where project_id = :P10_PROJECT_ID
      order by due_date desc, updated`

    Click the Template Options button and input the following:

    - Use Template Defaults - enable (enabled by default)
    - Remove Body Padding - enable

    Click OK.

    For Static ID, enter `milestones`.
    Note: Each of the regions and buttons that you will be adding will be given a unqiue Static ID. These will be used in a later topic when defining Dynamic Actions that utilize these values.

14. Update the columns and attributes for the Milestones region.

    In the Rendering Tree, under Content Body, expand the Milestones node. Expand the Columns folder. Click ID.
    In the Property Editor:

    - Type - Link
    - Heading - delete any text to clear the field

    Click the Link Builder button (No Link Defined).

    In the Link Builder window, input the following:

    - Page - enter `6`
    - Name - P6_ID
    - Value - #ID#
    - Clear Cache - enter `6`

    Click OK.

    In Link Text, click the Quick Pick button (its icon looks like a bulleted list). Select apex-edit-pencil.png.

    In the Rendering Tree, under Milestones, click Attributes.
    In the Property Editor, click the Template Options button.

    In the Template Options window, input the following:

    - Use Template Defaults - enable (enabled by default)
    - Stretch Report - enable
    - Report Border - No Outer Borders

    Click OK.

    In the Property Editor:

    - Pagination > Type - No Pagination (Show All Rows)
    - When No Data Found - enter `No Milestones`

15. Add a button that users can use to add milestone records.

    In the Gallery, click the Buttons tab. Click and hold Icon, drag it to the Milestones region, and place it in the Edit placeholder.

    In the Property Editor:

    - Button Name - enter `ADD_MILESTONE`
    - Label - enter `Add milestone`
    - Icon CSS Classes - fa-plus
    - Behavior > Action - Redirect to Page in this Application

    Click the Template Options button. For Style, select Remove UI Decoration and click OK.

    Click the Link Builder button (No Link Defined).

    In the Link Builder, input the following:

    - Page - enter `6`
    - Name - P6_PROJECT_ID
    - Value - &P10_PROJECT_ID.
    - Clear Cache - enter `6`

    Click OK.
    Note: In this link the `P10_PROJECT_ID` is sent to Page 6 as the new milestone will be created for the currently selected project.

    For Static ID, enter `add-milestone`.

16. Duplicate the Milestones region and update it form the Tasks region. Given the similarities between the regions, duplicating the existing region will save numerous steps.

    In the Rendering Tree, right-click the Milestones region and select Duplicate.

    In the Property Editor:

    - Title - enter `Tasks`
    - SQL Query - copy-paste the following code: `select t.id
      , t.name
      , t.description
      , decode(nvl(t.is_complete_yn,'N'),'N','No','Y','Yes') completed
      , (select m.name from demo_milestones m where m.id = t.milestone_id) milestone
      , (select tm.full_name from demo_team_members tm where tm.id = t.assignee) assignee
      , t.start_date
      , t.end_date
      from demo_tasks t
      where t.project_id = :P10_PROJECT_ID
      order by nvl(t.end_date, sysdate) desc`

    For Static ID, enter `tasks`.

    In the Rendering Tree, expand the Columns folder, select ID, and click the Link Builder button (Page 6).

    In the Link Builder window, input the following:

    - Page - enter `7`
    - Name - P7_ID
    - Value - #ID#
    - Clear Cache - enter `7`

    Click OK.

    In the Rendering Tree, under the Tasks region, select Attributes. For When No Data Found, enter `No Tasks`.

17. Update the button associated with the Tasks region.

    Click the ADD_MILESTONE_1 button. In the Property Editor:

    - Button Name - enter `ADD_TASK`
    - Label - enter `Add task`
    - Button Position - Edit

    In Behavior > Target, click the Link Builder button.

    In the Link Builder, input the following:

    - Page - enter `7`
    - Name - P7_PROJECT_ID
    - Value - &P10_PROJECT_ID.
    - Clear Cache - enter `7`

    Click OK.

    In the Property Editor, for Static ID enter `add-task`.

18. Create the Comments region.

    Right-click the Tasks region and select Duplicate.

    In the Property Editor:

    - Title - enter `Comments`
    - SQL Query - copy-paste the following code: `select tm.id id
      , c.id comment_id
      , ' ' icon_modifier
      , c.comment_text
      , c.created comment_date
      , dbms_lob.getlength(tm.photo_blob) user_icon
      , tm.full_name user_name
      , null actions
      , null attribute_1
      , null attribute_2
      , null attribute_3
      , null attribute_4
      from demo_team_members tm
      , demo_project_comments c
      where c.project_id = :P10_PROJECT_ID
      and upper(c.created_by) = upper(tm.username)
      order by c.created desc`

    Note: The columns in this SQL query use specific names required by the Comments template.

    Click the Template Options button and input the following:

    - Use Template Defaults - enable (enabled by default)
    - Remove body Padding - disable

    Click OK.

19. Update the columns and attributes for the Comments region.

    In the Rendering Tree, expand the Columns node, select ID. In the Property Editor, click the Link Builder button (Page 7).

    In the Link Builder, input the following:

    - Page - enter `8`
    - Name - P8_ID
    - Value - #ID#
    - Clear Cache - enter `8`

    Click OK.

    In the Rendering Tree, under Comments > Columns, select COMMENT_DATE.
    In the Property editor, for Format Mask enter `SINCE`.

    In the Rendering Tree, under Comments > Columns, select USER_ICON.
    In the Property Editor:

    - Type - Display Image
    - Table Name - DEMO_TEAM_MEMBERS
    - BLOB Column - PHOTO_BLOB
    - Primary Key Column 1 - ID
    - Mime Type Column - PHOTO_MIMETYPE
    - Filename Column - PHOTO_FILENAME
    - Last Updated Column - PHOTO_LAST_UPDATED

    In the Rendering Tree, under Comments, click Attributes.
    In the Property Editor:

    - Template - Comments
    - Show Null Values as - enter `&nbsp;`
    - When No Data Found - enter `No Comments`

20. Update the button associated with the Comments region.

    Click the ADD_TASKS_1 button.
    In the Property Editor:

    - Button Name - enter `ADD_COMMENT`
    - Label - enter `Add comment`
    - Button Position - Edit for Button Position

    In Behavior > Target, click the Link Builder button.

    In the Link Builder, input the following:

    - Page - enter `8`
    - Name - P8_PROJECT_ID
    - Value - &P10_PROJECT_ID.
    - Clear Cache - enter `8`

    Click OK.

    In the Property Editor, for Static ID enter `add-comment`.

21. Add a region to the side of the Comments page to display the Project Actions list you defined earlier.

    In the Gallery, click the Regions tab, and locate List. Click and hold List and drag it into the Right Side Column placeholder.

    In the Property Editor:

    - Title - enter `Project Actions`
    - List - Project Actions
    - Template - Blank with Attributes
    - Static ID - enter `actions`
    - Region Display Selector - No

    In the Rendering Tree, expand the Right Side Column folder, expand Project Actions, and select Attributes.
    In the Property editor, click the Template Options button (Use Template Defaults).

    In Template Options, select the following:

    - Style - Actions
    - Display Icons - For All Items

    Click OK.

22. Add a button to Page 10 to allow you to edit the Project.

    In the Gallery, click the Buttons tab and locate Text [Hot]. Click and hold Text [Hot] and drag it to the Breadcrumb region and into the Edit placeholder.

    In the Property Editor:

    - Title - enter `EDIT_PROJECT`
    - Label - enter `Edit Project`
    - Behavior > Action - Redirect to Page in this Application

    Click the Link Builder button (No Link Defined).

    In the Link Builder, input the following:

    - Page - enter `5`
    - Name - P5_ID
    - Value - &P10_PROJECT_ID.
    - Clear Cache - enter `5`

    Click OK.
    Note: This link is to the orioginal project form page generated in the Create Application Wizard, which was previously called from the Projects report page (Page 4).

Click Save and Run Page on the toolbar. The Master-Detail page shows a substantial amount of information in a single page.

## Updating the Detail Pages

In this topic, improve the detail pages for maintaining projects, milestones, tasks, and adding comments. Convert the form pages you generated in the Create Application Wizard for Milestones, Tasks, and Comments into modal pages and update item attributes to make the pages look better.
To watch a video of the steps in this section, see this video.

Note: If you have not completed the previous topic, you can import the Demo Projects App Export - Topic 6.sql file into your workspace, and continue working from this topic forward. You can find the export file in the `/files` subdirectory where you unzipped the original file.

1. Modify the default Project form to be more very visually appealing

   In the Demo Projects runtime environment, navigate to the Projects page and open one of the projects such as Configure APEX Environment.
   Reviewing the items it can be seen that Name should be mandatory, the Description item doesn't show all of the data, lists are required for some items, such as Project Lead and Status, and the audit columns should be moved to a sub-region.

   Click the Edit Project button. On the developer toolbar, click Edit Page 5.

   In the Property Editor:

   - Name - enter `Maintain Project`
   - Title - enter `Maintain Project`
   - Cursor Focus - First item on page

2. Update the page items.

   In the Grid Layout, under Content Body, click the P5_NAME item.
   In the Property Editor:

   - Template - Required
   - Width - enter `60`
   - Value Required - Yes

   In the Grid Layout, click the P5_DESCRIPTION item.
   In the Property Editor:

   - Type - Textarea
   - Width - enter `70`
   - Help Text - delete any text to clear the field

   In the Grid Layout, click the P5_PROJECT_LEAD item.
   In the Property Editor:

   - Identification > Type - Select List
   - List of Values > Type - select Shared Component
   - List of Values - TEAM_MEMBERS
   - Display Extra Values - No
   - Null Display Value - enter `- Select Team Member -`

   Note: The `P5_PROJECT_LEAD` item is using the List of Values defined in Shared Components in an earlier topic.

   In the Grid Layout, locate the P5_STATUS item. Click and hold P5_STATUS and drag it above the P5_COMPLETED_DATE column.
   Note: The Status item should be placed before the Completed Date as the date should only be entered when the status is Completed.

   In the Property Editor:

   - Identification > Type - Select List
   - List of Values > Type - Shared Component
   - List of Values - PROJECT_STATUS
   - Display Extra Values - No
   - Display Null Values - No

   Click the P5_COMPLETED_DATE item, and for Template select Required.
   Note: Generally when an item is mandatory you update the Template to Required and the Value Required to Yes. However, in this instance the Value Required attribute should remain No because the item is only mandatory when the status is Completed. A validation is added later in this section to accomodate this business rule.

3. Dynamic Actions within Application Express are used to declaratively define client-side behaviors without needing to write JavaScript or AJAX. Instead the Application Express engine implements the necessary code, based on your declaration.

   Create a Dynamic Action.

   Right-click the P5_STATUS item and select Create Dynamic Action.

   In the Property Editor:

   - Name - enter `Show Completed Date`
   - Condition - equal to
   - Value - enter `Completed`

   In the Rendering Tree, under the Show Completed Date dynamic action, expand the True folder and select Show.
   In the Property Editor, for Item(s) select P5_COMPLETED_DATE.

   Right-click Show and select Create Opposite Action.
   Note: For Dynamic Action types, such as Show, Enable, and Expand Tree, it is important to also include the corresponding opposite action. In that way the affected elements are set one way if the When Condition evaluates to True and the opposite if the When Condition evaluates to False. In this case the `P5_COMPLETED_DATE` item is shown when `P5_STATUS` equals Completed, and is hidden when any other status is selected.

4. Add validations to the Maintain Projects page so that when a user changes the staus to Completed, they add the Completed Date and that it is not forward-dated.

   In the left pane, click the Processing tab. Right-click the Validating node and select Create Validation.

   In the middle pane, click the Help tab.
   Note: The help text displays the currently selected attribute in the Property Editor (right pane). For example, clicking on the Validation Type attribute label displays a list of all the available options, together with a description of when each option will pass (not display the error message) or fail (displays the error message).

   In the Property Editor:

   - Name - enter `Completed Date is Not Null`
   - Type - Item is NOT NULL
   - Item - P5_COMPLETED_DATE
   - Error Message - select the Error Message attribute label (not the data entry area), at which point the Help pane will display the help text for Error Message. Copy-paste `#LABEL# must have some value.` from the Help pane Examples into the Property Editor attribute
   - Condition > Type - Item = Value
   - Item - P5_STATUS
   - Value - enter `Completed`

   Note: The `#LABEL#` text within the Error Message will be substituted with the Label of the associated item. In this manner, if the item label is updated the error message will also reflect the updated value. This improves consistency and prevents messages having an out of date label reference.

   In the Processing pane, right-click Validating and select Create Validation.

   In the Property Editor:

   - Name - enter `Completed Date is not Forward Dated`
   - PL/SQL Expression - enter `:P5_COMPLETED_DATE <= sysdate`
   - Error Message - enter `#LABEL# can not be forward dated`
   - Associated Item - P5_COMPLETED_DATE
   - Condition > Type - Item is NOT NULL
   - Item - P5_COMPLETED_DATE

   Click Save.

5. Reconfigure the audit columns to be display only and place them in a collapsible sub-region.

   Click the Rendering tab in the left pane. Right-click the Edit DEMO_PRODUCTS region and select Create Sub Region.

   In the Property Editor:

   - Title - enter `Audit Details`
   - Template - Collapsible
   - Condition > Type - Item is NOT NULL
   - Item - P5_ID

   Click the Template Options button and input the following:

   - Default State - Collapsed
   - Style - Remove UI Decoration

   In the Rendering Tree, hold the Ctrl key and click the following items to select them:

   - P5_CREATED
   - P5_CREATED_BY
   - P5_UPDATED
   - P5_UPDATED_BY

   With the above items selected, in the Property Editor:

   - Type - Display Only
   - Region - Audit Details

6. Reposition the buttons.

   Click the CANCEL button.
   In the Property Editor, for Button Position select Previous.

   Click Save.

   Navigate back to your Demo Projects runtime and refresh the browser. In the Projects page, click the Edit Project button.

   Try out these functions to see how the page responds:

   - Change the Status and see how the Completed Date is shown or hidden depending on the status selected.
   - Save a record with a Status of Completed and no Completion Date - An error message should be displayed.
   - Save a record with a Completion Date in the future - An error message should be displayed.

7. Convert the Maintain Milestone, Maintain Task, and Add Comment pages (pages 6 - 8) into modal pages. Modal pages restrict end-users from interacting with the underlying page.

   Update the Milestones page from a normal page to a modal page.

   In the Demo Projects runtime environment, cancel the Maintain Project form and click Add Milestone. On the developer toolbar, click Edit Page 6.

   In the Property Editor:

   - Name - enter `Maintain Milestone`
   - Title - enter `Maintain Milestone`
   - Page Mode - Modal Dialog
   - Cursor Focus - First item on page

   In the Rendering Tree, select the DEMO_MILESTONES region.
   In the Property Editor, for Template select Blank with Attributes.

8. Update the items on the Milestone page (page 6).

   In the Grid Layout, under Content Body, select the P6_PROJECT_ID item.
   In the Property Editor:

   - Type - Display Only
   - Based On - Display Value of List of Values
   - Template - Required
   - List of Values > Type - Shared Component
   - List of Values - PROJECTS

   In the Rendering Tree, select the P6_NAME item.
   In the Property Editor:

   - Template - Required
   - Width - enter `60`
   - Value Required - Yes

   In the Rendering Tree, select the P6_DESCRIPTION item.
   In the Property Editor:

   - Type - Textarea
   - Width - enter `70`
   - Help Text - delete any text to clear the field

   In the Rendering Tree, select the P6_DUE_DATE item.
   In the Property Editor:

   - Template - Required
   - Value Requried - Yes

   In the Rendering Tree, hold the Ctrl key and click the following items to select them all:

   - P6_CREATED
   - P6_CREATED_BY
   - P6_UPDATED
   - P6_UPDATED_BY

   Press the Delete key to remove the four items.

   In the Grid Layout, click the Breadcrumbs region and press Delete to remove it.
   Note: In general, breadcrumbs are not displayed on modal pages as there is limited real estate, and selecting a previous page often causes unexpected behaviour and potentially errors.

   Click Save.

9. In an earlier step you created a sub-region called Audit Details for the Maintain Project page (Page 5). The four items included in that region are the same items previously on the Maintain Milestone page, and are associated with the exact same database columns. As such that region, and its associated items, can be copied to the Maintain Milestone page, which will also copy the previously set template and template options.
   Note: If the four audit items, `P6_CREATED` and so forth, are not deleted from the page before copying the Audit Details region from the other page, then the items within the Audit Details region on this page will be named `P6_CREATED_1` and so forth. This is to ensure every item on a page has a unique name. This will not break the page processing, as the associated Database Column will still be `CREATED` and so forth, however, it is poor programming practice.

   Copy the Audit Details region from Page 5 to Page 6.

   In Page Designer, navigate to Page 5.

   In the Rendering Tree, right-click the Audit Details sub region and select Copy to other Page....

   In the Copy Region dialog, input the following:

   - To Page - enter `6`
   - Copy Region Items - Yes

   Click Next.

   Click Copy.

   In Page Designer, navigate back to Page 6.

   In the Rendering Tree, select the Audit Details sub region.
   In the Property Editor, for Parent Region select DEMO_MILESTONES.

10. When the Maintain Milestone page was first generated, as a normal page, the buttons were generated as Region Buttons. However, now that the page has been changed to be a modal page, this is an inappropriate position for these buttons, as a user will need to scroll to the bottom of the region content in order to see the buttons. Instead a new region should be defined which is always visible at the bottom of the modal window.

    Create a new region in the Dialog Footer and move the buttons to this region.

    At the bottom of the Rendering Tree, right-click the Dialog Footer folder and select Create Region.

    In the Property Editor:

    - Title - enter `Buttons`
    - Template - Buttons Container

    Hold the Ctrl key and click the following region buttons to select them:

    - Cancel
    - Delete
    - Save
    - Create

    In the Property Editor, for Region select Buttons.

    In the Grid Layout, drag each button to the Buttons region and drop them into the following placeholders:

    - CANCEL - PREVIOUS
    - DELETE - DELETE
    - SAVE - CREATE
    - CREATE - CREATE

11. Now that the Maintain Milestone page is a modal page, the page processing associated with closing this page must be modified.

    Add a dynamic action for the Cancel button and replace the branch with a process.

    In the Rendering Tree, under Dialog Footer, right-click the CANCEL button and select Create Dynamic Action.
    In the Property Editor, for Name enter `Cancel Dialog`.

    In the Rendering Tree, under the Cancel Dialog action, select the True event.
    In the Property Editor, for Action select Cancel Dialog.

    In the Rendering Tree, click the Processing tab. Under the Branches folder, select the Go To Page 6 entry and press the Delete key (the Branches folder disappears).

    Right-click on the Processes folder and select Create Process.

    In the Property Editor:

    - Name - enter `Close Dialog`
    - Type - Close Dialog

    Click Save.

    Navigate back to the Demo Projects runtime and refresh the browser. Navigate to the Projects page, click on an item in the Name column, and click on a milestone or click the Add Milestone button (+).

    When you click a Milestone, a dialog window should appear that looks like the following illustration:

12. Update the Maintain Task page (page 7) to a modal page.

    ### Selected instructions for updating the Maintain Task page

    This section should be used by those that are comfortable performing similar steps to those just performed to convert the Maintain Milestone page to a modal page. If complete instructions are required then please proceed to the next section Detailed steps for updating the Maintain Task page to a modal page.

    The instructions below only outline specifics for selected items that may not be self-evident.

    - For the P7_MILESTONE_ID item.
      In the Property Editor:
      - Type - Select List
      - SQL Query - copy-paste teh following code:
      `select name d, id r
      from demo_milestones
      where project_id = :P7_PROJECT_ID
      order by 1`
    - For the P7_ASSIGNEE item.
      In the Property Editor:
      - Type - Select List
      - List of Values > Type - Shared Component
      - List of Values - TEAM_MEMBERS
    - For the P7_IS_COMPLETE_YN item.
      In the Property Editor:
      - Type - Yes/No

    ### Detailed steps for updating the Maintain Task page to a modal page

    1. In Page Designer, use the Page Finder to navigate to page 7.

       In the Rendering Tree, select Page 7: Demo Tasks.
       In the Property Editor:

       - Name - enter `Maintain Task`
       - Title - enter `Maintain Task`
       - Page Mode - Modal Dialog
       - Cursor Focus - First item on page

       In the Rendering Tree, select the DEMO_TASKS region.
       In the Property Editor, for Template select Blank with Attributes.

    2. Update the items on the Maintain Task page.

       In the Grid Layout, under Content Body, select the P7_PROJECT_ID item.
       In the Property Editor:

       - Type - Display Only
       - Based On - Display Value of List of Values
       - Template - Required
       - List of Values > Type - Shared Component
       - List of Values - PROJECTS

       In the Grid Layout, select the P7_MILESTONE_ID item.
       In the Property Editor:

       - Type - Select List
       - List of Values > Type - SQL Query
       - SQL Query - copy-paste the following SQL code:

         `select name d, id r
         from demo_milestones
         where project_id = :P7_PROJECT_ID
         order by 1`

       In the Rendering Tree, select the P7_NAME item.
       In the Property Editor:

       - Template - Required
       - Width - enter `60`
       - Value Required - Yes

       In the Rendering Tree, select the P7_DESCRIPTION item.
       In the Property Editor:

       - Type - Textarea
       - Width - enter `70`
       - Help Text - delete any text to clear the field

       In the Rendering Tree, select the P7_START_DATE item.
       In the Property Editor:

       - Template - Required
       - Value Requried - Yes

       In the Rendering Tree, select the P7_END_DATE item.
       In the Property Editor:

       - Template - Required
       - Value Requried - Yes

       In the Rendering Tree, select the P7_ASSIGNEE item.
       In the Property Editor:

       - Type - Select List
       - List of Values > Type - Shared Component
       - List of Values - TEAM_MEMBERS

       In the Rendering Tree, select the P7_IS_COMPLETE_YN item.
       In the Property Editor:

       - Type - Yes/No

       In the Rendering Tree, hold the Ctrl key and click the following items to select them all:

       - P7_CREATED
       - P7_CREATED_BY
       - P7_UPDATED
       - P7_UPDATED_BY

       Press the Delete key to remove the four items.

       In the Grid Layout, click the Breadcrumbs region and press Delete to remove it.

       Click Save.

    3. Copy the Audit Details region from Page 5 to Page 7.

       In Page Designer, navigate to Page 5.

       In the Rendering Tree, right-click the Audit Details sub region and select Copy to other Page....

       In the Copy Region dialog, input the following:

       - To Page - enter `7`
       - Copy Region Items - Yes

       Click Next.

       Click Copy.

       In Page Designer, navigate back to Page 7.

       In the Rendering Tree, select the Audit Details sub region.
       In the Property Editor, for Parent Region select DEMO_TASKS.

    4. Create a new region in the Dialog Footer and move the buttons to it.

       At the bottom of the Rendering Tree, right-click the Dialog Footer folder and select Create Region.

       In the Property Editor:

       - Title - enter `Buttons`
       - Template - Buttons Container

       Hold the Ctrl key and click the following region buttons to select them:

       - Cancel
       - Delete
       - Save
       - Create

       In the Property Editor, for Region select Buttons.

       In the Grid Layout, drag each button to the Buttons region and drop them into the following placeholders:

       - CANCEL - PREVIOUS
       - DELETE - DELETE
       - SAVE - CREATE
       - CREATE - CREATE

    5. Add a dynamic action for the Cancel button and replace the branch with a process.

       In the Rendering Tree, under Dialog Footer, right-click the CANCEL button and select Create Dynamic Action.
       In the Property Editor, for Name enter `Cancel Dialog`.

       In Dynamic Actions in the left pane under Click, expand the Cancel Dialog action, expand the True folder, and select the True event.
       In the Property Editor, for Action select Cancel Dialog.

       Click the Processing tab in the left pane. Under the Branches folder, select the Go To Page 7 entry and press the Delete key (the Branches folder disappears).

       Right-click on the Processes folder and select Create Process.

       In the Property Editor:

       - Name - enter `Close Dialog`
       - Type - Close Dialog

       Click Save.

       Navigate back to the Demo Projects runtime and refresh the browser. Navigate to the Projects page, click the Tasks tab, and click on a task or the Add Task button (+). The Maintain Task dialog displays.

    The Maintain Task dialog should look like this in the runtime:

13. Update the Add Comment page (page 8) to a modal page.
    Note: Because comments can only be added, and existing comments can not be updated or deleted, the page should be called Add Comments.

    ### Selected instructions for updating the Add Comment page

    This section should be used by those that are comfortable performing similar steps to those just performed to convert the Maintain Milestone and Maintain Task pages to modal pages. If complete instructions are required then please proceed to the next section Detailed steps for updating the Add Comment page to a modal page.

    The instructions below only outline specifics for the page and selected items that may not be self-evident.

    - The modal page should be resized to Width `500` and Height `300`.
    - For the P8_COMMENT_TEXT item.
      In the Property Editor:
      - Type - Textarea
      - Width - enter `70`
      - Height - enter `7`
      - Value Placeholder - enter `Enter comment here...`
    - Change the Type for all items, except P8_COMMENT_TEXT, to Hidden.

    ### Detailed steps for updating the Add Comment page to a modal page

    1. In Page Designer, use the Page Finder to navigate to page 8.

       In the Rendering Tree, select Page 8: Demo Project Comments.
       In the Property Editor:

       - Name - enter `Add Comments`
       - Title - enter `Add Comments`
       - Page Mode - Modal Dialog
       - Width - enter `500`
       - Height - enter `300`
       - Cursor Focus - First item on page

       In the Rendering Tree, select the DEMO_PROJECT_COMMENTS region.
       In the Property Editor, for Template select Blank with Attributes.

    2. Update the items on the Add Comment page.

       In the Rendering Tree, under Regions, expand the Content Body folder, and expand the Items folder. Hold the Ctrl key and click the following items to select all six:

       - P8_ID
       - P8_PROJECT_ID
       - P8_CREATED
       - P8_CREATED_BY
       - P8_UPDATED
       - P8_UPDATED_BY

       With the above 6 items selected, in the Property Editor:

       - Type - Hidden

       In the Grid Layout, select the P8_COMMENT_TEXT item.
       In the Property Editor:

       - Type - Textarea
       - Width - enter `70`
       - Height - enter `7`
       - Value Placeholder - enter `Enter comment here...`

       In the Rendering Tree, expand the Region Buttons folder. Hold the Ctrl key and click the following items to select them all:

       - DELETE
       - SAVE

       Press the Delete key to remove the two buttons.

       In the Grid Layout, click the Breadcrumbs region and press Delete to remove it.

       Click Save.

    3. Create a new region in the Dialog Footer and move the buttons into it.

       At the bottom of the Rendering Tree, right-click the Dialog Footer folder and select Create Region.

       In the Property Editor:

       - Title - enter `Buttons`
       - Template - Buttons Container

       Hold the Ctrl key and click the following region buttons to select them:

       - Cancel
       - Create

       In the Property Editor, for Region select Buttons.

       In the Grid Layout, drag each button to the Buttons region and drop them into the following placeholders:

       - CANCEL - PREVIOUS
       - CREATE - CREATE

    4. Add a dynamic action for the Cancel button and replace the branch with a process.

       In the Rendering Tree, under Dialog Footer, right-click the CANCEL button and select Create Dynamic Action.
       In the Property Editor, for Name enter `Cancel Dialog`.

       In Dynamic Actions in the left pane under Click, expand the Cancel Dialog action, expand the True folder, and select the True event.
       In the Property Editor, for Action select Cancel Dialog.

       Click the Processing tab in the left pane. Under the Branches folder, select the Go To Page 8 entry and press the Delete key (the Branches folder disappears).

       Right-click on the Processes folder and select Create Process.

       In the Property Editor:

       - Name - enter `Close Dialog`
       - Type - Close Dialog

       Click Save.

       Navigate back to the Demo Projects runtime and refresh the browser. Navigate to the Projects page and click on an item in the Name column. Do one of the following:

       - In the Show All tab, scroll to the bottom of the page to the Comments section and click the Add Comment button (+).
       - Click the Comments tab and click the Add Comment button (+).
       - Click the menu button in the top-right (three parallel horizontal lines) to expand the right-hand sidebar and click Add Comment.

       The Add Comment dialog displays.

    The Add Comment dialog should look like this in the runtime:

For further assistance with these modal page conversions, watch the video for Topic 7, or you can import the Demo Projects App Export - Topic 7.sql file into your workspace as a separate application to check your work against it.

## Adding Dynamic Actions

In this topic, add dynamic actions to the Project Details (master-detail) page.
To watch a video of the steps in this section, see this video.

Note: If you have not completed the previous topic, you can import the Demo Projects App Export - Topic 7.sql file into your workspace, and continue working from this topic forward. You can find the export file in the `/files` subdirectory where you unzipped the original file.

1. Dynamic Actions within Application Express are used to declaratively define client-side behaviors without needing to write JavaScript or AJAX. Instead the Application Express engine implements the necessary code, based on your declaration.
   In a previous topic you defined a dynamic action to show or hide an item based on the value of a previous item. In this topic you will create more complex dynamic actions that fire based on the Edit Project button or jQuery selectors to refreh the page or specific regions. These dynamic actions ensure that this page reflects changes made on any of the modal pages, called from this page, as soon as the user returns from the modal page.

   Add a dynamic action for updates to the project.

   In Page Designer, navigate to Page 10.

   Click the Dynamic Actions tab in the left pane (its icon is a lightning bolt). Right-click the Dialog Closed folder and select Create Dynamic Action.

   In the Property Editor:

   - Name - enter `Project Updates`
   - Selection Type - Button
   - Button - EDIT_PROJECT

   In the Dynamic Actions pane under Project Updates, click the True action (currently Refresh).
   In the Property Editor, for Action select Submit Page.
   Note: The Submit Page action refreshes the whole page. This action is required to ensure the breadcrumb is recomputed for the use case where the Project Name was updated when the user edited the project and then returned to this page.

2. Add a dynamic action for updates made on the Maintain Milestone modal page.

   In the Dynamic Actions pane, right-click the Dialog Closed folder and select Create Dynamic Action.
   In the Property Editor:

   - Name - enter `Milestone Updates`
   - Selection Type - jQuery Selector
   - jQuery Selector - enter `#milestones, #add-milestone, #actions`
   - Condition - JavaScript Expression
   - JavaScript Expression - enter `this.data && this.data.dialogPageId == "6"`
   Note: For this dynamic action we need to use a Selection Type of jQuery Selector because the user can edit an existing milestone (Static ID = milestones), add a milestone by clicking the + button (Static ID = add-milestone) above the Milestones region, or clicking the Add Milestone entry (Static Id = actions) in the Project actions list. Because the Static Id is assigned to the Project Actions region and not individual list entries, the #actions are invoked by adding a milestone, task, or comment. Therefore, the dynamic action uses Condition Type JavaScript Expression to ensure that this dynamic action only fires when returning from the Maintain Milestones page (Page 6), and not from pages 7 or 8.

   Click the True action (currently 'Refresh'), and select Milestones for Region.

3. Add a dynamic action for updates to the tasks.

   In the Dynamic Actions pane, right-click the Dialog Closed folder and select Create Dynamic Action.
   In the Property Editor:

   - Name - enter `Task Updates`
   - Selection Type - jQuery Selector
   - jQuery Selector - enter `#tasks, #add-task, #actions`
   - Condition - JavaScript Expression
   - JavaScript Expression - enter `this.data && this.data.dialogPageId == "7"`

   In the Dynamic Actions pane under the Task Updates action, expand the True folder and select Refresh.
   In the Property Editor, for Region select Tasks.

4. Add a dynamic action for inserts to the comments.

   In the Dynamic Actions pane, right-click the Dialog Closed folder and select Create Dynamic Action.
   In the Property Editor:

   - Name - enter `Comment Inserts`
   - Selection Type - select jQuery Selector
   - jQuery Selector - enter `#add-comment, #actions`
   - Condition - JavaScript Expression
   - JavaScript Expression - enter `this.data && this.data.dialogPageId == "8"`

   Note: The jQuery Selector does not include the Comments region because existing records cannot be updated or deleted.

   In the Dynamic Actions pane under the Comment Inserts action, expand the True folder and select Refresh.
   In the Property Editor, for Region select Comments.

Click the Save and Run Page button on the toolbar. Try updating project details and inserting, updating, and deleting related detail records to see how the Project Details page responds.

## Updating the Calendar Page

In this topic, make the Calendar page easier to use by adding items that users can use to filter the records returned, and add a legend for the colors.
To watch a video of the steps in this section, see this video.

Note: If you have not completed the previous topic, you can import the Demo Projects App Export - Topic 8.sql file into your workspace, and continue working from this topic forward. You can find the export file in the `/files` subdirectory where you unzipped the original file.

1. In the Application Builder, enter `9` in the Page Selector field and click Go to navigate to Page 9 - Calendar.

   In the Property Editor, for Inline copy-paste the following CSS code:

   `.fc-event.fa:before { display: inline-block; float: left; margin-right: 4px; }
   .fc-eventlist-desc { display: block; font-size: 11px; margin-top: 8px; color: #707070; }
   .fc-agendaList-eventDetails { width: 80%; }
   .legend-list {list-style: none; margin: 0;}
   .legend.fc-event { display: inline-block; padding: 0 4px; width: 72px; text-align: center; }`

   Note: THis CSS code is used to style the legend region that will be added to the bottom of the page.

2. Modify the Calendar region.

   In the Rendering Tree under Content Body, expand the Calendar node and select Attributes.

   In the Property Editor:

   - Supplemental Information - enter `&DESCRIPTION.`
   - Multiple Line Events - No
   - CSS Class - CSS_CLASS
   Note: The CSS_CLASS is determined for each record by calling one of three functions in the DEMO_PROJECTS_PKG package: project_color, milestone_color, or task_color. These functions incorporate logic to check task completion and compare various dates. For further details review the DEMO_PROJECTS_PKG package body in SQL Workshop > Object Browser.

3. Add a region to the calendar that contains filter controls to make the page easier for end users to use.

   In the Rendering Tree, right-click the Content Body folder and select Create Region.

   In the Property Editor:

   - Title - enter `Filter Bar`
   - Template - Buttons Container

   In the Rendering Tree, click and hold Filter Bar and drag it above Calendar.

4. Create the filter items.

   In the Gallery, click the Items tab. Locate the Select List item type. Click and hold Select List and drag it to the Filter Bar region and drop it into the Items placeholder.

   In the Property Editor:

   - Name - enter `P9_PROJECT_ID`
   - Label - enter `Project`
   - List of Values > Type - Shared Components
   - List of Values - PROJECTS
   - Display Extra Values - No
   - Null Display Value - enter `- All Projects -`

   In the Grid Layout under ITEMS, right-click P9_PRODUCT_ID. Select Copy To, select Filter Bar, select Items, select P9_PRODUCT_ID, and select After.

   In the Property Editor:

   - Name - enter `P9_MILESTONE_ID`
   - Label - enter `Milestone`
   - List of Values > Type - SQL Query

   - SQL Query - copy-paste the following code into SQL Query:

     `select name d, id r
     from demo_milestones m
     where m.project_id = :P9_PROJECT_ID
     order by m.due_date desc`

   - Null Display Value - enter `- All Milestones -`
   - Cascading LOV Parent Item(s) - P9_PRODUCT_ID

5. Add a Dynamic Action to the P9_PROJECT_ID and P9_MILESTONE_ID items so that the application automatically refreshes the report when either item changes.

   In the Rendering Tree under Content Body, expand the Items folder, right-click P9_PROJECT_ID, and select Create Dynamic Action.

   In the Property Editor:

   - Name - enter `Refresh Calendar`
   - Item(s) - P9_MILESTONE_ID, which will add the selected item after the current entries (P9_PRODUCT_ID).

   Note: This one dynamic action will fire whenever either the Project or the Milestone items are updated. This dynamic action will also be displayed under both items in the Rendering Tree.

   In the Rendering Tree under P9_MILESTONE_ID, expand the Dynamic Actions folder, expand Refresh Calendar, expand the True folder, and select Show.
   In the Property Editor:

   - Action - Refresh
   - Selection Type - Region
   - Region - Calendar

   Note: The True action under P9_PRODUCT_ID is also updated to show Refresh, as it is showing the same dynamic action.

6. Update the calendar region and associate the filter items.

   In the Rendering Tree, select Calendar.
   In the Property Editor:

   - Template - select Blank with Attributes
   - Page Items to Submit - P9_PROJECT_ID and P9_MILESTONE_ID - Ensure your Page Items to Submit field matches the following illustration.

   Warning: If you do not update the region so that it submits the filter items as part of the region definition, then any changed values will not be utilized by the calendar region when it reexecutes the query.

   Note: The SQL Source for this region already includes where conditions for these filter items, such as `t.project_id = nvl(:P9_PROJECT_ID, t.project_id)` within the Tasks sub-query.

   Click the Save and Run Page button. In the Demo Projects runtime, experiment with entering different Projects and Milestones to see how the Calendar changes the displayed values.

7. Add a Legend below the calendar so users know what the different colors mean.

   Navigate back to Page Designer. Right-click the Calendar region and select Create Region.

   In the Property Editor:

   - Title - enter `Legend`
   - Template - Collapsible
   - Text - copy-paste the following: `<ul class="legend-list fc">
     <li><strong class="legend fc-event apex-cal-red">Red</strong>&nbsp;&nbsp;Milestone in the past and tasks ended after due date.</li>
     <li><strong class="legend fc-event apex-cal-orange">Orange</strong>&nbsp;&nbsp;Milestone in the past and <em><strong>incomplete</strong></em> tasks.</li>
     <li><strong class="legend fc-event apex-cal-green">Green</strong>&nbsp;&nbsp;Milestone in the past and all tasks ended before due date.</li>
     <li><strong class="legend fc-event apex-cal-yellow">Yellow</strong>&nbsp;&nbsp;Milestone in the future and Tasks scheduled to finish <u><strong>after</strong></u> due date.</li>
     <li><strong class="legend fc-event apex-cal-blue">Blue</strong>&nbsp;&nbsp;Milestone in the future and Tasks scheduled to finish on or before due date.</li>
     </ul>`

   Note: This HTML code uses the CSS classes added to the page CSS Code to achieve the desired presentation.

   Click the Save and Run Page button and review the calendar.

## Summary

To watch the summary video, see this video.

Note: If you choose, you can import the Demo Projects App Export - Topic 9 (Final).sql file into your workspace, which is the completed application. You can find the export file in the `/files` subdirectory where you unzipped the original file.

In this tutorial, you learned how to:

- Load a script file to create tables and packages and then use the Create Application Wizard to create the first-cut pages.
- Define application-wide Shared Components.
- Add new content to the Home Page.
- Add a card region to change the Team Members display.
- Create a master-detail page for Projects and incorporate children records.
- Convert the detail pages into modal pages and improve the way the items are displayed.
- Add dynamic actions to the master-detail page to reflect changes made when updating detail records.
- Add items and dynamic actions to help drive the Calendar.

#### Resources

- APEX OTN Home Page
- To learn more about Application Express, refer to additional OBEs in the Oracle Learning Library
- Oracle Application Express: Developing Web Applications
- Oracle University

#### Credits

- Lead Curriculum Developer: David Peake
- Other Contributors: Shakeeb Rahman, John Godfrey, Terri Jennings

To navigate this Oracle by Example tutorial, note the following:

Topic List:
  Click a topic to navigate to that section.
Expand All Topics:
  Click the button to show or hide the details for the sections. By default, all topics are collapsed.
Hide All Images:
  Click the button to show or hide the screenshots. By default, all images are displayed.
Print:
  Click the button to print the content. The content that is currently displayed or hidden is printed.

To navigate to a particular section in this tutorial, select the topic from the list.