AJAX in APEX

AJAX is becoming important in the world of web applications. APEX has provided us a very easy way to create an AJAX process, by using dynamic actions. Using PL/SQL Actions in Dynamic Actions to communicate with the database without submitting the page will suffice in most cases, but the downside is that the code is not very re-usable, and when you want to write a plug-in you simply don’t have access to Dynamic Actions. In this blog you will learn how to code your own AJAX process.

An AJAX process in APEX consists out of three parts

  • The JavaScript code that calls the AJAX PL/SQL Process
  • The PL/SQL Process that might or might not return a value
  • The JavaScript code that catches the return value and possibly does something with it

In APEX there are three ways to create an AJAX process from JavaScript:

  • The htmldb_get() method: undocumented but this used to be the only method available (without installing external libraries)
  • jQuery.ajax(): since jQuery was added to APEX, it has been quite common to use this method. It’s well documented on the jQuery homepage, but the downside is you need to write more code
  • apex.server: this new APEX API has been recently added (I believe at APEX 4.2). It is actually a wrapper of jQuery.ajax(), so it supports the same functionality with some additional APEX specific features. It is thoroughly documented in the APEX documentation, and this is the reason I prefer this method, and I will explain how you too can use it

The first thing we do is create a test application. In our case we have a table called “JOBS” that looks like this:

jobstable

In my jobs table I just inserted one job with a salary of 2800 of an unknown currency.

In our APEX application we have an Item of the type select list where the user can select a job, and then the minimum salary will be filled in.

Our page looks like this:

page

Next we write our JavaScript code.  This includes our change event and the apex.server.process . Double click your page name to go to the page definition, and scroll down to “Execute when page loads”.

javascript call

  • AJAX_GET_MIN_SALARY is the name of our future AJAX process.
  • X01 is the variable we pass, in this case the value of our #P17_JOB_ID item
  • Finally we declare that our expected return type is plain text. If we don’t do this, then by default the function expects a JSON string returned. Furthermore we declare in this function what we do with this return data. The return data will be delivered asynchronous, meaning we will get this data from our AJAX Callback function as soon as the AJAX Callback process is ready.

Now we can create our AJAX_GET_MIN_SALARY Ajax Callback process. Just right click on Ajax Callbacks . Click “Create” and select PL/SQL. Here we can put our PL/SQL code:

ajax_process

There are two things here that are worth mentioning:

  • TO_CHAR(apex_application.g_x01): this is how we catch the variable that is passed from our JavaScript code. We use TO_CHAR to identify that it’s a character.
  • HTP.Prn(v_min_salary): here we return the minimum salary back to our page

There, all done!  Let’s test out our application, shall we? Before you do anything it’s best to open the developer toolbar in the browser. In Chrome you can do this by pressing ctrl+shift+J.  It’s  a good practice to reload the page and to check if any JavaScript errors pop up on the console. If our JavaScript code shows no errors in the console go to the ‘Network’ tab, and select a job in the application.

items

You will now see www_flow.show appear. Click it. There are two tabs here that are vital to investigating this function for debugging, if needed. The first is the header, it shows what data is send to our AJAX Callback function.

toolbar

The second tab that’s important is our Response tab. It tells us what data is send back from the PL/SQL Process. If you remember our PL/SQL Process you will notice that we did not include an exception for when no data was found. Select “null” as job and you will get an error. If you then check out the response of the AJAX call you will see it gives our ORA error.

error

If you managed to read this far then you have gained some insights on how you can create your own AJAX function using the new APEX JavaScript API, how it works and how you can debug it should not everything go as planned.

Apex Extension

About a month ago I saw a mail coming by where a colleague of mine had integrated the jQuery plug-in Codemirror into a text area for the end-user. I hadn’t seen this plug-in before, but I really liked the feel of it.

I’m sure all of us can recognize the fact that we miss tab indentation in  APEX, or that we would like to see key words, numbers and strings in color, or how about some line numbers? Perhaps line numbers that hold into account that the line number of an error in a PL/SQL APEX process is never quite the same as the place of the error. This last one is because APEX places BEGIN and END; automatically around PL/SQL processes. Convenient for the developer so he can develop faster, not so much when it comes down to debugging.

Since we can not change the APEX Application Builder, it would be nice to find another solution? And that solution exists: take a look at the following screenshots:

Image

Image

So how did I do it? A little “thinking outside the box” did the trick. While we might not want to mess with Apex directly, we can use browser Extensions and add-ons, to alter the looks, safely from a distance. So I created a small Chrome Extension that integrates CodeMirror into the APEX Text Areas.

Chrome Extensions are created with HTML5 and JS so once you have the basics of your Extension set up you can convert an Apex Text Area like this:
var vTextArea=document.getElementById(“F4000_P4312_PROCESS_SQL2″);

vMyEditor = CodeMirror.fromTextArea(vTextArea, {

mode: “text/x-plsql”,
tabMode: “indent”,
tabSize : 2,
lineNumbers: true,
firstLineNumber: 2,
lineWrapping: true
});

I wrapped this in a “$(document).ready(function(){});” to make sure it is executed after loading all plug-ins.

I hope I showed you all that you can do allot with a little imagination, and I welcome any questions or suggestions.

Joni Vandenberghe

Get triggering element in dynamic action

Last week, I ran into a problem with a dynamic action in APEX 4.0.

I have a series of 8 images of persons which I generate with PL/SQL. They are all speakers on a conference. Every image is clickable and should insert the name of the speaker in the database.

I gave a class “speaker” to every image. The ID of the image is the primary key of the person in our database. By doing this, I am able to create a dynamic action which I can bind to the JQuery selector ".speaker".

In this case, I wanted to use AJAX to perform my actions so I created an AJAX callback insert_speaker which contained the PL/SQL block with the insert command. Based on the PK of the person, the name of the speaker will be inserted into the database, together with some extra information.

In my dynamic action, I added a true action of type “Execute JavaScript code”. Here, I ran into a problem: how do I get the ID of the image the user clicked on?

On the internet, I found two solutions with JQuery to get the ID of the triggering element of an event:

$(this).attr("id");

and

event.target.id;

There is a little difference between these two, found it out here, so I tested both and concluded I needed event.target.id.

I completed the JavaScript block with the AJAX request, the ID parameter and the other lines and tested the page.
Everything worked perfectly. Well done, I tought…
…untill I tested my page with Mozilla Firefox. Firebug returned an error ‘event is not defined’.

Hmm…and it all worked fine in Google Chrome (I use this browser for application development)? Strange.
After a while of searching, I figured out there is another solution, something specific to APEX:

this.triggeringElement.id;

Sounds logical, but it isn’t when you have no idea this line can be used in APEX.

The only official documentation I could find about this, is the help text of the textarea labeled “Value” in the When block of a dynamic action.
Help text

When I changed

event.target.id;

to

this.triggeringElement.id;

in my code, the page works fine in both Google Chrome and Mozilla Firefox.

For further development with APEX 4.0: make sure you test your pages in multiple browsers!
The example above states  very well that not all browsers interpret code the same way!

Oracle Forms 11g and Google maps integration

In last years blog post about Forms 11g Javascript integration I explained how you could call the Google Maps API from forms using JavaScript.

I captured that testcase using screentoaster.
It seems that this tool has disappeared and all the recorded sessions with it.

So, here’s a new video on youtube of this Google Map Integration, now in a demo application.
The Form is embedded in a HTML page witch contains a Google Map.

Oracle Forms 11g and Apex using external events

I remembered an old post of Roel Hartman where he integrated a form into apex.
He used a part of OraFormsFaces by Wilfred van der Deijl: the CommunicatorBean.
Using this CommunicatorBean forms could react on “external messages”.
Now with Forms 11g reacting on external events, this CommunicatorBean isn’t necessary any more(sorry Wilfred).

This is how I did it using external events…
First things first: set up the advanced queueing mechanism.
Check this tutorial which includes setting up advanced queueing.
I created a little form based on emp(nothing fancy)…

The new feature in forms:

With the following properties:

What should forms execute when this event happens?
This has to be specified in the When-event-raised trigger.

In this case we retrieve the payload and extract the empno from it.
The empno is used to set the default where clause on the block.
When there’s an empno on the queue, forms will query that employee.
That’s all for the forms part…
Now I created a little Apex page with two regions:

The Employee details will be our form.
So I put our form in the HTML using an iframe:

Using a “select list” it’s possible to select an employee.

This is the result:

Now the purpose of the select list is to choose an employee and show the detail information in our form.
In order to do this, the select list calls a javascript function.

This javascript function is created in the HTML header

The code behind this:

<script language=”JavaScript” type=”text/javascript”>
function getEmployee (){
var emp = $x(‘P2_EMPNO’);
// send request
var ajaxRequest = new
htmldb_Get(null,&APP_ID.,’APPLICATION_PROCESS=get_emp’,0);
ajaxRequest.add(‘P2_EMPNO’,emp.value);

// get response
ajaxResult = ajaxRequest.get();
ajaxRequest = null;
}
</script>

This javascript function calls an application process and uses the empno as parameter.
The application process put the empno on the queue.

When changing the select list, the form is queried

This is a solution to integrate forms into another application whether it’s Apex, ADF or another web applicaton.
When it can put something on the queue, forms can react on it.
And yes, I could do it using the javascript feature in Forms 11g. I know…
And for Apex it’s probably a better solution, as we can skip the AQ part and make calls to and from forms in Javascript.

Forms 11g javascript integration: Call others

Forms 11g holds a lot of interesting new features focused on event-driven architecture, one of these is javascript integration. There are two ways of using javascript with Forms 11g: “call others” and “let others call you”.

Javascript can call code in Forms(“Let others call you”) using the new forms trigger “when-custom-javacript-event”.

This post is going to show you the first one: “call others”, in other words call javascript from your Oracle Forms application.

During the Forms Modernization Seminar I showed a google map that could be manipulated from an Oracle Form. It’s an easy implementation with only a few lines of code(most of the javascript is taken from the api examples on the google code site: http://code.google.com/apis/maps/).

  • Build a little form with one (control) block, one text field(to enter an address) and one button(to call the javascript code).
  • Next step is to create an HTML-page to display the form.

This code puts the form(in an iframe) and the map side by side:
(Click to enlarge)

And it will look like this:

  • The javascript that will be called is put in another file google.js:

  • The only thing to do is creating a “when-button-pressed” trigger in forms to call the javascript function showAddress.
    This is done by a new built-in procedure web.javascript_eval_expr:
  • Copy the HTML and javascript file to the following directory:
    <middleware_home>\user_projects\domains\<domain>\servers\WLS_FORMS\tmp\_WL_user\formsapp_11.1.1\e18uoi\war\
  • Create a new configuration using Enterprise Manager:

  • Make sure the parameter EnableJavascriptEvent is set to “true’ in your configuration!

And the working demo…