Showing posts with label Universal Theme. Show all posts
Showing posts with label Universal Theme. Show all posts

Wednesday, 16 October 2024

Upgrading Forms compared to APEX #JoelKallmanDay

My current project has involved rebuilding the entire aging stack for an environment that's currently 95% Forms, with any new work developed in Oracle APEX. The upgrade covers all layers -  from OS, to DB, to browser, and to application builders - all heading to contemporary versions.

The general directive is like-for-like, so the applications should work the way they used to, if not a little better.

So to dumb down the process, we basically need to recompile everything on the new stack, fix the gaps, then test extensively.

***

It's been an interesting project to compare the type of effort required to uplift a large Forms application compared with a modest set of Oracle APEX applications. I do this with the awareness that it's like comparing apples and toaster ovens, but the outcomes have been interesting enough (to me, at least), that it's forming the basis of my next presentation.

In fairness, there wasn't too much in regard to general syntax used within Forms that needed addressing. Nothing has significantly changed in Forms functionality, and we just needed the app to function as it did previously. 

There were a few environment level settings we found to help with some backwards compatibility, thereby saving some rewrite. 

From an infrastructure perspective, however, there were a number of aspects we needed to tackle to keep up with the modernisation of the stack. This included the launcher (Applet->FSAL), the SSO mechanism, document (blob) handling, and guiding the application to a tidy close after a timeout occurred. Compared to Oracle APEX in a modern ecosystem, the sting of that last item will linger.

***

This application has a considerable amount of blob content stored in (now deprecated) OrdImage data types, so that one item took up a considerable portion of effort - from shifting the data; to modifying the UI to load and view the attachments.

Oracle APEX came to the rescue for this case, replacing an old mod_plsql interface that supplemented a Form, and an ancient looking webutil UI in another.

The saddest part of the Forms upgrade was the amount of time I needed to spend ensuring session timeout didn't get the user stuck in a dead session. Part of me kept thinking how much of that 95% we could have started to shift to APEX with that time... 

***

As for the APEX applications, we took advantage of the testing that was going to happen and updated the Universal Theme (UT) of the applications.

Prompt to upgrade the APEX UT

I'm working through the issues that came out of this for the presentation, but most of the issues we needed to remediate were due to the UT update - not the upgrade of the database and the Oracle APEX version. And even then, most of the issues are relatively benign UI differences which don't need attention. A good handful of which were on purpose, for the benefit of APEX users - just against the fine grain of "like for like".

We could have upgraded both the database and the APEX version, left the UT alone, and only had a few minor version related adjustments to take care of - then still have a nice new bag of tricks to explore.

This is a far cry from earlier days of APEX where a big hurdle to upgrades was contemplating the significate cost of migrating to a newer theme with improved considerations.

But again, this wasn't necessary. I recall Joel presenting a session where he took an APEX application built some time ago, spanning a gap of multiple APEX versions. He just imported the application, and it ran without change - even when APEX was still a comparative youngster.

This methodology and mindset hasn't changed. I've done a few APEX upgrades in my time, and my recollection of any issues were related to heavy customisation - rarely native usage. Any native changes were always well documented, with a guide to transition to what is an improved outcome.

***

So today I share this heavily abbreviated and filtered anecdote of my recent explorations with Oracle technology, and once again remember Joel as a guiding force to help transform Oracle APEX into a development tool that has longevity without heavy maintenance, while still making the developer's life easier each release. 

And also a feature haven for those Forms developers out there.

I can even draft next year's post with another small side story from this upgrade project, reaching deeper into the past of Oracle APEX.

Tuesday, 3 December 2019

Include new APEX templates in an older APEX instance

Have you seen that super awesome theme in the new APEX version, then wondered how long it will it be before your site upgrades so you can actually use it?

What if I told you that your current version could be retrofitted to use that template?

I really like the look of the Content Row template, I think that's going to serve many developers good purpose.
Sure, I could create something similar now, but if I do as much as I can the same, then it should grease the wheels come upgrade time.

Content Row 18.2 vs 19.2

To make this happen, I
  1. Downloaded APEX 19.2
  2. Copied the /theme_42/1.4 folder to my 18.2 instance
  3. Created the report template, including template options
  4. Added the region component in my app
The first two steps are all about making the relevant CSS available to your instance.

After I had the /1.4 folder in place, I thought I would need to increment the Theme folder, but that just introduced other issues.


Instead, I just referenced the ContentRow.css file in the pages I wanted to use it.
This is the path where you can find it, so it can be placed wherever you like on your older instance.
/i/themes/theme_42/1.4/css/core/ContentRow.css
Alternatively, you could include this for all pages in the User Interface attributes.

Then I needed to create the named column (row template) in my 18.2 application, details of which I just copied from a 19.2 instance.

Content Row syntax

I can even transfer the template options, so I started transferring from details on the page
You can also use this query to find instances within my 19.2 application.
select name, display_name, display_sequence, css_classes, group_id
  ,(select display_name
    from APEX_APPL_TEMPLATE_OPT_GROUPS
    where template_opt_group_id = group_id) group_name
  , help_text
from APEX_APPL_TEMPLATE_OPTIONS 
where application_id = 32532
and report_template = 'Content Row'
order by display_sequence
Then I created the template options in 18.2.

Add Template Option

And sure enough, they become available on my 18.2 region component.

Page Designer outcomes

Due to the differences in availability of template option groups, some manifest a little differently, but I personally prefer a one click checkbox to the more fiddly select list.

All that said, I'm not sure I'm entirely sold on the small screen format, though maybe thing will change when I get more realistic data in there.

Content Row - mobile

Now I'm sure when I change over to use the actual template when I'm in 19.2, I'll need to re-apply the template options - but Shakeeb likes the idea of retaining shared template options, so you never know.

This was all done in 18.2. If you're on an earlier version, your mileage may vary.

If you're not using the Universal Theme, then you're probably not going to get very far.

Wednesday, 18 September 2019

APEX 19.x Dark Mode CSS Extension

There have already been some insightful posts about APEX 19.2 Early Adopter, plus an interesting feed of features on Twitter, as they're discovered.

Sven has a great summary.
Adrian comments on markdown.
Mike is really plugging faceted search on twitter. I particularly look forward to playing with that one.

I couldn't resist giving the dark mode a test spin.

I immediately experienced the same contrasting issues from the original clean skin that 5.0 gave us, plus a few minor adjustments.

Spot the difference

Tweaks so far include

  • Region header
  • Delta icon
  • Text field background
  • Scrollbar width
  • Save message location (not seen)

I'm still trying to decide what the best contrast is to break through the darkness on the vertical scroll, but it's a good start.

As Mike Hichwa suggested, the experts may give this a twirl in 20.1.

You can find the CSS I use in this Github respository, but switching between the two modes will require manual interaction with the style extender, since there are no dark-mode classes to utilise.
https://github.com/swesley/orclapex-builder-css

I'm trying to lift my game a little, get more organised, and improve my markdown game.

Edit: Since I'm currently doing most of my work in 18.1, I forgot 19.1 introduced dark mode, not 19.2.

That said, I think Vita - Dark style added to the 19.2 Universal Theme offers better contrast than the page builder itself.

19.2 Dark UT style

Why do the users get the good stuff? ;p

Wednesday, 24 April 2019

APEX Classic Report as Alerts

I love classic reports.
You can make your data look like anything, out-of-the-box, as previously highlighted by Christina and Carsten.

When you create a classic report, you can select different Report templates via the region attributes. I use the Cards and Alerts a fair bit, allowing me to produce data driven content, instead of whatever I type in the application builder.

This has been the general premise of APEX templates since the beginning. We define a query, and feed those columns to the template, where the values are substituted in.

Alerts Report Template
We can combine this template with the following query, containing matching column aliases.
select 
  'Alert' as alert_title
 ,'Be alert, not alarmed.' as alert_desc
 ,null as alert_action
 ,'danger' alert_type 
 ,'fa-user-woman' alert_icon
from dual
This doesn't need to be from dual, it can be any query you like, as long as it contains those column aliases. Multiple rows will show multiple alerts, down the page. The alert_type can be any of the pre-defined template options for that attribute.

Over time these templates get upgraded, and now we operate with the Universal Theme, we gain access to improvements after verifying the theme.

For instance, APEX 5.1 introduced #CARD_COLOR# attribute to limit the manual CSS required to make it happen.

What the Alerts Report template still lacks is the ability to customise the icon (as at 19.1).


We can customise the icon with a declarative Alert Region, by setting the Template Option Alert Icons to 'Show Custom Icons', and specific the icon in the Icon field.

If we want to customise the output of a classic report displayed as an alert, we can use an After Refresh Dynamic Action that executes JavaScript on page load to rejig the HTML of the report.
// replace icon in template, since we can't do it in SQL yet
$('#acting .t-Alert').removeClass('t-Alert--defaultIcons').find('.t-Icon').addClass('fa fa-user-woman')

Here I find the region I gave a static ID of 'acting', then removes the default icons from the component with the t-Alert class.
It then finds the t-Icon class to extend with my chosen icon.
This transforms it to exactly what a declarative Alert region looks like.


This example was built for a report with only one record, but hopefully gives you an idea of the potential these type of events have. Check out similar example here.

Happy APEXing.

Saturday, 30 March 2019

Hide Pagination if one page results - Oracle APEX

I love this period of development not long after an APEX upgrade, where I discover all these little improvements that will help us out. Stuff that's not quite noteworthy in the wonderful read that is the new features guide (that's not sarcasm. Read it. Now.)

Recently I made an observation regarding a handy new template option, one that hides pagination if there is only one page of records. I've had a bit of jQuery doing this for a while, and I thought I had blogged about it already, but it was a similar feature regarding no data found.

Sure enough, it was still sitting in an email labelled 'blog post'. Now I could write this off, like quite a few others where a built-in feature got released before I got around to writing up a post. But I decided to post about this one anyway, in part because it may take some time for some to reach 18.2, and I think it's part of an interesting conversation regarding the evolution of the product.

Some of the improvements in each APEX release are likely the result of
- a tweet about a feature
- a forum post asking about a quirk
- a conversation at a conference, likely while at least one person was holding a beer
-  a request on apex.oracle.com/vote

If you notice something odd, or think something you've done would help everyone, put it out there.  Chuck it on the forum. Make it your first blog post. You'll help the community, and reap the benefits yourself when the time comes to upgrade to that version with some delicious fruit.

--***

So, that being said, here was the template option, available in APEX 18.2, but only to existing applications only after refreshing your theme.

Classic Report Region Template Option

Applied to a classic report, it will hide certain pagination styles with there is less records than that specified per page on that report.

This will save me creating a dynamic action on the region, calling a small bit of jQuery I have in a library. It's also something I figured could be practice for turning into a plug-in, but I never got there, either.

The trouble is, this template option doesn't appear to work with my favourite pagination type (another reason for the post).

I like to use the Search Engine pagination style, on the top left - available to the user regardless of vertical/horizontal width of the region. I have chapter in my book describing how to turn standard HTML links in this search engine pagination for a legacy theme into buttons.


Trouble is, it seems a little superfluous when there's only one page of results. And it takes up vertical space. Hence the idea of the template option.

With a little JavaScript invoked in a dynamic action after refresh on the region - this is the default dynamic action when you right-click to create dynamic action on a region in page designer. Kudos to the APEX developers responsible for those little touches.


Here's the code I used to do the job.
if ($(this.triggeringElement).find('.t-Report-paginationText').children().length == 1
  && $(this.triggeringElement).find('.t-Report-paginationText').children().text() == 1)
    $(this.triggeringElement).find('.t-Report-pagination').hide();
A few points:

  • this.triggeringElement refers to the region, since that's what the dynamic action is firing off
  • find() is looking for page elements with the t-Report-paginationText class, in this case, the button group
  • children() counts how many buttons, so true if there is only one
  • I added the second condition when I realised it was hiding results when there were 11 pages of results, so I check if the button contains the text "1"
  • then it applies .hide() to the pagination group

Note, this is designed for Search Engine pagination in the Universal Theme, and the template option probably works with a different mechanism. There might be a clever way to solve this with CSS?

The real solution also belongs in a library so it can be re-used. I did it like this once, but I'm sure it could be neater.
function hide_pagination_iff_one_page (p_region) {
  if ($('#'+p_region+' .t-Report-paginationText').children().length == 1
  && $('#'+p_region+' .t-Report-paginationText').children().text() == 1)
    $('#'+p_region+' .t-Report-pagination').hide();
}
I would then put this in the after refresh dynamic action. It passes the ID of the region triggering the action, ready for embedding in the selector.
hide_pagination_iff_one_page($(this.triggeringElement).attr('id'));

So my open question is, how would you tidy such JavaScript? how would you place it in a library?
I'm still getting the hang of namespaces, and how to organise our stubs.

Thursday, 23 August 2018

Pseudo Radiogroup in APEX Report

I'd be surprised if you've ever tried to put a radio group in a report, but if you've ever attempted it you might come across a post from Vincent Deelan.

When it comes to checkboxes and radio groups, the nature of HTML haunts us.

So it turns out it's possible to do the same task within a report, and we can build it so we don't even need to submit the page. It really just depends on how you want the page to interact. The following example simply logs the rating selected, rather than a rating being stored as an attribute of Emp.

This is no doubt even easier with Interactive Grids, but I'm not there yet, and I'm sure others aren't either.
And it's fun using Dynamic Actions to make applications more interactive, and revive draft blog posts from a good 18 months earlier. (I've got a few of these...)

I built a traffic light style report once before, but leveraging off the Universal Theme made this effort so much easier.

Consider the template options for creating a pill button group using standard button components.

Button Template Options

If you create three buttons, all with first, inner, last button sets respectively, you get something that looks like this:

Pill buttons
I refer to them as such because if you use the Inspect Element tool on these buttons, the template option classes are named as such
t-Button--pillStart
Check out the UT button builder for more examples.

So to utilise this in a report, I'll combine three manually constructed buttons, levering other existing classes.
select EMPNO,
       ENAME,
       JOB,
  '<span style="white-space: nowrap;">'
    ||'<a href="javascript:void(0);" data-emp="'||empno||'"'
    ||' class="high t-Button t-Button--success t-Button--simple t-Button--pillStart">H</a>'
    ||'<a href="javascript:void(0);" data-emp="'||empno||'"'
    ||' class="medium t-Button t-Button--warning t-Button--simple t-Button--pill">M</a>'
    ||'<a href="javascript:void(0);" data-emp="'||empno||'"'
    ||' class="low t-Button t-Button--danger t-Button--simple t-Button--pillEnd">L</a>'
    ||'</span>'  rate   
from scott.emp

If you remember to Escape Special Characters for the rate columnm you'll see something like this



Now you could slice and dice the dynamic actions in a number of ways, but here I created one for each type of button. So on click of the relevant class I associated with each button type, it will get the value from the data- attribute, put it in a hidden item, then insert a record.


The Set Value action would set some hidden item using the JavaScript expression
$(this.triggeringElement).data('emp')
The subsequent PL/SQL process would submit this item to session state, and insert the empno/rating selection into the log table. The third action refreshes the Rating region so we can see the new data.

We can make the buttons more pill-like but adding a border radius
span a.t-Button {border-radius: 10px;}


To dull the colours a touch
span a.t-Button{border-color: lightgrey; box-shadow: 0 0 0 1px lightgrey inset !important;}


It would only take a few more lines of jQuery to turn this into a status, leaving the active button highlighted. Plus a slight tweak to the SQL to match the relevant record.

Obviously I had a demo of this, but this draft was so old I've forgotten where I put it ;p

Monday, 7 August 2017

APEX Login Background Image Cover

For a while I've wanted to play with cover photos on login pages, and when Keegan asked a similar question on Twitter, I was curious enough to ultimately have a play.

Someone mentioned relevant a reference to CSS-Tricks Perfect Full Page Background Image, but after quickly finding the video Keegan must have screenshotted in her tweet, I realised us APEX developers need to use the following instead of 'html' as our selector.
.t-PageBody--login

Update for APEX 19.2: Days after I had a discussion about limiting the references to Universal Theme (UT) classes, particularly nested ones. I find that my original extended reference of .t-PageBody--login .t-Body is no longer valid in 19.2 UT.
As Peter suggested, it would be great to have a set of release notes to supplement the living document that is apex.oracle.com/ut.
I possibly wouldn't expect this particular example to be itemised, but knowing where to look would be great.

Plugin extraordinaire Daniel suggests
using 16:9 1920x1080 for standard UT use css media queries for different screen sizes with a pool of 2 / 3 images
The example I applied uses a CSS media query to not use a background image for smaller screens, as it may look too busy.
<style>
@media (min-width:400px)  { /* anything but mobile */
  .t-PageBody--login .t-Body {
    background: url(#IMAGE_PREFIX#cover_images/&P101_IMAGE.) no-repeat center center fixed;
    -webkit-background-size: cover;
    -moz-background-size: cover;
    -o-background-size: cover;
    background-size: cover;
  }
}
</style>
I defined this CSS within a region so I could apply a 'dev only' build option. Alternatively, this could be a PL/SQL region, with the code abstracted/encapsulated within a PL/SQL package, possibly utilising the htp package.

Style within Region
This also means the image location and file name are easily parameterised. So your images could be located anywhere, and you could programmatically decide which image to display. And/or use media queries to determine which image should display on the relevant device.

As an experiment, I wondered if I could rotate through a number of images, so each time someone visited the login page, they would see one image from a pool of many. So I defined an item with the following calculation:
'beauty'||floor(dbms_random.value(1,8))||'.jpg'

We can confirm an evenly distributed calculation by running that computation many times and counting the results.
select count(*), val from (
  select floor(dbms_random.value(1,8)) val
  from dual connect by level < 10000
) group by val

COUNT(*) VAL
1413  1
1445  6
1412  2
1420  5
1411  4
1415  3
1483  7
This would randomly select from a small suite of photos in the folder. I've used a selection I've collected from APOD.


And voila, an inspirational login page.

APEX Login with background cover image
I think an improvement would be to show a consistent image while attempting to login. A brief experiment suggests only running the computation when P101_IMAGE is null, and only clearing login fields (not the entire page cache) during page processing.

This could be the final bling you need after pimping your login page.

Don't forget, you can style the backend login, too.

Once again, thank you #orclapex community for making this a breeze.

Wednesday, 29 March 2017

Make Radio Group look like UT Buttons

It's pretty easy to convert links in APEX reports to use the Universal Theme button look & feel, as I described here

http://www.grassroots-oracle.com/2015/12/tutorial-include-action-button-in-report.html

We can apply the same technique to radio groups, but it requires a little more work than just adding some classes, but nothing like jQuery mobile radio fiddles.

It took me a few goes to get the correct string in the correct APEX attribute to make the individual buttons look & behave the way I imagined, so I thought I'd share the journey. Show my working, so to speak.

First, create a radio item:

A humble radio group

Then set 'Option HTML attributes' to add template option classes, just like I did for the report action buttons. This applies the string to each option, rather than the entire item.

class="t-Button t-Button--simple"

If we check the page, the radio group should have button boxes surrounding the text labels.

Radio group with button class


To work out what CSS selector I needed to hide those radio buttons, I used Chrome's Inspect element tool (right click a radio button) so I can see how the HTML is constructed.

Inspect Element is the best browser tool. The best.

One shared property for each item is how the input tag has type=radio.
Further up you can see the entire fieldset as an id of P47_RADIO, our item.
Combine these to identify any radio buttons within this specific item.

Edit page 'Inline CSS' to using this combined CSS selector, with a property to hide any web component identified with that selector.

#P47_RADIO input[type=radio] {
  visibility:hidden; 
  position:absolute;
}

Edit: Commenter Yol had success with visibility:hidden instead of display:none, when it comes to submitting the values. This may be a browser dependent issue.
Hence I have also set position:absolute to ensure the radio buttons don't take up space, as per visibility attribute definition.


This tidies the button group, trouble is,  the current selection is unknown without the native radio button. This can be solved by creating a dynamic action that toggles button classes upon click of each radio item.

Create dynamic action on click of jQuery selector

#P47_RADIO span.t-Button

Add action to Execute JavaScript
// add simple class to all options
$('#P47_RADIO span.t-Button').addClass('t-Button--simple');
// remove from current selection
$(this.triggeringElement).removeClass('t-Button--simple');
// Ensure underlying radio selected
$(this.triggeringElement).prev().click();
The result:



Edit 2: I found that clicking in the green padding area did not change the radio selection, only when I clicked in the blue label. So I added the third line in the JavaScript to ensure the input value simulates the click event.


In my case the t-Button--simple template option is removed from the current selection, but you can play with these options to choose a combination that suits your desired contrast, using the various colours:

t-Button--danger
t-Button--warning
t-Button--success
t-Button--primary


Or "hotness", a highlight:
t-Button--hot

Or contrast, well, not highlighting the entire button:
t-Button--simple
All demonstrated in the button builder reference in the Universal Theme app.

You can achieve consistent button width by adding this to your Inline CSS:
#P47_RADIO .t-Button {width: 100px;}
After your page loads, you can use the inspect element tool and increase the width 'live', to find a figure/unit that works for you.

Now we need to ensure this selection is defaulted when the page opens. I prefer to execute the click() event as to simulate the actual action, as opposed to replicating the relevant addClass() function.

You can use a similar technique to conditionally hide a specific radio button in the group (though you still need to validate the availability to the user on the database end.)

Add this to your 'Execute when page loads' page attribute, instead of adding a Default Value the item itself.

$('#P47_RADIO input[value=P]').next().click()

Where the value=P represents the relevant radio item value. The .next() moves selection to the next sibling, which is the span element, where click is triggered.

Or you could consider this button group plugin.

Or in APEX 5.1 you can use the pill template option.

Or you could use some form of List template button group.

Or you can stick with tiny buttons only people using a mouse on a desktop PC can hope to aim for.

One of the beauties of Oracle APEX - so many options. I think I need to try convert this to a plugin.

Happy APEXing!

Wednesday, 21 December 2016

Phased APEX migrations

While looking through the comments regarding 5.1 features it occured to me how many different ways the Oracle APEX team enable us to phase our applications into any new APEX version, thereby minimising risk and introducing new IDE features to developers earlier.

I've always thought APEX does a really good job of leaving our applications alone during upgrades. It normally depends on how much the boundaries have been pushed, and how much the theme has been modified, or templates added. In fact, most of the work is in upgrading the theme, which is why the Universal Theme came about.

So that that masterpiece may start the list:
  1. Universal Theme
    Designed to remove need to migrate themes in future. Instead, theme templates re-subscribed on demand as long as you kept your theme locked to the repository.
  2. Compatibility mode
    A relict from Oracle Forms, this feature allows you to prepare your app for behavioural changes between APEX versions. This great write up from Carsten describes how asynchronous developments in 5.1 may apply to your applications.
    Check this setting on any applications borne out of earlier APEX versions.
  3. jQuery Migrate
    To keep libraries lean, older functions are removed over time. Older references can sustained until they're refactored, as described by Marko.
  4. Utilities -> Upgrade Application
    APEX will leave deprecated features alone, until you're ready to upgrade each instance. The classic example is the old datepicker from 3.1. All your items called the horrible window until you replaced them all. This feature makes this process quicker and this older reference from Dimitri still applies. I may translate my mentioned of it in this presentation (as it applies to charts) to a blog post.
  5. Multiple concurrent versions
    It's not here year, but 5.2 may see the introduction of the ability to run two different APEX versions on the same database instance.
  6. apex.oracle.com
    This will always be a sandbox for the latest version or patch, so why not try your applications out in there? You can script up your tables, generate some data and import your app. Start preparing now and see how much your application won't break.
    Let's not forget apexea.oracle.com, when the latest major release is in early adopter mode.
If you can think of any others, let me know and I'll add them to the list.

Or do you have any stories of nasty surprises? I haven't heard of too many serious issues with APEX upgrades.

Edit:


#letswreckthistogether

Monday, 19 December 2016

Upgrading the Universal Theme

Back when APEX 5.0 was released, these forward thinkers at the development team installed a feature to verify your Universal Theme against the one defined in the repository.

There hasn't really been anything to verify against, until now.

There are a number of changes to the Universal Theme, and one way to explore these changes is to check out what's reported under the Verify button in the Theme definition.


Though unfortunately on apex.oracle.com I'm still getting the same error
ORA-20001: Unable to subscribe to report template.
ORA-00040: active time limit exceeded - call aborted


Errors aside, this facility all planned, of course, to minimise the impact theme upgrades have caused in the history of APEX. And no doubt used internally while they were developing UT in the first place.

As Patrick Wolf points out in this forum post, some features aren't borne out of the IDE upgrade alone, but are found with the theme upgrade. This includes RTL functionality.

So some thoughts that come out of reviewing the comparison:

  • A couple of new default styles, to go along with Slate. Nice.
  • Two new region templates to explore - Content Block and Blank with Attributes (No Grid)
  • Every other template has been touched in some way. It would be nice to see a diff of the updates.

If your Universal Theme is still locked, you just refresh your theme definition and your application should continue to work wonderfully.

Take care if you have any customisations or extensions, regression test as necessary. We've tried to minimise ours so it will be interesting to explore when 5.1 becomes generally available.

If you want to learn more about the features of the Universal Theme, check out the sample application, which also got a wicked upgrade, always available at
apex.oracle.com/ut
There are some awesome tools in the reference section alone.

Wednesday, 25 May 2016

More on CSS selector performance in Oracle APEX

Last month I wrote a post about CSS performance, including some performance test results.

I recently encountered this brilliant post on Medium that describes some best practices for CSS.

While APEX does a lot of this for you, I think it's worth a read by all developers. Even applying basic naming conventions can make code easier to read and understand.

There was also a section on performance that described an issue that my previous example didn't explore, and that's 'tree walking'. Each web page could be likened to a giant tree, and your CPU will like you if you can minimise the amount of traversing necessary to verify the component being sought.

So for APEX developers, consider the selector reading right to left, and try keep it to two steps.

For instance, to identify a button within a classic report, you would define a static region ID for the report, and use the following selector
#p1_region a.t-Button

This would look for anchors with the standard Universal Theme button class, but only if it exists within the classic report region. Concise & effective.

You could use this selector to apply further CSS attributes to the buttons, perhaps via the Inline CSS page attribute.
#p1_region a.t-Button { font-weight : bold; }

Or you could use it as a jQuery selector for an on-click Dynamic Action, responding to the button press. If you add the following as link attributes to the column with the link button. It adds an attribute to the anchor with information from a column aliased as season in your SQL.
data-season="#SEASON#"
Note, to render a column link as a button, this attribute would also contain this class listing, to look like the nearby image.
class="t-Button t-Button--warning t-Button--simple t-Button--large t-Button--stretch"

You can refer to this information within a JavaScript action to set a hidden page item with the data from the season column.
$s('P1_SEASON', $(this.triggeringElement).data('season'));

A subsequent PL/SQL action could then submit this value to session state and execute something related on the database, without submitting the page on click of the report row button.

While that has side tracked from selector performance, it shows how a simple selector can be used within APEX to trigger events. A pattern I use regularly, done with minimum effort.

If you like this post, you may like my book /plug

Small tip: Align button in UT

Ever had this problem where your button is offset to page items?

Item / Button misalignment

While the Universal Theme is awesome, it hasn't quite got everything right. I look forward to trying the updated version of the theme in our existing applications.

APEX forum legend fac586 (a.k.a. Paul MacMillan) provided a simple solution here.


Add t-Form-inputContainer to the Column CSS Classes property for the button.

Little tips like this can be acquired just by occasionally checking out the recent responses in the forums, perhaps opening anything of interest that might pertain to your work.

I think this tip should be suffixed with this funny
https://pics.onsizzle.com/rob-ybu-know-css-come-quick-to-disarm-the-bomb-2466256.png

Modified from the xkcd original
https://xkcd.com/1168/

Monday, 31 August 2015

APEX 5 Verify Theme Subscription

I was attempting to replicate the navigation bar example from the Opportunity Tracker application and I noticed my application was missing icons from the sub list dropping off the username.
Icons in submenu when visible
Here are the relevant User Interface settings for the Navigation Bar.

User Interface settings
It turns out in newly created application with Theme 42 the following is used as the sublist entry template
<li data-current="true" data-icon="#ICON_CSS_CLASSES#"><a href="#LINK#">#TEXT_ESC_SC#</a></li>

In my application that was created a few weeks ago uses
<li><a href="#LINK#">#TEXT_ESC_SC#</a></li>

So this is when I thought it might be worth giving the Verify Theme Refresh option a go.
Sure enough a bunch of templates, including the Navigation Bar, was "Out of Sync" instead of "Match"
Verify Theme Subscription

I followed the on-screen instructions as the documentation suggested, and waited with baited breath as to what to do next...

Nothing! A message came back saying my theme was synchronised and every template matched the theme master that lives in the Oracle domain somewhere.

I tried the Verify theme option previously but it does not seem to operate well in apex.oracle.com
ORA-00040: active time limit exceeded - call aborted
Not sure if this is a shared server thing or something is actually wrong.

At the end of the day this shows an advantage of running the Universal Theme - updates and corrections can come from Oracle at any time.

I guess we'll learn any disadvantages as time goes by, such as any JavaScript or CSS changes that affect your usage of the relevant template.

Also see UT migration guide.

Note: December 2017
Pre-release of 5.1 - Upgrading Universal Theme