0% found this document useful (0 votes)
416 views65 pages

Advanced Application Express

Oracle application express is a powerful and comprehensive tool. Advanced tips and techniques will be covered in this presentation. Topics include: pop-up windows, complex searches, document management, indexing and searching, "tool tip" or hints, email links, page 0, help text, background jobs, "add to my calendar" feature, saving contacts, sending mass emails, and more.

Uploaded by

Al Wall
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
416 views65 pages

Advanced Application Express

Oracle application express is a powerful and comprehensive tool. Advanced tips and techniques will be covered in this presentation. Topics include: pop-up windows, complex searches, document management, indexing and searching, "tool tip" or hints, email links, page 0, help text, background jobs, "add to my calendar" feature, saving contacts, sending mass emails, and more.

Uploaded by

Al Wall
Copyright
© Attribution Non-Commercial (BY-NC)
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 65

Advanced Application Express Tips and Techniques

www.tusc.com/briefing
By Bradley D. Brown http://bradleydbrown.blogspot.com Chairman and Chief Architect, TUSC

Abstract
Oracle Application Express is a powerful and comprehensive tool. Numerous advanced tips and techniques will be covered in this presentation. These topics include: pop-up windows, complex searches, document management, indexing and searching, tool tip or hints, email links, page 0, help text, background jobs, add to my calendar feature, saving contacts, sending mass emails, and more.

Topics

HTML
Favorite Icon Pop-ups & pass-backs Tool tips Anchors

PL/SQL
Complex searches Function-based queries Background jobs

JavaScript
Setting focus AJAX Netflix Flyups Google Maps

Apex
Page 0 Help text / page Custom login page Scrolling text Document Management Outlook Integration Email

Most everything is in the sample app


Download from www.tusc.com http://www.tusc.com/oracle/technology/briefing_menu.html

HTML Tips

Favorite Icon

Place favicon2.ico file in


$ORACLE_HOME\Apache\Apache\htdocs

In Page template
<link rel="shortcut icon" href="/favicon2.ico" type="image/x-icon" />

Pop-up windows

Pop-up Window
Target=_blank in Link Attributes

Custom Pop Ups Returning Multiple Values

Javascript passes the values back

The Oracle Experts

Bubble-Help, Tool tip or hints

Title attribute in Link Attributes Title="#COMMENTS#"

Anchors

Anchors can provide direct links to places on a page


Set an anchor anywhere on the page
<a name="Location">

Reference an anchor anywhere


<a href="#Location"> jump to location</a>

Best practice in page template is to include at the top of the body section
<a name="Top">

This way you can place a return to top link anywhere on the page
<a href=#Top><img src="/i/themes/theme_8/blue_arrow_up.gif" alt=Top of page" title=Top of page"></a>

Long Page in App

Application Express Tips

Page 0

Anything placed on Page 0 will appear on every page by default Can use Conditional display to turn region on or off for specific pages, users, etc.

Help text

Page level help text


Create a table HELP_TEXT with help for each page
Spell check your help text

Create a new blank page


Add a new region to the page Help Text Could also have conditional HTML sections

Add an item to your navigation bar (i.e. Help)


Branch to your help text page (i.e. 10) Pass &APP_PAGE_ID to P10_PAGE_ID

Item level help text


Open any page item Enter help text for the item Spell check your help text

Highlight Current

Note highlighting of current row


Master, master, detail

Key Elements

SQL Report Regions


Link to select current master record Detail SQL Query limited by selected master row

Hidden Items to implement details Custom Templates to highlight current row


Variation on alternating color report template PL/SQL expression condition for selected row

SQL Report Regions


Decode primary key against hidden item for selected master row
select decode(customer_id, :P1_CUST_ID, 'CURRENT', 'Select') sel_label, customer_id, cust_last_name||', '|| cust_first_name as cust_name, cust_street_address1||'<br>'|| Cust_city||', '|| cust_state|| ' '||cust_postal_code address from demo_customers
The Oracle Experts

Custom Template

Hidden item used in PL/SQL expression to determine Selected row Based off of current themes alternating row report template
The Oracle Experts

Custom Logon Page

You can create your own logon page for any application You can use Oracle Application Expresss built-in authentication or you can use any existing scheme you have Good document on creating a custom logon page:
http://forums.oracle.com/forums/thread.jsp?forum=137&thread =220034

Document management, indexing and searching


Documents will be stored in Oracle Application Express schema See Sample Application for great code examples Create a table to store the link to the documents
Create table person_document (PERSON_ID number, DOCUMENT_ID number DESCRIPTION varchar2(4000), DOCUMENT varchar2(4000))

Show a link to the document


(if there is one otherwise, create new)

Link is to p?n=document_number
select DESCRIPTION, decode(document, null, '<a href="f?p=' || :app_id || ':11:::::p11_person_id,p11_document_id:' || person_id || ',' || document_id || '">Upload Supporting Document</a>', '<a href="p?n=' || document || '">Download Document</a>') document from PERSON_DOCUMENT where person_id = :p1_id

Best Practices and Indexing Documents

If you
Might want to port your application Have many documents Desire to index document content

Create your own document table


Create table resumes as select * from apex_application_files Where

Easier to export an application (and data) otherwise, its in Apex schema

Mass Upload of Documents

Create placeholder
CREATE TABLE TEMP_RESUMES (NAME VARCHAR2(90), BLOB_CONTENT BLOB)

Sqlldr user/pass control=docs.ctl load data infile * into table resumes fields terminated by ', (file_name char(50), blob_content lobfile(file_name) terminated by eof) BEGINDATA a.doc b.doc

Start with directory


Dir /b >resume.ctl

Add SQL*Loader text above list

Load up Resumes from Temp_Resumes


INSERT INTO RESUMES SELECT ROWNUM ID, 0 flow_id, NAME NAME, NAME filename, NULL title, CASE WHEN SUBSTR(NAME,LENGTH(NAME)3+1) = 'doc' THEN 'application/msword WHEN SUBSTR(NAME,LENGTH(NAME)-3+1) = 'pdf' THEN 'application/pdf WHEN SUBSTR(NAME,LENGTH(NAME)-3+1) IN ('csv','xls') THEN 'application/vnd.ms-excel WHEN SUBSTR(NAME,LENGTH(NAME)-3+1) = 'gif' THEN 'image/gif WHEN SUBSTR(NAME,LENGTH(NAME)-3+1) = 'png' THEN 'image/png WHEN SUBSTR(NAME,LENGTH(NAME)-3+1) = 'jpg' THEN 'image/pjpeg ELSE 'application/text END mime_type,

LENGTH(blob_content) doc_size, 'ascii' dad_charset, '[email protected]' created_by, SYSDATE created_on, '[email protected]' updated_by, SYSDATE updated_on, SYSDATE last_updated, 'BLOB' content_type, blob_content, NULL LANGUAGE, 'Loaded by BDB in bulk' description, NULL file_type, NULL file_charset FROM TEMP_RESUMES

Loading Documents
INSERT INTO resumes(id,flow_id,name,filename,mime_type ,doc_size,dad_charset,created_by,created_o n,updated_by,updated_on,last_updated,cont ent_type,blob_content,description) SELECT id,flow_id,name,filename,mime_type,doc_size ,dad_charset,created_by,created_on,update d_by,updated_on,last_updated,content_type, blob_content,:P20_DESCRIPTION FROM APEX_APPLICATION_FILES WHERE name = :P1_FILE_NAME; DELETE from APEX_APPLICATION_FILES WHERE name = :P1_FILE_NAME;

Need a process to move document after upload See http://download.oracl e.com/docs/cd/B324 72_01/doc/appdev.3 00/b32469/up_dn_fil es.htm

Need Procedure to Download Document


CREATE OR REPLACE PROCEDURE download_my_file(p_file in number) AS v_mime VARCHAR2(48); v_length NUMBER; v_file_name VARCHAR2(2000); Lob_loc BLOB; BEGIN SELECT MIME_TYPE, BLOB_CONTENT, name, doc_size INTO v_mime,lob_loc,v_file_name,v_length FROM resumes WHERE id = p_file; -- set up HTTP header owa_util.mime_header( nvl(v_mime,'application/octet'), FALSE ); -- set the size so the browser knows how much to download htp.p('Content-length: ' || v_length); -- the filename will be used by the browser if the users does a save as htp.p('Content-Disposition: attachment; filename="'||replace(replace(substr(v_file_name,instr(v_file_name,'/')+1),chr(10),null),chr(13),null)|| '"'); -- close the headers owa_util.http_header_close; -- download the BLOB wpg_docload.download_file( Lob_loc ); end download_my_file;

Indexing the Documents

Need an Oracle Text index


create index doc_ctxidx on resumes(blob_content) indextype is ctxsys.context parameters ('datastore CTXSYS.DEFAULT_DATASTORE')

You must re-index regularly


begin ctx_ddl.sync_index('doc_ctxidx','2M'); end;

Searching the Index


Create a search field on the page (e.g. p14_search) Query, joining document to a person
select r.ID, pd.person_ID person_id, NAME, FILENAME, TITLE, MIME_TYPE, DOC_SIZE, CREATED_BY, CREATED_ON, UPDATED_BY, UPDATED_ON, LAST_UPDATED, CONTENT_TYPE, LANGUAGE, r.DESCRIPTION, pd.DESCRIPTION person_description, FILE_TYPE, FILE_CHARSET, get_person_attributes(pd.person_id, chr(13)) person_attribute_info, get_person_docs(pd.person_id, '<br>') all_docs from resumes r, person_document pd where contains (BLOB_CONTENT, :p14_search) > 1 and r.id = pd.document(+)

The Results

Outlook (or other) Integration

Add to my Calendar
Industry standard (RFC 2445) ICS format
Mac/Apple iCalendar, Mozilla Calendar, Outlook, etc.

Email Links Mass Email


Campaigns Reminders Workflow

Add contact
Industry standard contact VCF format

Email links

Select statement
select '<a href="mailto:' || me.EMAIL_ADDRESS || '">' || first_name || ' ' || last_name || '</a>' Member

Link
Report attributes, pick attribute, link Link Text = #MEMBER# Target = URL URL = mailto:#EMAIL_ADDRESS#

Sending mass emails


I like my own send_email procedure (email me and Ill send it)
CREATE OR REPLACE PROCEDURE Send_Email (in_mail_server VARCHAR2 DEFAULT 'exchange.tusc.com', in_sender_email VARCHAR2 DEFAULT '[email protected]', in_sender_name VARCHAR2 DEFAULT 'My Full Name', in_recipient_email VARCHAR2 DEFAULT '[email protected]', in_recipient_name VARCHAR2 DEFAULT 'Your Full Name', in_cc_email VARCHAR2 DEFAULT '[email protected]', in_cc_name VARCHAR2 DEFAULT 'My Full Name', in_html_flg VARCHAR2 DEFAULT 'N', in_subject VARCHAR2 DEFAULT 'No Subject was Provided', in_importance VARCHAR2 DEFAULT 'Normal', in_body VARCHAR2 DEFAULT 'No Body for this Email')

Add to my calendar feature


Industry standard (RFC 2445) ICS format
Mac/Apple iCalendar, Mozilla Calendar, Outlook, etc.

Branch to a PL/SQL page Mime-type is key

The Guts of the Code


htp.init; -- Wipe out the buffer owa_util.MIME_HEADER('text/cal endar; method=request'); -- Get the event information htp.print('BEGIN:VCALENDAR'); htp.print('PRODID:-//Microsoft Corporation//Outlook 9.0 MIMEDIR//EN'); htp.print('VERSION:2.0'); htp.print('END:VALARM'); htp.print('METHOD:PUBLISH'); htp.print('END:VEVENT'); htp.print('BEGIN:VEVENT'); htp.print('END:VCALENDAR'); end; htp.print('ORGANIZER:MAILTO:br [email protected]'); htp.print('DTSTART;TZNAME=MST: ' || to_char(nvl(to_date(v('P12_ expires_ON'),'mm/dd/yyyy'), l_expires_on), 'yyyymmdd') || 'T080000'); htp.print('DESCRIPTION:Reminde r for account expiring');

Add Contact feature


Industry standard VCF format
Mac/Apple iCalendar, Mozilla Calendar, Outlook, etc.

Similar to ICS Branch to a PL/SQL page Mime-type is key

The guts of the contacts


Declare cursor user_cur is select user_name, expires_on, company, phone, from where demo_users user_id = :p14_user_id; -- Get the user information htp.print('BEGIN:VCARD'); htp.print('VERSION:3.0'); htp.print('N:' || user_rec.user_name || ';;'); htp.print('ADR;HOME:;;'); Begin -- Get the user data for user_rec in user_cur loop htp.print('EMAIL;PREF;INTERNET:' || user_rec.email_address); htp.print('NOTE;ENCODING=QUOTEDPRINTABLE: Expires on ' || user_rec.expires_on || ' Admin user? ' || user_rec.admin_user || ' Quota: ' || user_rec.quota); htp.print('REV:20050707T234724'); htp.print('END:VCARD');

htp.init; -- Wipe out the buffer owa_util.MIME_HEADER('text/xvcard; method=request');

end loop;

end;

PL/SQL tips

Complex searches

Multiple search fields


Cant dynamically build the where clause Must use instr or like statements If large dataset, recommend:
Indexes on columns Use like :p1_search || % Dont use like % || :p1_search || % or instr Use separate pages / queries / regions for each field queried Can use Oracle Text (i.e. contains)

Function-based (Complex) Queries

Lets say you want to know


The first and last date you received an RSVP The number of people who RSVPed each day between

No easy way to execute this query Build a function-based query


Function Table and column data types View based on casted function

The Function
RSVP_FUNCTION
CREATE OR REPLACE FUNCTION rsvp_function (in_event_no number) RETURN rsvp_table where PIPELINED IS out_rec RSVP_COLUMNS := RSVP_COLUMNS(NULL,NULL,NULL,NULL,NUL L); TableSet RSVP_TABLE; from where and total cursor count_as_of_cur (in_date date) is select sum(decode(yn,'Y',1,0)) y, sum(decode(yn,'N',1,0)) n rsvp event_no = in_event_no rsvp_date <= in_date + 1; number := 0; event_no = in_event_no; select count(*) count from rsvp

cursor min_max_cur is select min(trunc(rsvp_date)) min_date, max(trunc(rsvp_date)) max_date, max(trunc(rsvp_date))min(trunc(rsvp_date)) days from where rsvp event_no = in_event_no;

cursor count_invitees_cur is

RSVP_FUNCTION
BEGIN -- Figure out the total count of invited people for count_invitees_rec in count_invitees_cur loop total := count_invitees_rec.count; end loop; for count_as_of_rec in count_as_of_cur(out_rec.rsvp_date) loop out_rec.y count_as_of_rec.y; out_rec.n count_as_of_rec.n; out_rec.w total - count_as_of_rec.y count_as_of_rec.n; end loop; for min_max_rec in min_max_cur loop FOR i IN 1 .. min_max_rec.days+1 LOOP PIPE ROW(out_rec); END LOOP; out_rec.event_no := in_event_no; END LOOP; RETURN; END; := := :=

out_rec.rsvp_date := min_max_rec.min_date + i - 1;

The Data Types


RSVP_COLUMNS and RSVP_TABLE

Columns
CREATE OR REPLACE TYPE rsvp_Columns AS OBJECT ( event_no number, rsvp_date date, y number, n number, w number);

Table
CREATE OR REPLACE TYPE RSVP_Table AS TABLE OF YPO.RSVP_COLUMNS

The View / Query

3 series (yes, no, waiting)


select rsvp_date, y from table(cast(rsvp_function(:P3_IN_EVENT_NO) as rsvp_Table)) select rsvp_date, n from table(cast(rsvp_function(:P3_IN_EVENT_NO) as rsvp_Table)) select rsvp_date, w from table(cast(rsvp_function(:P3_IN_EVENT_NO) as rsvp_Table))

The Results

Apex Add-ons (APIs)

Apex_plssql_job Apex_collection Apex_Ldap Apex_Mail Apex_Util

Background jobs

apex_plsql_job is a wrapper written around dbms_job APEX_PLSQL_JOBS is a table containing the job information for those submitted Very helpful for those hourly, daily, weekly, etc. processes

Functions and Procedures


SUBMIT_PROCESS (function)
Submits background PL/SQL, returns a unique job number. Job number is a reference point for other procedures and functions in this package.

UPDATE_JOB_STATUS
Updates the status of the currently running job. Most effective when called from the submitted PL/SQL.

TIME_ELAPSED
Determines how much time has elapsed since the job was submitted.

JOBS_ARE_ENABLED
Determines whether or not the database is currently in a mode which supports submitting jobs to the APEX_PLSQL_JOB package.

PURGE_PROCESS
Cleans up submitted jobs. Submitted jobs stay in the APEX_PLSQL_JOBS view until either Oracle Oracle Application Express cleans out those records, or you call PURGE_PROCESS to manually remove them.

JavaScript, AJAX, etc.

JavaScript

JavaScript provides clientside power Good doc to work from: http://www.oracle.com/technol ogy/products/database/htmld b/howtos/htmldb_javascript_h owto2.html#ref

Where to Place JavaScript Functions Calling JavaScript from a Button Add Client-Side JavaScript Validations Enable / Disable Form Elements Change the Value of Form Elements

Apex JavaScript - Setting Focus

Check out /i/javascript/apex_html_elements.js for a complete list of already developed JavaScript (charCount, setStyle, confirmDelete, hideShow, GetCookie, SetCookie, html_PopUp, etc) To focus on an item, make sure to change focus property in page properties first_field is a build-in function:
<script type="text/javascript"> first_field('P20_FROM_DATE'); </script>

AJAX and Other DHTML Tricks

AJAX
Asynchronous JavaScript and XML

Rest
Http get commands Returns XML

Excellent examples
http://apex.oracle.com/pls/otn/f?p =11933

Using AJAX
Asynchronous Java Script and XML
Not new technology, just combination of existing Interacts with the server without refreshing the page

Used a lot in APEX SQL workshop APEX makes implementation simple Refresh a variety of objects
Single display item Multi-value things such as select list Entire report regions

The Oracle Experts

Using AJAX

Select a value Populates Job

Select a department Populates select list

The Oracle Experts

AJAX Key Elements


Item with onChange event JavaScript function called by onChange
Calls Process using htmldb_Get Uses results

Application Level Process


On Demand returns value or XML document

Application Level Items, used in process Page Zero


The Oracle Experts

AJAX using a Query Process


Two page items Select list with onChange trigger Text field to accept value

Select list calls JavaScript function when its value is changed


The Oracle Experts

Netflix Flyups
Netflix uses AJAX to retrieve its flyups. For a great thread on how to implement this, see http://forums.oracle.com/fo rums/thread.jspa?threadID =318874&tstart=0

Google Map Integration

Easy integration http://www.google.com/apis/maps/documentation/

Summary

Oracle Application Express is powerful Download the Sample App


Real examples in there Lots of great code

Forum is helpful and well monitored Watch for Web 2.0 additions

Where to Get More Information?

Numerous presentations on the TUSC site


Full Day Tutorials Numerous 1-3 hour sessions Local Oracle Users Groups

TUSCs Training Center Oracle Application Express Handbook


by Larry Linnemeyer and Bradley D. Brown December 2005

Oracle Application Express Forum, Oracle Application Express Studio, etc.

Want more Information?

Call or email TUSC


800-755-TUSC [email protected]

Call or email Brad


303-985-2213 [email protected]

Visit our site


http://www.tusc.com Register for our newsletter

Questions?

Brads Papers and Presentations


Java-based Oracle Web Development Java Server Pages JavaMail Java for the PL/SQL Developer Web Cache achieving 150 the performance 9iAS Installation, Configuration, and Tuning Wireless Practical Portal Practices Implementing JSP in Portal UltraSearch Search Engines Utl_smtp and Utl_http iFS JavaScript Top DBA scripts for Web Developers Security

Special Thanks

Larry Linnemeyer for his advanced topics and all of his work on the Oracle Application Express book

Other TUSC Presentations and Papers


Tuning
Database SQL Applications

PL/SQL New Features Forms, Reports Designer Team Management Uncommon Leaders Workflow DBA topics

Security Migrations Discoverer & BI Built-in Packages

Copyright Information
Neither TUSC nor the author guarantee this document to be error-free. Please provide comments/questions to [email protected]. TUSC 2007. This document cannot be reproduced without expressed written consent from an officer of TUSC.

You might also like