Aug 17

In the last blog post I talked about the idea of using region plugins for defining query sources rather than acting as a standalone plugin, and the post before that: transforming apex button references into different Ext form items. This post is focused on bringing those two approaches together. i.e. in our development environment we used a stripped down region plugin to define a query source which is used to supply the list of radio items in an Ext Button Menu within the parent region/report.

Perhaps the following two images will explain what I’m failing to do with words…

In the above two images; the first shows the display of two separate menu’s with different items (it’s been photoshopped to show you two tabs of the tabpanel as the menu’s are on separate tabs). The second shows the APEX IDE and the menu plugins which are used to define the query source for the menu items.

The difference in approach to the “A button is not always a button” post is that instead of building a json object in the page header with our shortcuts and using a function to clean some malformed JSON outputted by our templates. We changed the design to generate the entire region toolbar JSON object in the page header, as it allowed a more cleaner and maintainable approach and opened up the ability to query the APEX data dictionary and process sub regions as we looped through each parent region at a time.

The following code example from our initial prototype (which only works for one menu button per region) should give you an idea of how we query the APEX data dictionary to build the toolbar object


--
-- Lets loop through all our page regions to create our region toolbar for each
--
FOR c IN
( SELECT *
  FROM   apex_application_page_regions
  WHERE  application_id = v_app_id
  AND    page_id        = v_page_id
  AND    source_type    NOT IN ('EXT_BUTTON_MENU') -- ignore our stripped pseudo plugins
  AND    extjs_utils.auth_condition_check(condition_type,condition_expression1,condition_expression2,authorization_scheme) = 0
)  LOOP
  v_toolbarObj := JSON_LIST();
  --
  -- Lets loop through all our page buttons to create our region toolbar
  --
  FOR c1 IN
  ( SELECT pb.region_id
    ,      label
    ,      nvl(redirect_url,'apex.submit('''||button_name||''');') link
    ,      button_attributes
    ,      template
    FROM   apex_application_page_buttons pb
    ,      apex_application_temp_button  tmp
    ,      apex_applications             app
    WHERE  pb.application_id  = v_app_id
    AND    pb.page_id         = v_page_id
    AND    pb.region_id       = c.region_id
    AND    tmp.application_id = pb.application_id
    AND    app.application_id = pb.application_id
    AND    tmp.template_name  = pb.button_template
    AND    tmp.theme_number   = app.theme_number
    AND    extjs_utils.auth_condition_check(pb.condition_type,pb.condition_expression1,pb.condition_expression2,pb.authorization_scheme) = 0
    ORDER by pb.button_sequence
  ) LOOP
    --
    -- Lets check our button attributes for shortcuts
    --
    v_shortcut_name := regexp_replace(c1.button_attributes, '.*"(EXT_\w+)".*','\1');
    v_shortcut_name := CASE v_shortcut_name
                         WHEN c1.button_attributes THEN NULL
                         ELSE v_shortcut_name
                       END;
    IF v_shortcut_name IS NOT NULL THEN
 
      FOR c2 IN
      ( SELECT shortcut_name
        ,      shortcut
        FROM   apex_application_shortcuts
        WHERE  application_id = v_app_id
        AND    shortcut_name  = v_shortcut_name
      )  LOOP
        v_shortcut := c2.shortcut;
        --
        -- Lets loop through our shortcut and replace our menu references with a JSON object
        --
        WHILE instr(v_shortcut,'#MENU:') > 0 LOOP
          FOR c3 IN
          ( SELECT source_type
            ,      region_source menu_sql
            FROM   apex_application_page_regions
            WHERE  application_id   = v_app_id
            AND    page_id          = v_page_id
            AND    parent_region_id = c.region_id
            AND    source_type      = 'EXT_BUTTON_MENU'
          ) LOOP
            --
            -- Lets execute our query and return the result encoded in a JSON object
            --
            v_json := sql_to_json( p_sql => c3.menu_sql );
            v_shortcut := regexp_replace(v_shortcut,'(\$MENU:\w+\$)',v_json,1,1)..........

In the above we query all the regions on the page and ignore any of our pseudo plugin regions. We then build up the toolbar JSON object with the assistance of PLJSON and then loop through each of the buttons defined for the region and use the defined button template and make the necessary string replacements e.g. #BUTTON_ATTRIBUTES#. But before we do, we check the button attributes to see if a custom MENU shortcut has been defined and if so we extract the shortcut name and query the shortcut source. We then extract any MENU definition in the shortcut source and then in the c3 cursor loop we query “apex_application_page_regions” and check the source type matches our plugin name and we use this SQL definition and execute it to get the results for the named menu.

So what it allows us to do from a development point of view is define a single button template e.g. radio menu, and use our pseudo plugins SQL to define the menu items. Essentially our toolbar menu button is made up of a button template, shortcut, and plugin region. All three components can be subscribed and published across all applications in the workspace so we get the benfit of code centralization and any additional custom config for the button menu can be defined by either using multiple shortcuts or some additional config in #BUTTON_ATTRIBUTES#.

In order to make sure the plugin region never displays, we use a template named either “Ext.Exclude” which wraps the content in a DIV with style=”display:none;”. Optionally we can use another template named “Ext.Destroy” which uses the Ext.onReady function and removes the region/DIV from the DOM on page load. Both come in very handy in different situations. We simply ignore regions which have these templates assigned to them within our viewport generation code.

Note: you will see this error in the region source when you use a stripped plugin like we have

ORA-20100: No render function has been defined for plug-in PLUGIN_EXT_BUTTON_MENU

 

however this is never visible because the template we define either destroys the region or hides it from display.

Tagged with:
Jul 16

We’ve bitten the bullet and updated our internal development environments to APEX 4.0 which includes our APEX/Ext development framework. We had no troubles during installation. Post Installation, there have only been a few minor issues which we’ve run into which are:

  1. Changing our javascript override for “doSubmit” to “apex.submit”, we use this for upload/downloading multiple clobs and other things….
  2. Catering for data dictionary changes for item type “Display As” definitions
  3. Viewing session state: collection information does not appear to work
  4. We’ve had to move the developer toolbar on page load using javascript (i.e in runtime development mode) as it sometimes overlays important navigation on the page e.g. bottom tabs on a tabpanel etc.
  5. That’s it!!

APEX 4.0 is a big jump for the product and personally I must say that the development team has done a fantastic job as we were quite worried about the impact this version would have on all the previous custom development we’d performed against earlier versions. We can breathe easy now ;)  

What’s my favourite part/new feature? Plugins come a close second but my favourite new feature is the ability to create a region within a region. Now you’re probably thinking that I’ve got a couple of screws loose! but for me this single feature has just opened the door for a perfect design for APEX and Ext integration, as we can now build/define page components/templates in the exact same form Ext creates them, e.g. Viewport -> Layout -> Panel -> Form e.g.

 

Note: the above is just a quick mockup as all regions are defined as “HTML”, normally the region types would reflect their specific type e.g. a Tree would be a Tree, a Form would be a Form etc.

I am a little biased though on the features that I like because I’m purely focused on APEX and Ext, but I’m also spicing things up by using a sprinkling of jQuery here and there, so in the future we’ll be documenting the sociability of APEX/Ext/jQuery, as we’d like to still use some of the productivity gains we get from dynamic actions and the likes.

Finally we’re curious if anyone would purchase a license and support for a commercial plugin, we’re considering building an APEX 4.0 plugin for the Ext Gantt demo with full editing support. Just leave a comment to start a discussion on the (controversial) topic…

Tagged with:
Dec 19

Since it’s Christmas and things have slowed down, it’s time to knuckle down and work on upgrading to Ext 3.1 (released on 16th December) and do some preliminary testing now that APEX 4.0 early adopter has been released.

Ext JS 3.1

So far upgrading to Ext 3.1 hasn’t been smooth, it initially looks like all our component integration which uses the config renderTo is not working, but the bright side is that we’re introducing a new design change which will make the framework more cohesive from an Ext point of view. So hopefully the New Year is going to mean that we’ll be supporting both pretty soon. There’s some pretty cool functionality that’s available in 3.1 compared to 2.2. The end result though, is that a commercial release of our framework will be a little farther down the track than we were anticipating…

APEX 4.0 Early Adopter

As for APEX 4.0 it looks pretty good and is much more functional, pity there’s no new themes available in the early adopter release, would be nice if they had at least one with a similar look and feel to the IDE as it looks much cleaner and more business-like, but hopefully there will be a couple in the official 4.0 release!! Region REST support requires your entire page to be public, not sure if I agree with that but having it there in the first place is brilliant. “Group By” on interactive reports didn’t work as I expected it to (maybe it was me), simply showed me the one column I selected to group by….

I’m also a little concerned about sociability of our existing javascript as APEX defines a non customizable jQuery document.ready function which will cause a little havoc, fingers crossed they provide a switch to easily turn it off for the few who have alot of their own custom stuff in place. Anyway I’m continuing to play with both, it’s a nice Christmas present exploring the goodies in both (for a self confessed geek)!!

But on a whole APEX 4.0 has been worth the wait, I can see my job getting easier by the day, problem is we need to find a commercial competitive edge, and its hard to do that if APEX covers most of the bases. That said I still think that Ext will be the dominant widget company in the web application arena (if they’re not already) so aligning with them is a recipe for success, combining that with the productivity benefits of APEX and the Oracle RDBMS (11gR2 has so much cool stuff) I think we’ve got our competitve edge! ….. as long as too many people don’t catch on ;-)

Tagged with:
preload preload preload