Showing posts with label Plug-ins. Show all posts
Showing posts with label Plug-ins. Show all posts

Tuesday, 18 February 2020

APEX Component Settings for Switch

While I point out a 'hidden' setting for Switch items in APEX, I want to comment on two related item types found in Oracle APEX => radio buttons and checkboxes.


1) Radio button

I really think the standard Template Option for radio groups should 'Display as Pill Button'

It really provides a simple and effective UX when a small set of options are on offer. Touch devices can select the option as if it's a button, and mouse users only need one click, compared to a select list requiring two. And the click doesn't need to be precise for those tiny radio group circles. I wish the application builder adopted the pill button approach more often.

And it's real easy to hook a dynamic action on change of the radio group, perhaps to refresh a classic report with data limited to the selected option. (Don't forget to add page items to submit!)

2) Switch

The Switch item was the answer to a number of methods of deploying an "iPhone-like" on/off switch.
I actually wrote an (internal) item plugin to do just this, but I much prefer using the native option.

A frequent question relates to how switches are rendered. If you don't see what you expect, have a look in Shared Components -> Component Settings.
Application -> Shared Components -> Component Settings

Personally I prefer the 'Pill Button' look, for reasons above. I find the APEX Application Builder seems more washed out with all the Switches in the properties bar, compared to the more softened On/Off pill buttons. If I could change this at the builder level, I would.

The offerings will vary depending on your APEX version, and if the application's Universal Theme has been refreshed

Application level settings for plugins can also be found in Component Settings, in addition to built-in APEX feature tweaks. These can something you choose to review after an APEX version upgrade.

3) Checkbox

It seems the humble HTML checkbox will always be extant, regardless of the pain it brings to tabuler forms. However, it suffers the same precision requirement as the native radio group selections - though better deployments allow selection using the label as well.

Go with the Switch (as a pill).

What do you think?


Thursday, 28 November 2019

Interpreted code in APEX

A few years ago I posted a comparison between plugin code left in the source attribute, vs code that has been transferred to a PL/SQL package.

In the interests of good science, and I wanted to chat about it at next week's Office Hours, I wanted to repeat this test.

I had a little difficulty working out how I got the metrics, I think APEX debugging has changed a little since I ran the test. Instead I considered looking at v$sqlarea to assess performance.

Turns out I quickly found the relevant queries using the following SQL, which a case statement to help me identify the difference between rows each time
select
  case
  when sql_text like 'begin declare  begin wwv_flow_plugin_api.%' then 'API'
  when sql_text like 'begin declare function x return varchar2 is begin return null; %' then 'call dynamic'
  when sql_text like 'begin declare FUNCTION enkitec_sparkline_render%' then 'parse dynamic'
  when module = 'SQL Developer' then ' me'
  end which
  ,executions
  ,loads
  ,parse_calls
  ,disk_reads
  ,buffer_gets
  ,user_io_wait_time
  ,plsql_exec_time
  ,rows_processed
  ,cpu_time
  ,elapsed_time
  ,physical_read_requests
  ,physical_read_bytes
  ,lockeD_total
  ,pinned_total
  ,sql_text
from v$sqlarea
where sql_text like '%sparkline%'
order by which
When APEX invoked the code using an API call, it looked like

begin declare begin wwv_flow_plugin_api.g_dynamic_action_render_result := apx_plug_sparkline.render (p_dynamic_action => wwv_flow_plugin_api.g_dynamic_action,p_plugin => wwv_flow_plugin_api.g_plugin );end; end;

When APEX needed to parse the entire function, it looked like

begin declare FUNCTION enkitec_sparkline_render ( 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

To do this test, all I needed to do was paste the PL/SQL back into the source attribute; I didn’t bother changing what was invoked in the callback fields.

After 50 page refreshes each in dev – parsing the code was at least twice as slow, based on CPU time.

I suspect the 'call dynamic' was the builder validating the code.

Basic glimpse

In an environment with more activity, I was able to compare the standard API call with a few hundred that included parsing the code.

Click/tap to embiggen

If I take 141312 CPU time, divide by 301, then multiply by 17778, I get parsing around 1.8x the amount time as using the API.
The same goes for elapsed time, while the PLSQL Execution time remains the same.

Plus there’s disk reads, an obscene amount of buffer gets, considering the execution ratio.

I tried a second plugin (nested reports), and while the CPU ratio seemed the same, the physical reads were over twice as high.

Remembering this is just placing the code in the box – I haven’t even referenced it.

Too many words and numbers? How about a graph.

If this seems a fair reason to reduce the amount of interpreted code you have…

Twice the work, for nothing.

... then how does this make you feel?

What's a buffer, and why do we want to get it?

It seems by removing the code from the source attribute of the plugin, we measurably reduce the amount of work the database does. Imagine if we reduce our PL/SQL usage throughout the application?

So I conclude

  1. Use bind variables
  2. Put your code in packages

Wednesday, 20 December 2017

On Controlling Use of Minified Code in APEX

Today I encounted an issue during regression testing for 5.1. An older application that doesn't use the Universal Theme, and hasn't really been touched since 4.x, complained about the SkillBuilders modal page plugin.

The solution seemed pretty clear upon reading through this forum post - just update the relevant jquery.colorbox.js file to the latest version, no problem.

I just updated the minified version on my dev instance, jquery.colorbox-min.js, but saw no effect. After checking the code in my relevant plugin package (since all our plugin PL/SQL goes into packages), I saw it wasn't actually using the minified version, and it got me thinking.
apex_javascript.add_library(
      -- p_name      => 'jquery.colorbox-min',
      p_name      => 'jquery.colorbox',
      p_directory => p_plugin.file_prefix,
      p_version   => NULL
   );
Quite some time ago I remember learning about the #MIN# substitution string. The idea is you include files using my.file#MIN#.js, and it only used the minified code when you weren't in debug mode. (That double negative is just for Eddie.)

Item help when adding File URLs
My initial thought was to add it myself, based on the value of debug.
apex_javascript.add_library(
      p_name      => 'jquery.colorbox'||case when v('DEBUG') = 'NO' then '-min' end,      
      p_directory => p_plugin.file_prefix,
      p_version   => NULL
   );
Only to quickly realise the apex_javascript.add_library API has a dedicated parameter for such a task, though it expects dot notation in the filename, not a dash: my.file.min.js
apex_javascript.add_library(
      p_name      => 'jquery.colorbox',
      p_check_to_add_minified => true,
      p_directory => p_plugin.file_prefix,
      p_version   => NULL
   );
What surprised me though was looking through the other plugins. I couldn't find any in my current data source that used the p_check_to_add_minified parameter, they all just expected its use.

Do plugin developers not bother with p_check_to_add_minified?

Perhaps the newer plugins at apex.world use the parameter, if so I'll stand corrected.

Or perhaps there's little value for its use in our data driven pages, once the plugin is up and running. Any APEX plugin authors care to chime in?

Thursday, 21 April 2016

Improving PL/SQL performance in APEX

One of the simplest tuning techniques to encapsulate PL/SQL used in APEX within packages, minimising the size of anonymous blocks. This applies to any PL/SQL within the page, including computations, processes, plugins, dynamic actions, validations, shortcuts and dynamic PL/SQL regions.

This change can make a big impact in the execution time of PL/SQL as it's processed at compile time instead of being parsed and compiled at runtime as dynamic PL/SQL.

Plug-ins can be wonderful black boxes and consumers may not care how it works or looks under the hood. I have a few other views on the use plug-ins that I'll share on day, but this post looks at a way you can always improve it's performance by shifting the supplied code into a PL/SQL package.

Example of freshly imported plug-in in APEX 5.0

You (re)move the code that's supplied and defined as a procedure in your own package, perhaps apx_plugins.

Then modify the "Render function name" to prefix the call, ie: apx_plugins.render_save_before_exit

I gathered performance data on two plugins using compiled vs dynamic code. The following graph shows the relative difference in rendering time between the two using 11g, where the red dots display how many data points I used.

APEX Plug-in Performance - Dynamic vs Compiled PL/SQL
This particular information was garnered from debug log execution time.
select message, avg(execution_time)
from apex_debug_messages
where message like '%sparkline%'
group by message;

Update: I have used Oracle's instrumentation to get better figures
http://www.grassroots-oracle.com/2019/11/on-interpreted-code-in-oracle-apex.html

The recommendation to move this code can be found in (At least) the help text for plugin PL/SQL and documentation.


Moving code to packages will also overcome other limitations such as how much code fits in the attribute, though I think this boundary should only be reached in extreme circumstances. The Excel2Collection plug-in is an example. The author had to compress the PL/SQL code to make it and be packaged as a plug-in.

Encapsulating PL/SQL also provides more opportunity for re-use, reducing chance of defects and
allowing more granular version control.

I would like to think Oracle Forms developers have been doing this for years, in part to help minimise network traffic.

If I'm not mistaken, the same concepts can be applied to complex SQL, moving them into database views.

Daniel Hochleitner has also blogged on this topic.

Friday, 10 January 2014

2013 Blog Review

Just like every other tom, dick & harry on the internet, I thought I'd look back at the year that was.
Keep an eye out for interesting tangential and useful links.

A vague attempt at humour

Readership continues to grow. Rapidly. From my first full year (2010) with 5k visits, I'm now at 50k visits & 69k page views for 2013, averaging 70 posts per year - cool stuff!

I've been impressed with the growth of referals from google/yahoo/bing searches, and the top pages reflect that in regard to the year published - four from previous years.
Either people are searching for these topics (as search terms suggest), and/or people are bookmarking/remembering my blog as a place to visit - so thank you.

On blogging


Other things come above raw numbers, however, and what I find enjoyable about my job is learning. Learning things well comes with trying to describe it to others. 

That being said, I think I've got the knack of blogging regularly. This year I tried to output one technical entry per week, usually on a Wednesday, but it always depends on the post. I found a oraclenerd's 2009 review, and he had an era where he was posting something every day or so. I'm happy with one a week, with maybe the odd non-technical thrown in.

As many bloggers do, I have plenty of ideas in an e-mail folder - and that thing about learning? I find converting snippets of code & thought into blog posts a good source of reference and when using a tool like APEX you need your references only a click or two away.

I think I'll be further updating my blog reference map - I'm starting to use that frequently now, along with my recently sorted APEX bookmarks that includes documentation, how-tos and sample apps.

Issues


I've switched to google+ commenting, and while I like the integration - I'm missing people's comments, not seeing accurate comment counts in the blog homepage. Searching in chrome hiccups when it detects the site you want to search on - did the same thing as the search widget - no search results.

I'm considering moving to an APEX based blogging platform - but it might tempt me to import my back catalogue using XML from Google Takeout. Wouldn't that be fun?

So now onto the pages and behaviours that make this journey interesting.

Top visited pages


Note which year some of these were published - only two-ish from 2013.
  1. Upgrading to apex 4.2 in three steps (2012) -- done on my laptop, basics only
  2. CSS pulldown menu (May 2013) -- common request, neat solution
  3. Form report tutorial (2011) -- what I mostly aim for in this blog
  4. Modify login page (2011) -- includes link to modifying workspace page
  5. A common oracle error (2012) - an experiment based on some search results. Hypothesis verified.
  6. Tree region use case (Feb 2013) -- honourable mentioned because of when published

Top Referrers


Thank you for those linking to my pages, talking about them, reading them, searching & opening them. I hope you find things as useful as I do. There are also some predictable behavioural differences compared to 2012.
  1. ODTUG - Not surprising since moving from apexblogs.info
       #63 apexblogs.info - down 100%
  2. Twitter - I post all posts here, given recent social media trends, and #oraclapex, I'd expect some throughput
  3. scoop.it - should bloggers be concerned? it seems to attribute authors and encourage site visits. WOT doesn't say anything nasty.
  4. orana.info - from nothing to something? I was added in 2009, but only 1 visit recorded from 2012?
  5. apex.oracle.com - I've referred to my posts a few times when answering questions
  6. Feedly - of course... long live google reader!
  7. Feedburner - must relate to greader? down 61%
I found apex blogger love at a number of places. A humbling pleasure it is to be on people's blogroll.
  1. #10 oracle-and-apex.com - on all things extending apex (only a comment and backlink?)
  2. #12 www.oraclealchemist.com - ACEriffic all-sorts (a mention... in a massive collection of 12c articles)
  3. #13 mikesmithers.wordpress.com - The anti-kyte (blogroll)
  4. #14 oraculix.wordpress.com (a mention regarding coalesce)
  5. #20 sqlcur.blogspot.com (a mention about a post on trees)
  6. #23 dbswh.webhop.net - an APEX jQuery guru I may collaborate with this year (blogroll)
  7. #49 oracleinsights.blogspot.com - a fellow Aussie (mention)
  8. #68 jeffkemponoracle.com - many woven interactions with this fellow Perth blogger, who unknowingly seeded my drive to blog.
  9. #81 inside-oracle-apex.com - good internal APEX resource (a few mentions, comments)

My top 10


I perused the 2013 archive and decided on favourite posts of my own - either those I visit regularly as a reference, or those that have helped my journey as a software developer.
  1. Learning APEX - I'd recommend these particular books depending on where you are on the spectrum.
  2. Customising workspace login - I do this for training, differentiating environments or just being a control freak.
  3. Starting jQuery - I started to do stuff with jQuery, beginning with client side features I remembered doing in Oracle Forms. Then I moved to tarting up reports.
  4. Customising plug-ins - it's easy to tinker & learn with other people's plugins. I've played a lot with Enkitek's navbar.
  5. Lists shared component - I've really appreciated the simbiosis between lists & templates. You can APEX-ify just about anything you see on the web, typically with a List template.
  6. Performance - I've made a number of discoveries this year regarding performance. A few of them are in my draft folder already.  
  7. Published! - I'm a published author, of sorts - a screencast/video series on Oracle APEX techniques. Not a bad first effort, I think.
  8. 12c - whether c is for cloud or consolidation - it sounds like fun - I want in.
  9. Off topic fav - Tim Minchin is an entertainer + educator - an edutainer, if you will. I plan to share more off-topic randomness this year, I hope you don't mind. Twitterers get it already, google+ posts are mostly science/tech.
  10. Consuming plug-ins - having trouble implementing someone's plug-in? Try this sample application with accompanying instructions.

A fun 'top 5' - cities


Just for giggles.

  1. Bangalore
  2. London
  3. Perth -- my home city
  4. Chennai
  5. Moscow
  6. ...
  7. #7 NY (top US city)

Predictions


At the start of 2013 I made promises regarding posts on mobile, RW, Ubuntu and what search terms showed me.
  • I haven't explored the mobile theme as much as I'd hoped, but I've been involved in a great tablet project. 
  • RWD pains me and I'm still getting the hang of manipulating APEX's templates. I wonder how much this will change in APEX5.
  • Ubuntu's been flowing like pitch (again), but I have been learning plenty of jQuery. I'm really loving it and plan to continue sharing things I've learnt - one in the form of a prezi.
  • 4.2.y did not deliver a third user interface - but I imagine they held back to make sure it's delivered even better in APEX5.
  • Search terms... meh, I just went where things took me
I did finish the year creating a few simple item plug-ins. That's a garden being cultivated, I'm not sure what it will bring but I'm keen to explore more. The penny has dropped and the gates are open!

As hinted, in 2014 I predict heaps of posts about APEX5, looking at IDE, modals, interactive reports, templates, tablets, editing layouts & hopefully not lacking improvements in release management & page/region caching control. No doubt APEX will deliver other surprises to find along the way.

This year I also hope to implement a PhoneGap delivery; learn more about jQuery; and deliver some more public facing APEX applications.  It would be nice to develop on 12c, but I'm not holding my breath.


Here's to averaging a post per week!

ps - I'm also increasingly curious about Big Data...

Tuesday, 19 November 2013

Spice up your APEX application with third party plug-ins

At this year's Australian Oracle User Group Insync13 conference series I conducted a half-day workshop in Melbourne, Brisbane and Perth called "Spice up your APEX application with third party plug-ins"

I selected some commonly used plug-ins that I thought would be interesting and showed attendees how to download, configure and use them. I hoped this would build further awareness of the usefulness and expandability of APEX 4.x

I spent the first 10-15 minutes introducing what plug-ins are all about, and you can find link to the slides here.



I have a tutorial application that demonstrates the eleven GPL/MIT licenced (available for commerical use) plug-ins I chose do illustrate:
http://apex.oracle.com/pls/apex/f?p=PLUGIN

Future readers may find this useful as I've also listed instructions on how to use each of them.

Plug-in instructions
You can now ignore the 'claim workspace' section. On a side note, when running workshops at conferences I certainly learned a few ways to make things run more smoothly!

You can also download setup scripts to run the application in your own environment from here
sagecomputing.com.au/workshops

Many thanks to the author's of the APEX plug-ins that make our lives easier!
Find more at apex-plugin.com

Scott

Wednesday, 8 May 2013

Freezing the Navbar Menu plugin to top of page

Recently I blogged about a nifty CSS only menu that is a great alternative to the horrible APEX tab-sets. Unfortunately I had to ditch it for a recent project because it didn't work well on touch screen devices, so I picked up Enkitec's Navbar plugin instead.

I wanted to freeze the menu at the top of the page, so when the user scrolled down, the menu would remain at the top of the screen.
I tried doing this some time ago with a side-bar menu but came across a bunch of problems - this time round it required very little CSS to make it happen. This stackoverflow post suggested 2 lines, but my APEX example extended a touch more:
.navbar {
  position:fixed;
  width:100%;
  z-index:10000;
}
.apex_span_12, .apex_span_10 {
  margin-top:50px;
}
The key is the position fixed, width 100%, but the fixed position had some minor side effects - some objects overlapped my menu, and all existing content shifted up underneath the menu.

To fix the overlap I used z-index, which is the third dimension beyond height/width and decides which components appear above another when the position is set. I added a large z-index value so the menu always overlapped other objects I had such as a google map, CSS checkbox switches and other maps that by default went over the menu instead of under like all the APEX components.

Then I had to make sure all my regular content started underneath the menu, so this is where the margin comes in. Since I was using the responsive Theme 25, I identified those classes as the lowest common denominator for moving my content.

Depending on the page template used, it was either of those classes - basically if I had a side-bar region the apex_span_n changed. I'm happy to receive feedback on a smarter solution, but this worked for me.

I used 50 pixels, but the font in my menu is at 130% to benefit bigger fingers on the touch screen.

Hope it helps!

Scott

Wednesday, 24 April 2013

Implement Bullet Sparkline using extended Enkitec Plug-in

This post details the implementation of an extended version the Enkitec Sparklines Plug-in to include bullet charts. Previously I posted how this extension was made.

First you need to download and import the plug-in. Once this is done, you can define the data used, then create a dynamic action to convert the data into the sparkline chart.

In my case I didn't need to consider string aggregation techniques as my data came from different fields. I defined a dynamic PL/SQL block that generated HTML similar to
<span id="jobBullet">12,15,15,13</span>
Where the values are respectively Target (red line), Performance (inner blue line), Range (full background shading), Expected (first layer of shading, near red line)

Target, Performance, two ranges
We will probably use the inner blue line to represent "expected" target, and have just one background colour, so this data set would not have the fourth number.
Target, Performance, Range
I found the jQuery Sparkline documentation lacking when attempting to modify the tooltip values.
I ended up finding the information I need in the related Google Group.
tooltipValueLookups: { fields: {r: 'Range', p: 'Performance', t: 'Measurement'} }

This information forms part of the onLoad dynamic action that will convert the span of data into a sparkline.

The action utilised comes directly from the plug-in definition: Enkitec Sparklines [Plug-in]
I directly identify the data span with the jQuery selector #jobBullet
When generating a sparkline for every row in a report, it's likely your selector will be a class.
I wanted my sparkline to be larger, so I adjusted the plug-in to allow me to enter the common width property each time.


My next step is to parameterise the colour scheme so I can modify the Performance colour to be green or red, depending on the Target value.

Extend APEX sparklines plugin to include bullet chart

Dan McGhan recently announced a new plug-in using sparklines. This post details how I extended the plug-in to support another chart type. A separate post details how I implemented this in an application.

If you haven't seen them, check out his brief summary - there's a great image showing examples of those he's built into the plug-in from those available in the original jQuery plugin.

They are basically word/sentence sized graphs - which I think are great because a picture often paints a thousand words.

Out of all the info I've read since coming home from leave, this really stood out because I knew some perfect applications for them in a current project - using the bar chart with negative values, it can display a visual indicator for the users that encourage them to target "zero", which is a big culture change in regard to what's being attempted.

Since I was curious, and noticed they had only enabled some of the available charts, I checked out the documentation on the jQuery plugin and saw the bullet charts. These were another potential solution for us since the AnyChart options licensed through APEX did not include horizontal linear gauges.

The APEX evangelists have built an integration kit. I also considered looking into RGraph and jqChart, but since finding the bullet sparklines I tried tweaking the example and scaled it up using Chrome - there was my answer.

My APEX plug-in authoring skills are still developing, as is my jQuery - but I didn't find it hard to adapt Dan's code to include bullet sparklines as another chart type in the plug-in.
Bullet Sparkline - scaled up
I also adjusted the custom attributes to make width always available. I've made an export of the extended plugin available here.

This segment of code shows how easy it was to extend - all I needed to do was modify the attributes to match those in the jQuery Sparklines documentation
ELSIF l_chart_type = 'bullet'
   THEN
      l_js_function :=
         'function(){'|| l_crlf ||
            'this.affectedElements.sparkline("html", {' || l_crlf ||
               'type: "' || l_chart_type || '",' || l_crlf ||
               'height: "' || l_height || '",' || l_crlf ||
               'width: "' || l_width || '",' || l_crlf ||
               'targetColor: "' || l_bullet_target_color || '",' || l_crlf ||
               'targetWidth: "' || l_target_width || '",' || l_crlf ||
               'performanceColor: "' || l_bullet_perf_color || '",' || l_crlf ||
               'rangeColors: ' || l_bullet_range_colors || ',' || l_crlf ||
               CASE
                  WHEN l_enable_tooltips_and_hl = 'N'
                  THEN 'disableTooltips: true,' || l_crlf ||
                     'disableHighlight: true'
               END ||
               CASE
                  WHEN l_additional_options IS NOT NULL
                  THEN l_crlf || l_additional_options || l_crlf
                  ELSE l_crlf
               END ||
            '});' || l_crlf ||
            CASE
               WHEN l_add_click_event_bindings = 'Y'
               THEN
                  'this.affectedElements.bind("sparklineClick", function(evnt) {' || l_crlf ||
                     'var sparkline = evnt.sparklines[0];' || l_crlf ||
                     'apex.jQuery(document).trigger("enkitecsparklineclick", {' || l_crlf ||
                        '"sparklineId": "' || l_sparkline_id || '",' || l_crlf ||
                        '"sparklineObj": sparkline,' || l_crlf ||
                        '"xValue": sparkline.currentRegion,' || l_crlf ||
                        '"yValue": sparkline.values[sparkline.currentRegion]' ||
                     '});' || l_crlf ||
                  '});' || l_crlf
            END ||
         '}';
   END IF;
And just quietly, I really love the floating bookmark index in the jQuery Sparklines documentation.

Thanks Dan, Doug & Enkitec, for the headstart on this versatile solution.

Scott

Wednesday, 13 February 2013

Review: Expert Oracle Application Express Plugins

In Oracle APEX there are probably a few broad classifications of technologist, and I think to create plug-ins as an APEX shared component is probably one of them.

While I have consumed many plug-ins, I haven't created any that aren't security related. And just quietly, the security plug-ins are a fair simple encapsulation of a known entity.

If you want to learn how to create plug-ins using the tools available, I would recommend reading Expert Oracle Application Express Plugins, by Martin Giffy D'Souza.

I started a technical review for this book, but had to pull out due to poor timing - super busy with too many other projects. Publishers apress kindly sent me a copy of the book regardless, which I read on train rides to work.

Chapter 1, Introduction

Fairly short but concise description of what is covered in the book. Again due to poor timing, Martin was unable to include the authentication & authorisation plug-ins - but on fundamentals alone you could build these no problems after reading half the book.
So it covers dynamic action, item, region & process plugins; and mentions to the reader you should be reasonably versed in PL/SQL, JavaScript, jQuery, CSS & HTML - which generally the demarcation from a typical APEX developer.

Chapter 2, Plug-in Fundamentals

Using some simple examples, it builds a pretty good picture on the required infrastructure for a plug-in.

Chapter 3, Item Plug-ins

A very thorough guide to building a date-picker item plug-in, probably the most popular & UI related plug-ins you'll encounter. I've had a few ideas & needs for item plug-ins, such as a Forms style combo-box that operates as a select list of an LOV as well as a free text input. If I had the time, this chapter would be my "right hand man" for building it.
As with much of the book, it's very syntax heavy - so be prepared for that. However, it's quality code - well structured and  is a good reference.
You are also introduced to the console wrapper in this chapter.

Chapter 4, Dynamic Action Plug-ins

First Martin does well to describe how dynamic actions work, then goes into an example of creating a modal dialog.

Chapter 5, Region Plug-ins

Again Martin sets the picture and talks about the importance of AJAX. He then pushes us in to the deep end by building a region to display titles from an RSS feed.

Chapter 6, Process Plug-ins

Process plug-ins are a great example of basic software engineering, where we can encapsulate complexity and increase reusability - the major tenant of plug-ins. Martin uses this to create the black box that is to send a message to a mobile phone. He doesn't forget to include the technical requirements for this using SMTP.

Chapter 7, Best Practices and community

The best thing about plug-ins is you don't need to write them, you can just consume them as part of the community. But of course, they introduce the concept of "cost of not writing the plug-in". Martin also covers security, instrumentation, commenting, templates, versioning, compression & error handling - lots of goodies ;-)

Chapter 8, Debugging & Tools

After meeting Martin in Melbourne last year, I found one of his APEX strengths is instrumentation, debugging & coding design. This chapter takes a much closer look at the JavaScript Console Wrapper, APEX debug, browser tools, jQuery UI Widget factory, the Apache HTTP server and finally the APEX APIs & data dictionary.

Summary

Certainly a very technical book on APEX plug-ins, but to become an effective plug-in developer you would expect nothing less. Even as a consumer of plug-ins, it wouldn't hurt to have a better understanding of how they work & fit together. Certainly, if you end up having to write one, this is is the best reference out there.

Related Links

Community Plug-ins
Oracle Plug-ins
Commercial Plug-ins

Scott







Wednesday, 30 January 2013

Dynamic Action hidden False actions

I thought I'd share what's quite literally a hidden problem I experienced in 4.1.1 involving dynamic actions.

The project used hundreds of dynamic actions, and often I would copy them between pages.

Something to watch out for, however, is the cleaning up APEX does with dynamic actions in it's own builder. I've notice in the past the meta-data I saw in dictionary views contained stale information, hidden after no longer being needed when adjusting some other attribute - like condition types.

By looking at the stock debug, I noticed that a good portion of my page render time was for dynamic action plug-ins. One of these was for the notification plug-in supplied by Oracle (gritter). Over time the number of notifications on the Global Page Zero had grown - but in my case could be consolidated using &ITEM. substitution syntax to define the title & message.

But there were still more instance of the gritter notification in the rendered page sauce than was expected, so I looked a little harder...

In regard to dynamic actions, beware the non-condition - in past I must have copied this from another action; removed the event "when" condition; the false action region was hidden from the developer, but and a false action remained - causing unnecessary rendering of a plug-in, hence performance issue. What a paragraph, hope that made sense!

All I saw when editing the item were the True actions.
True actions for DA with no JavaScript "when" event condition
By changing the when condition to "equal to", I was able to see the previously hidden False action.
screenshot actually from 4.2
Sure enough - there it is
A hidden False action, displayed when condition restored
So I had a few false actions to remove that would never fire.

You can find such cases yourself with the following SQL - I used this query to check for other issues.
select * 
from   apex_application_page_da d
-- no when condition present
where when_condition is null 
--and dynamic_action_name = ''
and application_id = 104
and page_id = 0
and exists  -- a false condition
  (select null 
   from apex_application_page_da_acts a
   where a.dynamic_action_id = d.dynamic_action_id
   and dynamic_action_event_result = 'False')
/

I saved about .05 seconds each plug-in render, so notifications in page zero added up over time. I saved about third of a second in my clean up of these alone. Plus I was finding other minor performance gains - they all add up!

Scott

Wednesday, 18 July 2012

Apex - closing modal page on escape

I've been making use of the Skillbuilders Modal Page plug-in a fair bit recently, and I thought I'd share this little ditty on closing the dialog when the escape button is pressed.

I set the event to Key Release, using the 'document' DOM object.

The JavaScript condition is set to 'event.which = 27' - the ASCII translation of the escape key.

Finally, the true action closes the window, passing nothing back to the calling page
javascript:window.parent.$(window.parent.document).apex_modal_page('close','');>

Inline images 1

Of course, aside from the action - the same event can be captured if you're listening for the escape key for whatever reason.

Hope it helps.