Tuesday, November 6, 2012

Apex Plugin: Execute PL/SQL code and return content to page

Here is a Dynamic Action plugin for Oracle Application Express (Apex) that lets you execute PL/SQL code in the database, and then send output generated on the server (via calls to the "HTP.P" procedure) back to any element on the web page.

A more specific use case would be to respond to the clicking of a button by generating a fragment of HTML using PL/SQL, and then refresh a DIV on the page with that dynamically generated content. See the screenshot below for an example; notice that part of the first region has been updated with content generated on the server (using input from the user, in this case the name from a regular text input item). Every time the user clicks on the button, the line above the button is updated using an Ajax call to the server.

The second region illustrates another use case: Automatically refreshing part of the page at a fixed interval.



This is how the page has been set up:



The first region has a standard text input item, and a button. The button has a Dynamic Action that is triggered when the button is clicked. The click executes the PL/SQL code which generates the greeting.

The dynamic action is set up as follows:



We can see that the content generated by the PL/SQL code is returned into a page element called "my_div". This div is simply included as the static content of the HTML region:



The second dynamic action has been set up to trigger on "Page Load". The plugin is set up to call the PL/SQL code every 5 seconds (nice way to hammer your database with requests...) and return the content into another div, called "my_other_div". The mode has been set to "Append after", which means the content will be added to the end of the existing content, instead of replacing it.



Here is the setup for the second region:



Conclusion: This plugin combines the flexibility of Dynamic Actions with the power of PL/SQL for dynamic content generation. You can download the plugin here. Update 22.05.2016: This plugin is now in my plugin repository at GitHub.




17 comments:

Jon Trøstheim said...

Hi Morten

Great!, this is something many will find useful, i have had this need many times, great that you made this.

Jon

Unknown said...

I'm looking for help with an ODP.Net + EF5 issue regarding primary key violations. they don't make sense at all considering its all done on Oracle's side via insertion triggers and sequences. Can we get in touch for a few minutes? I have a week left to solve this problem.

Morten Braten said...

@Unknown: And what, exactly, has your question regarding ODP.NET and Entity Framework to do with the subject of this blog post, a PL/SQL plugin for Apex... ? Please stay on topic.

- Morten

Patrick Wolf said...

Hi Morten,

was there a reason not to use "Set Value" action with "Set Type" = "PL/SQL Function Body"? Wouldn't that do the same (except of being able to specify the replace mode and the refresh interval)?

Regards
Patrick

Morten Braten said...

@Patrick: Good question... :-) I guess I assumed that the "Set Value" action would only work for Apex page items, but now I see that the Affected Element can also be set to (for example) any DIV using a jQuery selector. That's certainly useful to know!

However, there is still a difference in that the "Set Value" action with "PL/SQL Function Body" expects you to return everything as a single string (probably with a 32k limit?), whereas the plugin lets you construct HTML of any length and complexity with one or more htp.p calls. Depending on the usage scenario, that may be a significant difference.

Perhaps you could add an option to the "Set Type" dropdown that acts as the "Output of PL/SQL Code" option which is available in the "Based On" attribute for Display Only items? (Or some other way to incorporate the plugin's functionality in the core Apex engine.)

- Morten

Anonymous said...

Hello,

I have implemented your plugin and it is working great. Thanks!

I do have a problem with implementing jquery tabs with it. I have the plsql that puts the div, ul, and li in properly but the tab ui has a jquery function that normal gets called after page load. This binds all of the classes and stuff to the ul and li to act as a tab. Here is the function:

$(function() {
var tabs = $( "#tabs" ).tabs();
tabs.find( ".ui-tabs-nav" ).sortable({
axis: "x",
stop: function() {
tabs.tabs( "refresh" );
}
});
});


Do you know how I can fire this function once your plugin appends the plsql to the div container?

I tried outting it in the plsql, the region, creating a dynamic action, etc. and can not get it to work.

Morten Braten said...

@Anonymous: I actually added a JS callback feature to the plugin in the latest version, which allows you to define a JS function that you would like to be called after the Ajax call finishes (ie after your server-generated content is inserted).

I haven't uploaded this version yet, I'll see if I can do that sometime soon...

- Morten

Anonymous said...

Morten...

Thank you for this plug-in. I have been using it and loving it.

> I'll see if I can do that sometime soon

I have run into a similar situation as described by "Anonymous" before where I want to run some jQuery on the affected DIV after your plug-in is finished. I could really use the "JS callback" functionality you described. I went to the download page and saw that the latest version of the plug-in is the original version from Nov. 2012. Do you have a version with the "JS callback" in it available to the public yet? Thank you.

Shane Bentz.

Anonymous said...

Thanks a lot. Great tool, and easy to work with. I use it for showing and refreshing a progress bar every n seconds.

The only drawback seems that the interval timer cannot be "killed" from within the plugin, so it repeats forever until the page gets refreshed.

Andreas

Anonymous said...

Hi,

what Oracle Apex Versions this plug-in works ? I tried in Application Express 4.0.2.00.09 and got this error message Not compatible (the exported can contain not supported application levels)

Anonymous said...

This is great! Out of interest, how can I call a plugin in a region based on PL/SQL - or is that even possible. I have an item plugin which I want to render x times so want it to be dynamic.
Thanks
Paul

Waqar said...

Hi,

This is a great plugin and working perfectly fine, but one thing i'm missing in this that i cannot use "Wait for result" attribute in this, can you please update this standard attribute in this plugin or guide me to do this.

Thanks a lot
Waqar Ahmed

Morten Braten said...

@Waqar: The latest version of the plugin (see updated link at the end of the post) has a callback attribute where you can specify some Javascript code to run after the process has finished. It's not exactly the same as "Wait for result", but should be helpful anyway.

- Morten

Orujo-kid said...

Works like a charm!

I use it in a setup with GoogleMaps ( Jeff Kemp plugin ReportMap) to display marker content in a seperate Apex region without having to submit the whole page when clicking on a Marker.

Thnx for this plugin!

Mesut Sağlam said...
This comment has been removed by a blog administrator.
Vladimir said...

Hi Morten, thank you for your plugins. htmldb_Get is desupported since Application Express Release 5.1 which means to keep APEX application backwards javascript compatibility to use your excellent plugin. Not to time to release new version with the usage of apex.server.process? Thank you for consideration.

Morten Braten said...

@Vladimir: It's true, htmldb_Get is deprecated and requires the "include legacy scripts" attribute to work in newer APEX versions. I have developed a new version of the plugin that uses apex.server.plugin instead of htmldb_Get. Will publish it soon.

- Morten