My First APEX plug-in

In an attempt to reach a broader audience, this will be my first blog in English. I hope this will help more people to read and use my tips and tricks. For me it will be an extra challenge!

For some time now (since version 4.0), APEX has offered the plug-in functionality and although I used several plug-ins, I still did not build any myself. This is mainly because existing plug-ins were adequate or I built the needed functionality directly into the application. To be able to reuse code, it is better to use plug-ins instead of coding everything into pages. In this blog I will build my first plug-in.

The purpose of the plug-in is to display notifications that can be controlled by a dynamic action. As a basis I will use the noty jQuery plug-in (http://needim.github.io/noty/) which is a good start to build the APEX plug-in around.

How to start? First, go to the shared components of your application and click on plug-ins under the User Interface heading. So far for the easy part ;-), although building a plug-in is not that complicated I discovered to my surprise. I will guide you through the different steps below.

  1. Shared components
  2. Plug-ins
  3. Create a new plug-in
  4. Enter the name for the plug-in.

    The name you provide here is used within your application. It is good practice to use your domain as a prefix. This creates a globally unique name. With this name you are able to share the plug-in without worrying about duplicates. I bet there are more plug-ins called ‘notification’ out there ;-). Choose the Type and Category as shown in the screenshot.
  5. Now create the plug-in, we will finish it later.
  6. Add Custom Attributes. These are the parameters to pass on to the Javascript function that will start the real action on your page. I did not create parameters for all available options in noty. For a start I just took those that are essential.

    Label Type Required Depending on Description
    Theme Select list yes  Select one of the themes you have created or use the default.
    Layout Text yes Where does the notification pop-up
    Type Text yes  alert, succes, error, warning, information or confirm
    Text Textarea yes  The text for the notification.
    Sticky notification Text no  Will the notification stick on the page.
    Hide after x seconds Integer no  Hide the notification after x seconds, only for not sticky notifications.
    Max visible notifications Text no The maximum number of visible notifications. More will be queued and become visible when other notifications disappear.
    Item receiving confirm answer Page Item/ Column no Item for confirm answer (Ok/Cancel)
  7. Now we build a wrapper around the noty jQuery plug-in. This is a Javascript function that is executed by APEX. In the wrapper we will receive the Custom Attributes defined in step 6 and pass them on to the noty jquery plug-in as parameters. There is a possibility in this function to use the value of an item for the attributes. To enable this you just put the item name between ‘#’s. (eg #P1_TEXT#).

    /**
    * Notification plugin v1.0 – http://www.orcado.nl
    *
    * Based on jQuery plugin noty
    * noty – jQuery Notification Plugin v2.1.2
    * Contributors: https://github.com/needim/noty/graphs/contributors
    * Examples and Documentation – http://needim.github.com/noty/
    * Licensed under the MIT licenses:
    * http://www.opensource.org/licenses/mit-license.php
    *
    **/
    function com_orcado_notification(){

    function replacePlaceholders(pText) {
    // replace all #page_item_name# placeholders
    var lSearchPattern = new RegExp(“#w+#”, “g”),
    lFoundList,
    lPageItem,
    lFinalText = pText;
    // search as long as the text contains a placeholder
    while (lFoundList = lSearchPattern.exec(pText)) {
    // get value, but search without the #
    lPageItem = $x(lFoundList[0].replace(/#/g, “”));
    if (lPageItem) {
    lFinalText = lFinalText.replace(lFoundList[0], $v(lPageItem));
    }
    }
    return lFinalText;
    }; // replacePlaceholders

    // It’s better to have named variables instead of using
    // the generic ones, makes the code more readable
    var lTheme = this.action.attribute01,
    lLayout = this.action.attribute02,
    lType = this.action.attribute03,
    lText = this.action.attribute04,
    lSticky = ((this.action.attribute05===”Y”)?false:this.action.attribute06*1000),
    lMax = this.action.attribute07;
    lAnswer = this.action.attribute08;

    if (replacePlaceholders(lType)==’confirm’) {
    var n = noty({
    text: replacePlaceholders(lText).replace(/n/g,’
    ‘),
    type: replacePlaceholders(lType),
    dismissQueue: true,
    layout: replacePlaceholders(lLayout),
    theme: lTheme,
    timeout: lSticky,
    maxVisible: replacePlaceholders(lMax),
    buttons: [
    {addClass: ‘btn btn-primary btn-noty-ok’, text: ‘Ok’, onClick: function($noty) {
    $s(lAnswer, ‘Ok’);
    $noty.close();
    }
    },
    {addClass: ‘btn btn-danger btn-noty-cancel’, text: ‘Cancel’, onClick: function($noty) {
    $s(lAnswer, ‘Cancel’);
    $noty.close();}
    }
    ]
    });
    }
    else { var n = noty({
    text: replacePlaceholders(lText).replace(/n/g,’
    ‘),
    type: replacePlaceholders(lType),
    dismissQueue: true,
    layout: replacePlaceholders(lLayout),
    theme: lTheme,
    timeout: lSticky,
    maxVisible: replacePlaceholders(lMax)
    });
    }
    }

    First, we assign the generic variables to named ones. This is not required but it makes the code more readable. Then we call the noty plug-in with the right parameters. As you can see, a bit of Javascript knowledge is needed here.

  8. Upload Files used by the plug-in.

    Name Description
    com_orcado_jquery.noty.js Javascript wrapper around the noty jquery plug-in
    custom.js Custom theme (based on default.js)
    default.js Default theme
    jquery.noty.js noty jquery plug-in
    layout.js Javascript which will set the css for the available layouts
  9. What remains is the PL/SQL code for rendering and executing the plug-in. You can see that you need to register the Javascript libraries and the function with attributes in the dynamic action

    function render_noty_notification (
    p_dynamic_action in apex_plugin.t_dynamic_action,
    p_plugin         in apex_plugin.t_plugin )
    return apex_plugin.t_dynamic_action_render_result
    is
    l_theme          varchar2(4000) := p_dynamic_action.attribute_01;
    l_layout         varchar2(4000) := p_dynamic_action.attribute_02;
    l_type           varchar2(4000) := p_dynamic_action.attribute_03;
    l_text           varchar2(4000) := p_dynamic_action.attribute_04;
    l_sticky         varchar2(4000) := p_dynamic_action.attribute_05;
    l_wait_seconds   number         := to_number(p_dynamic_action.attribute_06);
    l_max            varchar2(4000) := p_dynamic_action.attribute_07;
    l_answer         varchar2(4000) := p_dynamic_action.attribute_08;
    l_result         apex_plugin.t_dynamic_action_render_result;
    begin
    — During plug-in development it’s very helpful to have some debug information
    if apex_application.g_debug then
    apex_plugin_util.debug_dynamic_action (
    p_plugin         => p_plugin,
    p_dynamic_action => p_dynamic_action );
    end if;
    — Register the javascript and CSS library the plug-in uses.
    apex_javascript.add_library (
    p_name      => ‘jquery.noty’,
    p_directory => p_plugin.file_prefix,
    p_version   => null );
    apex_javascript.add_library (
    p_name      => ‘com_orcado_jquery.noty’,
    p_directory => p_plugin.file_prefix,
    p_version   => null );
    apex_javascript.add_library (
    p_name      => ‘default’,
    p_directory => p_plugin.file_prefix,
    p_version   => null );
    apex_javascript.add_library (
    p_name      => ‘layout’,
    p_directory => p_plugin.file_prefix,
    p_version   => null );
    — Register the function and the used attributes with the dynamic action framework
    l_result.javascript_function := ‘com_orcado_notification’;
    l_result.attribute_01 := l_theme;
    l_result.attribute_02 := l_layout;
    l_result.attribute_03 := l_type;
    l_result.attribute_04 := l_text;
    l_result.attribute_05 := l_sticky;
    l_result.attribute_06 := l_wait_seconds;
    l_result.attribute_07 := l_max;
    l_result.attribute_08 := l_answer;

    return l_result;
    end render_noty_notification;

  10. Save the plug-in by clicking Apply Changes
  11. 1. You finished building the plug-in so now we are able to use it. To do this, create a Dyamic action based on the plug-in we just built.
  12. Enter the values in the parameter fields:
  13. And you are done. The plug-in provides for nice notifications the way you specify in the dynamic action.
  14. See here for a demo