Thursday, March 6, 2008

Implementing Ext Dates in Oracle Apex

"Anonymous" asked me for more explanation on how I implemented the Ext date-picker in Oracle Apex, as seen in my demo.

Look, I don't mind answering, but please put a name on your feedback - anonymous is just rude.

Here's the plain English explanation:

We are converting a simple html input item into a Ext date-picker, which just happens to be associated with a date field in the database.

To make it easy to identify which input items to convert we assign a class of "date-picker" to the item. The code to do the conversion is shown in my demo.

The only other thing to worry about is making sure the date format of the input item matches the database date format.

Everything else you want to know can be learnt by reading the documentation.
Here are the steps:

1. Set the database date format in Apex
Lets use a mask of DD-Mon-YYYY as there's no confusion internationally.
In Apex 3.1 do this directly in Home>Application Builder>Application 200801>Shared Components>Edit Globalization Attributes.
In earlier versions, you need to create application processes for "On Load Before Header" and "On Submit After Page Submission - Before Computations and Validations" with the following code
execute immediate 'alter session set nls_date_format=''DD-Mon-YYYY''';

2. Create the date item
In Apex create a form on a table containing dates.
Make sure the item type of the date field to display as "Text Field" and not "Date Picker".
Finally add class="date-picker" in the Form Elements Attributes.

3. Add the javascript
Include the Ext javascript files in your page template, cut and paste the javascript code from the demo into your page or page template.

If you run that it all works beautifully.
You'll notice the code allows for alternative data entry format masks e.g "dd/mm/yyyy" and partial formats e.g. "dd/mm".
Thats because the alternate formats are easier for keyboard operators.
See ExtJS documentation on date formats available.

4. Optional step
You may have noticed on my demo I use "DD-MON-YYYY", not "DD-Mon-YYYY" as shown in this blog.
To achieve this I set the database format easily enough, but then had to override the default Ext date names with the following line of javascript in my application javascript file:
Date.monthNames =["JANUARY","FEBRUARY","MARCH","APRIL","MAY","JUNE","JULY","AUGUST","SEPTEMBER","OCTOBER","NOVEMBER","DECEMBER"];

This is the Ext way on internationalizing dates, so it's not a hack.
What it does is force the javascript date format "d-M-Y" to return the month in uppercase.

Anyway hope this helps.

Mark

12 comments:

Timo Annemüller said...

Hi Mark, thanks for the implementing instruction. I´m using the ext version 2.0.2. And there you will get an error when using "df.applyTo(el);". There you need to write "df.applyToMarkup(el);" in the javascript.

Mark Lancaster said...

Hi Timo

Thanks for bringing the error to my attention - I'd updated the code, but not the example script.

Mark

Timo Annemüller said...

Hi Mark,
i´ve played a little bit with your commenting system, but i can´t understand the way how you write the information into the database table. Is it possible for you to write a little explanation about the way. Thank you very much! Timo

mj said...

hey ya!

first of all, apologies if i used this avenue for a question unrelated to the post (can't find any other way to contact you).. sorry!

Ive been using forms/reports all my professional life (5 yrs) and i wanted to branch out to other things (extinct dinosaurs come to mind). I've come across APEX bec of this and wanted to know how:

I can create a website (or a blog) using XE + Apex? Is this possible?

Your blog came up when i asked mr. google and i was wondering if you could 'point' me to the right direction...

apologies again and i hope you reveal your email in your about page =)

Mark Lancaster said...

Hi Timo

Here is a super-brief explaination, I'm a little time challenged at the moment :)

I use an application process to insert the data into the database. The javascript to do this is on my demo site - just download the source and then format it to see what's going on.

When inserting it into the database I have to unescape the comment so it will render later.

I use dbms_xmlgen.convert(:new.app_comment,dbms_xmlgen.entity_decode) to do this. There may be a better way I haven't thought of.

I also strip out some html elements such as script, object, embed etc to prevent malicious attacks.

The javascript then does a PPR to display the comment immediately.

Regards

Mark

Mark Lancaster said...

MJ

Yes, you can use Apex + XE to create a website - the Oracle forums contain heaps of info on this.

You would be best served to install Apache as the web-server, rather than using the embedded PL/SQL gateway.

Also, there a number of security holes with XE - sometimes "free" is not the best approach.

Timo Annemüller said...

Hi Mark,
thanks for your help regarding to the commenting system. I build one with js (without ext) that works fine. And i also tried to build a commenting system with ext integration, but it didn´t work. I´m a newbie in js, so could you post a little extjs-commenting example please?

Leo said...

Mark,

I tried to implement this but wasn't successful. Can you please help me?

Here's what I did:
1.Uploaded ext-all.js & ext-base.js to Shared Components -->Files -->Static files and calendar.gif to images
2.Copied the following in the HTML Header of the page attributes:

script language="JavaScript" type="text/javascript" src="#WORKSPACE_IMAGES#ext-all.js"/script
script language="JavaScript" type="text/javascript" src="#WORKSPACE_IMAGES#ext-base.js"/script
script type="text/javascript"
// convert inputs with class "date-picker" to date fields
function makeDateFields(){
var els=Ext.select("input.date-picker",true);
els.each(function(el){
var df = new Ext.form.DateField({"format":'d-M-Y',"altFormats":'j|j/n|j/n/y|j/n/Y|j-M|j-M-y|j-M-Y'});
df.applyToMarkup(el);
})
}

Ext.onReady(function() {
makeDateFields();
});
/script
3.Changed the date item to Text field.
4.Entered in HTML Form element attributes: class="date-picker"
But still not seeing calendar icon next to the date item.

PS: Removed tags <>
Your help is greatly appreciated.
Thanks
Pradeep

Seek said...

Nice and useful Mark!
What about disabled fields?

function makeDateFields(){
var els=Ext.select('input.date-picker',true);
els.each(function(el){
var df=new Ext.form.DateField({
'format':'d-M-Y',
'altFormats':'j|j/n|j/n/y|j/n/Y|j-M|j-M-y|j-M-Y'
});
df.applyToMarkup(el);
if (el.getAttribute('readonly')){
df.disable();
}
})
}

I'm trying to do the same thing managing disable state, but I have some problem setting the correct data value, did you encounter this problem?

Thanks
Seek

Mark Lancaster said...

Hi Seek

Disabled is easy:

function makeDateFields(){
var els=Ext.select('input.date-picker',true);
els.each(function(el){
new Ext.form.DateField({
applyTo: el,
disabled: el.dom.disabled,
format:'d-M-Y',
altFormats:'j|j/n|j/n/y|j/n/Y|j-M|j-M-y|j-M-Y'
});
});
}

Seek said...
This comment has been removed by the author.
Seek said...

Hi Mark!
Thanks for response, in fact that easy and best implemented in your version.

I found exactly my problem.
I found a visualization error, when DOM input text is defined in ApEx as TEXT_DISABLED, and appens only with FireFox....