10

APEX Plugin – Ext JS Tree (Coming very soon)

This is a sneak peek at a new Ext JS tree plugin which I’ve developed. I’m in the final stages of packaging it and producing the demo’s and documentation so it will be available for download on apex-plugin.com very soon.

So what features does the plugin offer?

  • AJAX enabled with the choice of loading the entire tree in one call or on node by node expanding
  • Search: Dynamic filtering of the tree contents
  • Expand & Collapse buttons
  • Drag & Drop Reordering Support
  • Tree Label Editing
  • Checkbox Nodes with state saving using an existing APEX item
  • Context Menu Support (from SQL Query)
  • Cookie based state saving for expanded nodes.
  • Order by “Display Sequence” support
  • Fully integrated into dynamic actions. Bind click, drag & drop, edit complete, expand, collapse, context menu selection etc. events
  • In it’s basic form opens URL targets
  • Tree config is fully customizable
  • Support for node by node custom config, e.g. enableDrag = false
  • Full support for replacing substitution strings (label, help text, url, etc)
  • Custom icon support
  • Help text support
  • Supports unlimited tree’s on a single page

The plugin takes the following list of 10 parameters:

With the event support you can create dynamic actions to process tree events. This means that it’s simple to refresh reports, perform AJAX callbacks to process the reordering of nodes, or label edits, or filtering of reports based on check box selections.

The hidden gem is the context menu. The context menu can be generated just like the tree in an object hierarchy from a single SQL statement. This means that you can have multi navigational capabilities, or filtering. Here’s one example of using a date picker within the context menu….

and if you’re using 11g and you need a complex context menu with datepicker, radio items, combo support, you can define your context menu query based on a table/view which has a parameter and value column like this…

SELECT id           menu_id
,      pid          menu_pid
,      display_seq  display_seq
,      LISTAGG('<'||parameter||'>'||parameter_value||'</'||parameter||'>', ' ')
         WITHIN GROUP (ORDER BY parameter) xmlconfig
FROM   af#tree_context_menu
GROUP BY
       id
,      pid
,      display_seq

Your parameter values can be (sub)JSON objects I’ll take care of turning the entire resultset into a JSON object hieararchy with the aid of “dbms_xmlgen.newcontextfromhierarchy” and XSLT.

P.S. This is just the first Ext plugin in the series, with more coming soon.

23

APEX Plugin – Multiple File Upload

Today I’m releasing the RC1 (Release Candidate 1) version of my commercial File Upload Item Plugin. The plugin supports the multiple selection and uploading of files from a single file browse with the addition of drag & drop support for browsers that support HTML5. It also provides backwards compatibility for non HTML5 browsers by allowing multiple files to be uploaded one by one without submitting the page. The plugin is compatible with modplsql & the PLSQL gateway.

The plugin supports 4 events which can be used in combination with dynamic actions e.g. refreshing a report once a file upload is complete. Here’s a recorded demonstration of the plugin in action.

You can also demo the plugin on apex.oracle.com and view the documentation here.

Finally I’m making a obfuscated RC1 version available for download and testing from apex-plugin.com as I’m hoping to gather some useful feedback before the final product release to accommodate any tweaks or enhancement requests. So please download and test it out for me if it’s something you think you might use in the future.

Please Note: using the plugin in production will require the purchase of an appropriate license.

1

Custom Tabular Form Validations

This is a follow up post to “Combining your item validations into one, without losing inline display”. Whilst most of the techniques I describe (present and past) are not officially supported, the point to note is that they simply exist because APEX currently does not provide the required functionality. The thing I like about APEX is that there is a lot of flexibility to interact with the engine during page rendering and processing, at the same time though we need to ensure that we do this in a safe and future proof manner, or at least be aware of the risks and properly document them.

Custom Tabular Form Validation

So the point of today’s post is to fulfil the requirement of creating complex tabular form validations without losing the benefits of inline display. Now I’m sure this will be coming in the next APEX 4.1 release, but as always I have an immediate requirement. So to fill the void in the meantime I’ve extended the “LOG_VALIDATION_ERROR” function defined in the earlier post to include support for tabular forms ( it’s simply a wrapper for code centralization purposes ).

-- ---------------------------------------------------------------------------
--
-- Procedure      : log_validation_failure
-- Author         : Matt Nolan
-- Private/Public : Public
-- Description    : Wrapper for logging validation failures in the APEX engine
-- ---------------------------------------------------------------------------
-- Revision History
-- Date            Author       Reason for Change
-- ---------------------------------------------------------------------------
-- 02 FEB 2011     M.Nolan      Created.
-- ---------------------------------------------------------------------------
PROCEDURE log_validation_failure
( p_item          IN VARCHAR2
, p_message       IN VARCHAR2
, p_location      IN VARCHAR2 DEFAULT 'INLINE_WITH_FIELD'
, p_column_id     IN VARCHAR2 DEFAULT NULL
, p_column_name   IN VARCHAR2 DEFAULT NULL
, p_row_num       IN VARCHAR2 DEFAULT NULL
)
AS

  l_app_id     VARCHAR2(10) := apex_application.g_flow_id;
  l_page_id    VARCHAR2(10) := apex_application.g_flow_step_id;
  l_item_id    apex_application_page_items.item_id%TYPE;
  l_index      PLS_INTEGER;

BEGIN

  apex_application.add_validation_error
  ( p_message                => p_message
  , p_error_display_location => p_location
  , p_page_item_name         => p_item
  , p_column_id              => p_column_id
  , p_column_name            => p_column_name
  , p_row_num                => p_row_num
  );  

  IF apex_application.g_debug THEN
    apex_debug_message.log_message('Custom Validation');
    apex_debug_message.log_message('...Item: '||p_item);
    apex_debug_message.log_message('...Message: '||p_message);
    apex_debug_message.log_message('...Location: '||p_location);
    IF p_column_id IS NOT NULL THEN
      apex_debug_message.log_message('...Column ID: '||p_column_id);
      apex_debug_message.log_message('...Column Name: '||p_column_name);
      apex_debug_message.log_message('...Row Number: '||p_row_num);
    END IF;
  END IF;

EXCEPTION
  WHEN OTHERS THEN
    -- custom error handler goes here
    RAISE;
END log_validation_failure;

Here’s an example of how we would code a custom tabular form validation ( Note: its a PLSQL page level validation which always returns TRUE as we add the errors ourselves within the function):


FUNCTION mytabform_validation
( p_tabform_pk      IN APEX_APPLICATION_GLOBAL.VC_ARR2
, p_tabform_column  IN APEX_APPLICATION_GLOBAL.VC_ARR2
, p_column_id       IN VARCHAR2
, p_column_name     IN VARCHAR2
, p_message         IN VARCHAR2
) RETURN BOOLEAN
AS

  l_student_id        user_volts_reservation_day_vw.student_id%TYPE;
  l_reservation_id    user_volts_reservation_day_vw.reservation_id%TYPE;
  l_message           VARCHAR2(500);

BEGIN

  FOR i IN 1.. p_tabform_column.count LOOP

    l_pk_id := p_tabform_pk(i);
    l_value := p_tabform_column(i);

    IF NOT some_validation
          ( p_pk               => l_pk_id
          , p_value            => l_value
          , p_message_override => l_message
          )
    THEN
      log_validation_failure
      ( p_item        => NULL
      , p_message     => nvl(l_message,p_message)
      , p_location    => 'INLINE_WITH_FIELD_AND_NOTIFICATION'
      , p_column_id   => p_column_id||'_'||lpad(i,4,'0')
      , p_column_name => p_column_name
      , p_row_num     => i
      );
    END IF;
  END LOOP;
  --
  -- Always return true as we validate and add the error messages ourselves
  --
  RETURN TRUE;

EXCEPTION
  WHEN OTHERS THEN
    -- your custom error handler goes here
    RAISE;
END;

And here is how we’d call the validation, by passing in the column arrays which we are interested in validating along with the column_id of the field we are validating and its corresponding name. In this example I also pass through the tabular form primary key as well to use in table lookups during validation.

RETURN mytabform_validation
      ( p_tabform_pk     => apex_application.g_f02
      , p_tabform_column => apex_application.g_f03
      , p_column_id      => 'f03'
      , p_column_name    => 'STUDENT_ID'
      , p_message        => 'Student is booked on another course!'
      );

Note: the “column_id” and “g_f0x” array items can be determined by using firebug and inspecting the input elements in the tabular form on the page. Alternatively you could omit them and do a lookup of the APEX Data Dictionary within the validation based on the column name passed through to identify the required id’s.

If you need extra validation control on your tabular form but are uncomfortable with using the undocumented “ADD_VALIDATION_ERROR” procedure, then have a look at an alternative post Denes Kubicek wrote late last year. Otherwise I hope you find this information useful, as it’s helped me on my current project immensely.

Finally if one of the APEX development team members happens to read this ( not naming and shaming names :) ) a little inside knowledge of whether this will break in the next 4.1 release would be invaluable.

Pages ... 1 2 3 4 5 6 7 8 9