Friday, May 26, 2017

Inspecting Oracle APEX Packaged Applications (Part 3)

This is the third and last part of a series of blog post. You can access the first and second parts here:

In this last part we are going to create a "Display As" pill button with two options using a List of Values with a custom template to switch between the Cards View created on the previous article and a new Interactive Report.
  1. Create a button under the new Movies Report region:
      • Button Name: ADD_MOVIE
      • Label: Add Movie
      • Button Position: Next
      • Hot: Yes
      • Under Template Options:
      • Spacing Left: Large
      • Action: Redirect to URL
      • URL: #0
  2. Go to Shared Components, List of Values:
      • Click on Create
      • Create List of Values: From Scratch
      • Name: DISPLAY_AS_LOV
      • Type: Static
      • Display Value #1: Cards View
      • Return Value #1: CARDS
      • Display Value #2: Report View
      • Return Value #2: REPORT
      • Create List of Values
  3. Edit the DISPLAY_AS_LOV list of values:
      • Edit the Cards View Display and add the following Template: <span class="t-Icon fa fa-cards" title="#DISPLAY_VALUE#"></span><span class="u-VisuallyHidden">#DISPLAY_VALUE#</span>
      • Edit the Report View and add the following Template: <span class="t-Icon fa fa-table" title="#DISPLAY_VALUE#"></span><span class="u-VisuallyHidden">#DISPLAY_VALUE#</span>
  4. Back on Page 4, create a sub region under the Movies Report region:
      • Title: Display As
      • Template: Blank with attributes
  5. Create a page item under the Display As sub region:
      • Name: P4_DISPLAY_AS
      • Type: Radio Group
      • Number of Columns: 2
      • Template: Hidden
      • Under Template Options:
        • Size: Large
        • Radio Group Display: Display as Pill Button
      • List of Values Type: Shared Component
      • List of Values: DISPLAY_AS_LOV
      • Display Extra Values: No
      • Display Null Value: No
      • Default Type: Static value
      • Static Value: CARDS
      • Escape special characters: No
  6. Create a new region:
      • Name: Report
      • Type: Interactive Report
      • SQL Query:
      • Page Items to Submit: P4_DISPLAY_AS
      • Under Template Options:
      • General: Show Maximize Button
      • Static ID: reportRegion
      • Custom Attributes: style="display: none;"
      • Region Display Selector: No
  7. Create a Dynamic Action:
      • Name: Toggle Display As
      • Event: Change
      • Selection Type: Item(s)
      • Item(s): P4_DISPLAY_AS
      • True Action #1:
        • Action: Execute JavaScript
        • Code:

That's it. Below are two print screens of the final result:



Thursday, May 25, 2017

Inspecting Oracle APEX Packaged Applications (Part 2)

This is the second part of a series of blog post. You can access the first and third parts here:

In this part we are going to implement a classic report using the cards template with a faceted search left side bar. In case you are wondering what a "faceted search" is, here is the definition according to Wikipedia:

Faceted search, also called faceted navigation or faceted browsing, is a technique for accessing information organized according to a faceted classification system, allowing users to explore a collection of information by applying multiple filters. A faceted classification system classifies each information element along multiple explicit dimensions, called facets, enabling the classifications to be accessed and ordered in multiple ways rather than in a single, pre-determined, taxonomic order.

Assuming we are working on Page Number 4.
  1. Modify the page properties:
      • Page Template: Left Side Column
  2. Create a new region:
      • Title: Cards
      • Type: Classic Report
      • SQL Query:
      • Page Items to Submit: P4_SEARCH,P4_ORDER_BY,P4_CATEGORIES,P4_DISPLAY_AS
      • Template: Blank with Attributes
      • Static ID: cardsRegion
      • Under the Report Attributes:
        • Template: Cards
        • Under Template Options:
          • General: Apply Theme Colors
          • Style: Basic
          • Icons: Display Initials
  3. Create a new region:
      • Title: Filter
      • Position: Left Column
      • Under Template Options:
        • Header: Hidden
        • Item Width: Stretch Form Fields
      • Static ID: filterRegion
  4. Create a page item under the Filter region:
      • Name: P4_SEARCH
      • Type: Text Field
      • Template: Hidden
      • Under Template Options:
        • Size: Large
      • Icon CSS Classes: fa-search
      • Value Placeholder: Search Movies
  5. Create another page item under the Filter region:
      • Name: P4_ORDER_BY
      • Type: Select List
      • Label: Order By
      • Template: Optional – Above
      • List of Values Type: Static Values
      • Static Values: STATIC2:Ascending;ASC,Descending;DESC
      • Display Extra Values: No
      • Null Display Value: - Select -
  6. Create another page item under the Filter region:
      • Name: P4_CATEGORIES
      • Type: Checkbox
      • Template: Optional – Above
      • List of Values Type: SQL Query
      • SQL Query: select category d, id r from categories order by category asc
      • Display Extra Values: No
      • Display Null Value: No
      • Pre Text:
  7. Create a region button under the Filter region:
      • Button Name: RESET_FILTERS
      • Label: Reset Filters
      • Button Position: Below Region
      • Button Template: Text with Icon
      • Under Template Options:
        • Type: Warning
        • Width: Stretch
      • Icon CSS Classes: fa-repeat
      • Action: Defined by Dynamic Action
  8. Create a dynamic action:
      • Name: Reset Search Filters
      • Event: Click
      • Selection Type: Button
      • Button: RESET_FILTERS
      • True Action #1:
        • Action: Clear
        • Selection Type: Item(s)
        • Item(s): P4_SEARCH,P4_ORDER_BY,P4_CATEGORIES
  9. Create a dynamic action:
      • Name: Refresh Report on Items Change
      • Event: Change
      • Selection Type: Item(s)
      • Item(s): P4_ORDER_BY,P4_CATEGORIES
      • True Action #1:
        • Action: Refresh
        • Selection Type: Region
        • Region: Cards
  10. Create a dynamic action:
      • Name: Refresh Report on Search Enter
      • Event: Key Down
      • Selection Type: Item(s)
      • Item(s): P4_SEARCH
      • Client-side Condition:
        • Type: JavaScript expression
        • JavaScript Expression: this.browserEvent.which === 13
      • True Action #1:
        • Action: Refresh
        • Selection Type: Region
        • Region: Cards
      • True Action #2:
        • Action: Cancel Event
        • Event: Refresh Report on Search Enter
That's it for this part. On the third and last part with are going to create a "Display As" pill button with two options to switch between the Cards View and an Interactive Report.

Wednesday, May 24, 2017

Inspecting Oracle APEX Packaged Applications (Part 1)

Oracle Application Express (APEX) provides a set of built-in Packaged Applications that you can install and use in your environment. There are two types of packaged applications: (1) Sample Applications that highlight certain APEX capabilities such as Charts, Dynamic Actions, and so on; and, (2) Productivity Applications that are fully supported by Oracle as long as you don't unlock them.

With every new release, the APEX Team put a lot of effort upgrading these applications to take advantage of new features introduced on that release. For that reason, every time Oracle releases a new APEX version, I like to spend some time exploring some of these built-in Packaged Applications looking for design and functional ideas that I can use in my own projects. Once I find something I like, it's very simple to inspect how they've done it (if it's one of the Productivity applications, it must be unlocked first before you can inspect it on the Page Designer).

For this article, I'll show the step-by-step on how to implement one design and functionality that caught my attention in the latest APEX 5.1, located on the Customer Tracker application, Page 59 - Customers.

Whether possible, I tried to use declarative methods, e.g. Dynamic Actions instead of writing pure JavaScript code, this way I keep things as simple as possible. This is the print screen of the page I'm referring to:



It has three features that I liked and I will explain each of them on separate posts due to the length of this implementation:
  1. Fixed Page Title with Icon and a Description.

  1. A Classic Report with Cards Template and a Faceted Search Left Side Bar.

  1. "Display As" Pill Button with Three Options: Cards View, Logo View, Report View.

I setup a demo application with the final results, login using the credentials Demo/Demo. You can also go there and copy the script to generate the sample database objects and data If you want to follow along this demo.

Let's start with the fixed page title with icon and a description.
  1. On your Application, create a new page:
    • Select a Page Type: Blank Page
    • Page Number: 4
    • Name: Movies
    • Breadcrumb: - don't use breadcrumbs on page -
  2. On Page 4, create a new region:
    • Title: Movies Report
    • Text: Track and Manage Movies
    • Position: Breadcrumb Bar
    • Template: Hero
    • Icon CSS Classes: fa-film
    • Region Display Selector: No
Optionally, you could use one of the images located on the following directory inside the APEX installation folder: apex\images\apex_ui\img\icons_src\pkg-apps, e.g.
  • Icon CSS Classes: app-script-planner

For this to work, you'll have to go to your application's Shared Components, User Interface Attributes. Select the Desktop interface, under Cascading Style Sheets add the following File URL:
#IMAGE_PREFIX#pkgapp_ui/css/5.0#MIN#.css

That's it for this part. On the second part with are going to create a classic report using the cards template with a faceted search left side bar.

Monday, May 15, 2017

Working with Multi-Select Items on Oracle APEX

The following post was motivated by a recent thread in the Oracle Application Express Community about how to convert single select to multi select field.

The Problem


When working with items that allow multiple selections in Oracle APEX such as checkbox, list manager, radio group, or shuttle, these values are stored in a single colon-delimited string.

Storing the value in this format into the database does not comply with the database normalization forms and is considered a bad practice.

Below I explain my approach to solve this problem. I created a demo application where you can try the solution and/or copy the script to generate the required database objects in your own environment to follow along with this example. Login using the credentials Demo/Demo.

The Solution


In this example, let’s assume we have the following data model:


Since a movie can have one or more categories, and a category can be assigned to zero or more movies, we will use an associate table (MOVIES_CATEGORIES) to link the values between these two tables (MOVIES and CATEGORIES). Instead of storing CATEGORIES as a column on the MOVIES table.

The first step is to create a "Form on a Table with Report" based on the MOVIES table. Click on "Create Page", select "Form" and "Form on a Table with Report". Modify the following values and leave the rest as default:

Under Report Page

Implementation: Classic
Page Name: Movies Report

Under Data Source

Table / View Name: MOVIES

Under Form Page

Page Mode: Modal Dialog
Page Name: Movies Form
Primary Key Type: Select Primary Key Column(s)
Primary Key Column 1: ID (Number)
Select Columns: NAME (Varchar2)

You will end up with two pages, e.g.:

  • Page 2 – Movies Report
  • Page 3 – Movies Form

On the Movies Report, change the SQL query as follow:

On the Movies Form, go to Processes and select "Process Row of MOVIES". Under Settings, set the "Return Key Into Item" to your page item holding the Primary Key ID, e.g. P3_ID.

Create a new Page Item "P3_CATEGORIES". Make it a Shuttle. Under the List of Values properties, specify the following:
Type: SQL Query
SQL Query: select category d, id r from categories order by category

Create a new process "Process Categories", right after "Process Row of MOVIES" and before "reset page" with the following PL/SQL Code:

Finally, create a fetch process "Fetch Categories" on the Pre-Rendering section, right after "Fetch Row from MOVIES" to retrieve the category information for existing records. This process should have a server-side condition of "Item is NOT NULL" = P3_ID and the following PL/SQL Code:

That's it!

Final Words


This demo was designed with Oracle Database 11g and APEX 5.0 in mind. In Oracle Database 12c, you can take advantage of Identity Columns when creating new tables. Also, the latest APEX 5.1 comes with a new package APEX_STRING that includes two functions (SPLIT and JOIN) that can be used instead of the package APEX_UTIL and the functions STRING_TO_TABLE and TABLE_TO_STRING.

Regardless of the method you use, it’s important to always keep your database normalized to reduce data redundancy and improve data integrity.