Friday, July 25, 2008

Selecting Apex page items by class using $x_ByClass

I just noticed an $x_ByClass example on Carl Backstrom's demo site which selects page items using the class attribute.

So why is this important?

It provides you with a mechanism to easily tag form items, typically text input fields, so you can add AJAX functionality to them.
In Carl's demo he is simply changing the the border color of datepicker items, as a proof of concept. This is exactly the same technique I use with ExtJS to:
All I have to do is assign a class to a field, and generic javascript code fires looking for the class and applying the functionality. What's really great is Oracle is building this javascript infrastructure directly into Apex.

It means that developers can easily hook in widgets and AJAX functionality, because the low level plumbing has been done for us.

Mark

Thursday, June 19, 2008

Oracle Apex Builder CSS fix for Firefox3

Does Firefox3 do this to your Oracle Apex Builder?

The fix is to disable a CSS attribute for the "fieldset.lov" class, as seen here using Firebug

To permanently fix the CSS, modify the apex_3_1.css file. Search for "fieldset.lov" and delete the "height:1em;" attribute.

I haven't tested to see if this has other undesirable side affects, but so far so good.

Mark

Friday, June 13, 2008

Tabbed Regions in Oracle Apex using Extjs

David from Scotland emailed asking how I implemented tabbed regions on my demo site. 

It's actually very easy using Extjs.  

Step 1 - Create a region template which uses static ids  
<div id="#REGION_STATIC_ID#" class="tab-content">
<div class="x-fieldset-bwrap" style="padding:10px">
<div align="right" class="x-fieldset-tbar">#CLOSE##PREVIOUS##NEXT##DELETE##EDIT##CHANGE##CREATE##CREATE2##EXPAND##COPY##HELP#</div>
<div class="x-fieldset-body"> #BODY# </div>
</div>
</div>  

Step 2 - Create your report/form regions as usual, but assigning them a static id.
I tend to use tab1, tab2, ..., tabn - but that's a personal choice.

Step 3 - Add an opening div tag before the first tab region and a closing div tag after the last region. <div id="pageTabs"> </div>
You can either create extra regions of type "html text" with no template, or simply add the extra tags in your region header and region footer. I use extra regions, so it's really obvious whats going on when I look at again in 6 months time. When the page is generated the html will look like this:
<div id="pageTabs">
    <div id="tab1" class="tab-content"> <!-- content --> </div> 
    <div id="tab2" class="tab-content"> <!-- content --> </div> 
    <!-- and so on -->
    <div id="tabn" class="tab-content"> <!-- content --> </div>
</div> 

Step 4 - Add the javascript magic Here I'm showing 2 tabs, and usually include the script with the closing div tag.
<script type="text/javascript">
Ext.onReady(function(){
       var tabs = new Ext.TabPanel({
           cls: 'prism',
           applyTo: 'pageTabs',
           plain: true,
           width: 795,
           //height: 450,
           autoHeight:true,
           enableTabScroll:true,
           autoScroll:true,
           activeTab: 0,
           deferredRender: false,
           border: true,
           defaults: {layout:'fit', autoScroll:true},
           items:[
               {contentEl:'tab1', title:'Create/Edit Customer'},
               {contentEl:'tab2', title:'Existing Customers'}
           ]
           });
});
</script>

The cls: 'prism' is a customisation I use to have a blue background for the tab panel.
I'll leave that for you to work out how I did that.

As usual, the documentation on tab panels goes into far more details. Mark

Friday, May 30, 2008

Horizontal Radiogroups in Oracle Apex

I had a requirement to set out a radiogroup horizontally the other day. Amazingly I'd almost never used radiogroups before in Apex, so didn't know how before searching the forums. The answer is quite simple: just specify the number of columns in the "List of Values" section against the item, as shown below. So that's fine for a static LOV where you know how many columns to specify. What about dynamic LOV's? Have a guess, and then go to my demo for the answer. Mark

Thursday, May 1, 2008

Carl Backstrom has created a monster

Carl Backstrom has created a monster with his forum post on "Enhancement Request Thread : Post 3.1"

The quality of the requests coming through really is testament to the growing maturity of Oracle Apex.
It is obvious that many of the respondents have the depth of understanding of the product that is only developed over time.

Interactive report regions (IRR), was a huge step forward in the 3.1 release.
It really enhanced and simplified implementing query-by-example functionality.
What's more by using AJAX functionality to only refresh the region, rather than the whole page, the user experiences better performance and a more interactive experience.

A particular feature to note is the column value filtering, which performs a lookup based on:
- column values (select distinct)
- pre-defined lov
- datatype specific, e.g. a variety of date based alternatives  

So what next for future releases post 3.1?

To my mind the focus should now be on enhancing the data entry side of Oracle Apex.
With the reporting side so much improved, data entry is looking a little tired.

Two quick wins here:
- javascript dates instead of popups
- AJAX lookups.

Implementing javascript dates is already in the statement of direction, so enough said.

AJAX lookups are not currently mentioned, but I'm sure that internally its very much on the radar.
Why am I so confident of this?
Well, mostly because so much of it is already implemented in interactive report regions.

Benefits:
- allows lookups to be performed on large datasets
- allows "auto-complete" functionality i.e. reducing list of values as you type
- better user experience than popup search forms

To see a working example, look at my demo site http://apex.oracle.com/pls/otn/f?p=200801:2007:0



My implementation is based on a holiday table, which includes a customer_id.

The AJAX functionality calls the following procedure:  

PROCEDURE customer_lookup
(p_callback varchar2
,p_query varchar2 default null
,p_limit number default 20
,p_start number default 0
,p_customer_id number default null );

The procedure works as described in the following pseudo-code:  
if p_customer_id is not null then  
-- lookup customer details and return in JSON format  
else  
-- lookup customers where name like p_query||'%' 
-- return n records in JSON format (configurable by p_limit), starting at record p_start  
end;  

For Apex to implement this:
1. New item type (perhaps AJAX lookup?)

2. Developers would need to be able to define a 3 column lov query against the item
   (Nice to have, but 2 column lov OK also)

   select value, short_display_value, long_display_value from some_table

3. Mudge existing IRR lookup functionality for query and display on page.

Worthwhile? Whats your opinion?

Mark

Thursday, March 20, 2008

Commenting system javascript on my web-site

I've received a few requests to view the commenting system javascript from my demo web-site.
The javascript is already there for all to see, either by downloading the page or viewing the source directly.
I would definitely recommend using Firefox and Firebug when viewing as it allows you to view attached script files as well as the page source.
The screenshot shows the Script tab in Firebug, listing the script files attached to the current page. In the background you can see the source for the active file.

Most of the javascript for my demo site in contained in a single "application" file playpen.js. The code has been compressed, but not obfuscated. This means you can load it into your favorite text editor and read the full source after you've done some formatting. As far as understanding the code I would highly encourage you to look at Ext 2.0 Samples and Ext Documentation. Like anything worthwhile you need to invest time and energy to gain understanding.

The comment form is based on one of the examples for dynamic forms.

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.

If this doesn't make sense to you, time to do some reading and learning :)

Mark

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