advanced application express

65
Advanced Application Express Tips and Techniques By Bradley D. Brown http://bradleydbrown.blogspot.com Chairman and Chief Architect, TUSC www.tusc.com/briefing

Upload: al-wall

Post on 06-Mar-2015

172 views

Category:

Documents


7 download

TRANSCRIPT

Page 1: Advanced Application Express

Advanced Application Express Tips and Techniques

By Bradley D. Brown http://bradleydbrown.blogspot.com

Chairman and Chief Architect, TUSC

www.tusc.com/briefing

Page 2: Advanced Application Express

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.

Page 3: Advanced Application Express

Topics

HTMLFavorite IconPop-ups & pass-backsTool tipsAnchors

ApexPage 0Help text / pageCustom login pageScrolling textDocument ManagementOutlook IntegrationEmail

PL/SQLComplex searchesFunction-based queriesBackground jobs

JavaScriptSetting focusAJAXNetflix FlyupsGoogle Maps

Page 4: Advanced Application Express

Most everything is in the sample app Download from www.tusc.com

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

Page 5: Advanced Application Express

HTML Tips

Page 6: Advanced Application Express

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" />

Page 7: Advanced Application Express

Pop-up windows

Pop-up WindowTarget=“_blank” in “Link Attributes”

Page 8: Advanced Application Express

The Oracle Experts

Custom Pop Ups Returning Multiple Values

Javascript passes the values back

Page 9: Advanced Application Express

“Bubble-Help,” “Tool tip” or hints

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

Page 10: Advanced Application Express

Anchors

Anchors can provide direct links to places on a pageSet 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>

Page 11: Advanced Application Express

Long Page in App

Page 12: Advanced Application Express

Application Express Tips

Page 13: Advanced Application Express

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.

Page 14: Advanced Application Express

Help text

Page level help textCreate a table HELP_TEXT with help for each page

• Spell check your help textCreate 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 textOpen any page itemEnter help text for the itemSpell check your help text

Page 15: Advanced Application Express

Highlight Current

Note highlighting of current rowMaster, master, detail

Page 16: Advanced Application Express

Key Elements

SQL Report RegionsLink to select current master recordDetail SQL Query limited by “selected”master row

Hidden Items to implement details

Custom Templates to highlight current row

Variation on alternating color report templatePL/SQL expression condition for “selected” row

Page 17: Advanced Application Express

The Oracle Experts

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

Page 18: Advanced Application Express

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

Page 19: Advanced Application Express

Custom Logon Page

You can create your own logon page for any application

You can use Oracle Application Express’s 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

Page 20: Advanced Application Express

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 documentsCreate table person_document(PERSON_ID number,DOCUMENT_ID numberDESCRIPTION varchar2(4000),DOCUMENT varchar2(4000))

Page 21: Advanced Application Express

Show a link to the document (if there is one – otherwise, create new)

Link is to p?n=document_numberselect 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_DOCUMENTwhere person_id = :p1_id

Page 22: Advanced Application Express

Best Practices and Indexing Documents

If you…Might want to port your applicationHave many documentsDesire to index document content

Create your own document table

Create table resumes as select * from apex_application_filesWhere…

Easier to export an application (and data) – otherwise, it’s in Apex schema

Page 23: Advanced Application Express

Mass Upload of Documents

Create placeholderCREATE TABLE

TEMP_RESUMES

(NAME VARCHAR2(90),

BLOB_CONTENT BLOB)

Start with directoryDir /b >resume.ctl

Add SQL*Loader text above list

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…

Page 24: Advanced Application Express

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

Page 25: Advanced Application Express

Loading Documents

Need a process to move document after upload

See http://download.oracle.com/docs/cd/B32472_01/doc/appdev.300/b32469/up_dn_files.htm

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;

Page 26: Advanced Application Express

Need Procedure to Download DocumentCREATE 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;

Page 27: Advanced Application Express

Indexing the Documents

Need an Oracle Text indexcreate index doc_ctxidx onresumes(blob_content)indextype is ctxsys.contextparameters ('datastore CTXSYS.DEFAULT_DATASTORE')

You must re-index regularlybegin ctx_ddl.sync_index('doc_ctxidx','2M'); end;

Page 28: Advanced Application Express

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_docsfrom resumes r, person_document pdwhere contains (BLOB_CONTENT, :p14_search) > 1and r.id = pd.document(+)

Page 29: Advanced Application Express

The Results

Page 30: Advanced Application Express

Outlook (or other) Integration

Add to my CalendarIndustry standard (RFC 2445) ICS format

• Mac/Apple iCalendar, Mozilla Calendar, Outlook, etc.

Add contactIndustry standard contact VCF format

Email Links

Mass EmailCampaignsRemindersWorkflow

Page 31: Advanced Application Express

Email links

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

LinkReport attributes, pick attribute, linkLink Text = #MEMBER#Target = URLURL = mailto:#EMAIL_ADDRESS#

Page 32: Advanced Application Express

Sending mass emails

I like my own send_email procedure (email me and I’ll 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')

Page 33: Advanced Application Express

“Add to my calendar” feature

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

Branch to a PL/SQL page

Mime-type is key

Page 34: Advanced Application Express

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('METHOD:PUBLISH');

htp.print('BEGIN:VEVENT');

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');

htp.print('END:VALARM');

htp.print('END:VEVENT');

htp.print('END:VCALENDAR');

end;

Page 35: Advanced Application Express

“Add Contact” feature

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

Similar to ICS

Branch to a PL/SQL page

Mime-type is key

Page 36: Advanced Application Express

The guts of the contactsDeclare

cursor user_cur is

select user_name, expires_on, company, phone, …

from demo_users

where user_id = :p14_user_id;

Begin

-- Get the user data

for user_rec in user_cur loop

htp.init; -- Wipe out the buffer

owa_util.MIME_HEADER('text/x-vcard; method=request');

-- Get the user information

htp.print('BEGIN:VCARD');

htp.print('VERSION:3.0');

htp.print('N:' || user_rec.user_name || ';;');

htp.print('ADR;HOME:;;');

htp.print('EMAIL;PREF;INTERNET:' || user_rec.email_address);

htp.print('NOTE;ENCODING=QUOTED-PRINTABLE: Expires on ' || user_rec.expires_on || ' Admin user? ' || user_rec.admin_user || ' Quota: ' || user_rec.quota);

htp.print('REV:20050707T234724');

htp.print('END:VCARD');

end loop;

end;

Page 37: Advanced Application Express

PL/SQL tips

Page 38: Advanced Application Express

Complex searches

Multiple search fieldsCan’t dynamically build the where clauseMust use instr or like statementsIf large dataset, recommend:

• Indexes on columns• Use like :p1_search || ‘%’• Don’t use like ‘%’ || :p1_search || ‘%’ or instr• Use separate pages / queries / regions for each field queried• Can use Oracle Text (i.e. contains)

Page 39: Advanced Application Express

Function-based (Complex) Queries

Let’s say you want to knowThe first and last date you received an RSVPThe number of people who RSVPed each day between

No easy way to execute this query

Build a function-based queryFunctionTable and column data typesView based on casted function

Page 40: Advanced Application Express

The Function RSVP_FUNCTION

CREATE OR REPLACE FUNCTION rsvp_function (in_event_no number)

RETURN rsvp_table

PIPELINED IS

out_rec RSVP_COLUMNS := RSVP_COLUMNS(NULL,NULL,NULL,NULL,NUL L);

TableSet RSVP_TABLE;

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 rsvp

where event_no = in_event_no;

cursor count_invitees_cur is

select count(*) count

from rsvp

where event_no = in_event_no;

cursor count_as_of_cur (in_date date) is

select sum(decode(yn,'Y',1,0)) y,

sum(decode(yn,'N',1,0)) n

from rsvp

where event_no = in_event_no

and rsvp_date <= in_date + 1;

total number := 0;

Page 41: Advanced Application Express

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 min_max_rec in min_max_cur loop

FOR i IN 1 .. min_max_rec.days+1 LOOP

out_rec.event_no := in_event_no;

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

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;

PIPE ROW(out_rec);

END LOOP;

END LOOP;

RETURN;

END;

Page 42: Advanced Application Express

The Data Types RSVP_COLUMNS and RSVP_TABLE

ColumnsCREATE OR REPLACETYPE rsvp_Columns AS OBJECT( event_no number,

rsvp_date date,y number,n number,w number);

TableCREATE OR REPLACETYPE RSVP_Table AS TABLE OF YPO.RSVP_COLUMNS

Page 43: Advanced Application Express

The View / Query

3 series (yes, no, waiting)select rsvp_date, yfrom table(cast(rsvp_function(:P3_IN_EVENT_NO)

as rsvp_Table))select rsvp_date, nfrom table(cast(rsvp_function(:P3_IN_EVENT_NO)

as rsvp_Table))select rsvp_date, wfrom table(cast(rsvp_function(:P3_IN_EVENT_NO)

as rsvp_Table))

Page 44: Advanced Application Express

The Results

Page 45: Advanced Application Express

Apex Add-ons (APIs)

Apex_plssql_job

Apex_collection

Apex_Ldap

Apex_Mail

Apex_Util

Page 46: Advanced Application Express

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

Page 47: Advanced Application Express

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_STATUSUpdates the status of the currently running job. Most effective when called from the submitted PL/SQL.

TIME_ELAPSEDDetermines how much time has elapsed since the job was submitted.

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

PURGE_PROCESSCleans 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.

Page 48: Advanced Application Express

JavaScript, AJAX, etc.

Page 49: Advanced Application Express

JavaScript

JavaScript provides client-side power

Good doc to work from: http://www.oracle.com/technology/products/database/htmldb/howtos/htmldb_javascript_howto2.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

Page 50: Advanced Application Express

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>

Page 51: Advanced Application Express

AJAX and Other DHTML Tricks

AJAXAsynchronous JavaScript and XML

RestHttp get commandsReturns XML

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

Page 52: Advanced Application Express

The Oracle Experts

Using AJAX

Asynchronous Java Script and XMLNot new technology, just combination of existingInteracts with the server without refreshing the page

Used a lot in APEX SQL workshop

APEX makes implementation simple

Refresh a variety of objectsSingle display itemMulti-value things such as select listEntire report regions

Page 53: Advanced Application Express

The Oracle Experts

Using AJAX

Select a valuePopulates Job

Select a departmentPopulates select list

Page 54: Advanced Application Express

The Oracle Experts

AJAX Key Elements

Item with onChange event

JavaScript function called by onChangeCalls Process using htmldb_GetUses results

Application Level ProcessOn Demandreturns value or XML document

Application Level Items, used in process

Page Zero

Page 55: Advanced Application Express

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

Page 56: Advanced Application Express

Netflix Flyups

Netflix uses AJAX to retrieve its flyups.

For a great thread on how to implement this, see http://forums.oracle.com/forums/thread.jspa?threadID=318874&tstart=0

Page 57: Advanced Application Express

Google Map Integration

Easy integration

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

Page 58: Advanced Application Express

Summary

Oracle Application Express is powerful

Download the Sample AppReal examples in thereLots of great code

Forum is helpful and well monitored

Watch for Web 2.0 additions

Page 59: Advanced Application Express

Where to Get More Information?

Numerous presentations on the TUSC siteFull Day TutorialsNumerous 1-3 hour sessionsLocal Oracle Users Groups

TUSC’s Training Center

Oracle Application Express Handbookby Larry Linnemeyer and Bradley D. BrownDecember 2005

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

Page 60: Advanced Application Express

Want more Information?

Call or email [email protected]

Call or email [email protected]

Visit our sitehttp://www.tusc.comRegister for our newsletter

Page 61: Advanced Application Express

Questions?

Page 62: Advanced Application Express

Brad’s 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

Page 63: Advanced Application Express

Special Thanks

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

Page 64: Advanced Application Express

Other TUSC Presentations and Papers

TuningDatabaseSQLApplications

Security

Migrations

Discoverer & BI

Built-in Packages

PL/SQL

New Features

Forms, Reports

Designer

Team Management

Uncommon Leaders

Workflow

DBA topics

Page 65: Advanced Application Express

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.