Development

APEX 5.1 - Client side messaging and apps not using Universal Theme

Anthony Rayner - Thu, 2016-12-22 09:42
Introduction

In APEX 5.1, we are introducing new client side messaging functionality, which aims to provide more modern, faster messaging across APEX, including the capability to display both error and success messages from the client side, without requiring a full page reload (as is the traditional way in APEX). Messaging in APEX is something we have wanted to modernise for a long time, and in 5.1, precipitated by the introduction of the Interactive Grid and its requirement for such messaging, this comes to fruition. 


This new functionality works well with apps already using the Universal Theme, however apps using older, or custom themes may face some consistency issues in how inline item errors are displayed between pages that display messages the old way and the new way. The purpose of this blog post is to highlight when such inconsistencies may occur, and to provide guidance on how you can go about fixing them.

Note: If you have created your own custom theme, please see Method #2 for instructions on how to update your theme to work with client side messaging.


When can these inconsistencies occur?
Client side messaging for inline item errors will be used in the following scenarios:
  1. To display the error messages if an APEX validation error occurs, and the page attribute Reload on Submit is set to Only for Success (which is the default for new pages, irrespective of theme).

  2. Screenshot showing the new Reload on Submit page level attribute in APEX 5.1The new Reload on Submit page level attribute in APEX 5.1

  3. To display the error messages if a client side validation error occurs such as Value Required = Yes, and the app Compatibility Mode is set to 5.1 (default for new apps, irrespective of theme), a Submit Page button is used with set to Execute Validations = Yes.
Compatibility Mode, available in Application Attributes

So as soon as you start adding new pages to an existing app for example, you will start to hit these inconsistencies, because existing pages will have Reload on Submit set to Always, and new pages will have this set to Only for Success

In both of the above scenarios, an inline item error will be shown but it may not look exactly the same as on other existing pages. This is because as it is, the client side messaging logic isn't able to use the corresponding template markup from the theme because of some missing information (more on that in a moment), and instead relies on some generic fallback logic to display the error. We can see the inconsistency below. 

Here is an inline item error, rendered using server-side logic due to the page level attribute Reload on Submit being set to Always (default for existing apps).

Screenshot showing Inline item error display for Theme 21, when the page level attribute Reload on Submit is set to Always



And here is the same error, rendered on the client side due to the page level attribute Reload on Submit being set to Only for Success (default for new pages).

Screenshot showing Inline item display for Theme 21 in APEX 5.1 when the page level attribute Reload on Submit is set to Only for Success



The Known Issues page for 5.1 mention this issue, including a few suggestions for working around it.

Screenshot showing excerpt from known issues page detailing this issue. To read the full issue please follow the known issues page for 5.1 link, and search for 'client-side messaging issues in apps using old, or custom themes'


Now let's explore each of the suggestions in a bit more detail.


Method #1 - Disallowing client side validation

The first solution is described in the Known Issues as follows:
These differences can be avoided by setting Reload on Submit to Always, (please note the Interactive Grid feature requires this to be set to Only for Success and not using client side validation by either setting app Compatibility Mode to less than 5.1, or setting Execute Validations = No.Setting Reload on Submit to Always, or disallowing client side validation as described will of course resolve the inconsistencies, but are somewhat brute-force, with the negative side-effects that you cannot benefit from the new way, you are precluded from upgrading your compatibility mode and also by setting Reload on Submit to Always, this means you cannot use the Interactive Grid on that page.

This is good for a quick-fix, but does place limitations upon your app, which are far from ideal.


Method #2 - Updating your theme
A better way to resolve this, and one that doesn't limit you in the same way as detailed in Method #1, is to update your themes so that they work better with the new client side messaging. Specifically this involves an update to your theme's label templates. 

The reason that the client side messaging functionality is not able to use the markup from the label template, is because it relies on the following:
  1. The error markup being provided in the Error Template attribute of the label template.
  2. The #ERROR_TEMPLATE# substitution string being included in either the Before Item or After Item attribute of the label template.
Now we know what's required, let's look at an example using the standard Theme 21, and the Optional Label with Help label template. In this template, you will see the Error Display information is provided as follows:


Screenshot showing Theme 21 > Optional Label with Help label template before any changes. Shows an empty Error Template and error markup defined in the On Error Before Label and On Error After Label attributesTheme 21 > Optional Label with Help label template before any changes. Shows an empty Error Template and error markup defined in the On Error Before Label and On Error After Label attributes

Given the aforementioned rules, this clearly won't work, there is no Error Template defined, so the client side will need to resort to its fallback template, causing the possible inconsistencies.

So firstly, we need to move the error related markup into the Error Template attribute. However, this presents a slight problem, because the way it is currently, the On Error Before Label markup will be rendered exactly as described, before the label markup when an error occurs, and the On Error After Label markup similarly will be rendered after the label markup. This means that it will effectively wrap the label markup in the template, which is very difficult to replicate by switching to the Error Template approach (where the markup is defined in its entirety in a single place, and inserted into the template in a single place). Unfortunately this means we will need to compromise, and go with an approach that will be slightly different to how it looked prior to 5.1, however importantly this will be consistent between client side and server-side rendered messages now, and without the downsides of having to resort to Method #1.

So we move the combined error markup into the Error Template, as shown:


Screenshot showing Theme 21 > Optional Label with Help label template after moving the error markup into the Error Template attributeTheme 21 > Optional Label with Help label template after moving the error markup into the Error Template attribute

Note: We removed the line break because we no longer need to force a new line after the label as was the case before, and because the DIV will automatically start on a new line because it is a block-level element, so the error will appear on a new line after its preceding element.

The next part is to add the #ERROR_TEMPLATE# substitution string to the best place in either of the two attributes where it is supported in a label template, either the Before Item or After Item attributes. Let's go with the more common approach of displaying the error after the item, so simply add #ERROR_TEMPLATE# in the After Item attribute, as shown:


Screenshot showing #ERROR_TEMPLATE# substitution string added to the After Item attribute of the label template


You will need to replicate this in the different label templates in your app, and of course different themes will have slightly different implementations for label templates, but if you follow the rules laid out above, then it should be a fairly straight forward switch over. 


Screenshot showing Updated appearance following template change with the error displayed below the input, now consistent irrespective messaging typeUpdated appearance following template change, now consistent irrespective messaging type


Method #3 - Migrate to Universal Theme
This will almost certainly result in the most work, but will provide great benefit in the long run, and all these problems will automatically go away.


Screenshot showing Universal Theme Sample Application, available in your workspace via Packaged Apps > SampleUniversal Theme Sample Application, available in your workspace via Packaged Apps > Sample

This will fix these inconsistency issues, and would be the best thing you can do to also benefit from the huge improvements offered by Universal Theme over our legacy themes, but will most likely take the most time and should be considered as part of a migration project (rather than a simple change), so may of course not be feasible. To see our Migration Guide, specifically the section entitled Migrating from Other Themes for further information.



Summary
The new client side messaging of APEX 5.1 offers some great benefits over the server-side approach, but does represent some issues with inline errors and apps not using Universal Theme as detailed here. If you have time, converting to Universal Theme would definitely be the way to go, there are just such massive improvements to benefit from in terms of capability, accessibility, responsiveness, modern look and feel, and more, but this will of course take the most time and investment. If this is not feasible, we would recommend updating your existing themes as detailed here, to be able to provide a consistent look and feel, and still benefit from other new features in 5.1 as described.
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; -webkit-text-stroke: #000000} span.s1 {font-kerning: none} p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; -webkit-text-stroke: #000000} span.s1 {font-kerning: none}
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica; -webkit-text-stroke: #000000} span.s1 {font-kerning: none}
Categories: Development

Oracle SINH, COSH, and TANH Functions with Examples

Complete IT Professional - Thu, 2016-12-22 05:00
In this article, I’ll cover what the Oracle SINH, COSH, and TANH functions are, and show you some examples. Purpose of the Oracle SINH, COSH, and TANH Functions These three functions are used to calculate the hyperbolic sine, cosine, or tangent of a number: SINH: Calculate the hyperbolic sine of a number COSH: Calculate the […]
Categories: Development

What Is Professional Networking and Why Should I Do It

Complete IT Professional - Wed, 2016-12-21 05:00
Networking is a common term in the IT industry. It can have two meanings – the process of linking computers and other devices together so they can communicate, and the process of meeting and talking to other people to help your IT career. This article is about speaking to people – professional networking. What Is […]
Categories: Development

Oracle ABCS - Traversing Relationships, Conditional Navigation, Query and Update with JavaScript

Shay Shmeltzer - Mon, 2016-12-19 11:02

Oracle Application Builder Cloud Service (ABCS) lets you do a lot of things in a declarative way, however for more complex validation and conditional logic you might need to resort to some basic coding in JavaScript.

I ran into such a case with an application I was developing, and figured out that the code sample from that system will be a good way to illustrate some coding techniques in ABCS.

The application I was working on allows people to register to various events. Each event has a certain capacity, so if there are too many people registered to an event, we want the rest to be added to a wait list. For each record of a person registering, we keep a reference to the event they want to attend.  So the logic flow is:

  1. Check how many open spaces are available for the event we are trying to register for.
  2. If there is space in the event, save the new person data, and show a success message.
  3. If there isn't space, update the person "Waitlisted" field to be true, save the data, and show a message saying that the person is on the wait list. 

In the demo video below I'm showing how to:

  • Define declarative conditional flow of steps based on results from custom code
  • Traverse relationships between custom object through code
  • Execute a conditional query and run through the results from a custom object with code
  • Set the value for a property of a custom object through code

For reference here is the complete code from the sample:

require([    'operation/js/api/Conditions',    'operation/js/api/Operator'], function (Conditions, Operator) {    var lab = Abcs.Entities().findById('Lab');    var id = lab.getProperty('id');    //condition is to find a lab with the id that is in the page's drop down box    var condition = Conditions.SIMPLE(id, Operator.EQUALS, $Person.getValue('ref2Combo_Box'));    var operation = Abcs.Operations().read({        entity: lab,        condition: condition    });    //if query returned value we loop over the rows and check the capacity and registration columns    operation.perform().then(function (operationResult) {        if (operationResult.isSuccess()) {            operationResult.getData().forEach(function (oneRecord) {                if ((oneRecord.Capacity - oneRecord.Registered) < 1) {                    $Person.setValue('Waitlisted', true);                    reject("error");                } else                {                    resolve("ok");                }            });        }    }).catch(function (operationResult) {        if (operationResult.isFailure()) {            // Insert code you want to perform if fetching of records failed            alert('didnt worked');            reject("error");        }    });});

More information on the JavaScript APIs used here are in the Oracle ABCS Documentation.

Categories: Development

Oracle ABCS - Traversing Relationships, Conditional Navigation, Query and Update with JavaScript

Shay Shmeltzer - Mon, 2016-12-19 11:02

Oracle Application Builder Cloud Service (ABCS) lets you do a lot of things in a declarative way, however for more complex validation and conditional logic you might need to resort to some basic coding in JavaScript.

I ran into such a case with an application I was developing, and figured out that the code sample from that system will be a good way to illustrate some coding techniques in ABCS.

The application I was working on allows people to register to various events. Each event has a certain capacity, so if there are too many people registered to an event, we want the rest to be added to a wait list. For each record of a person registering, we keep a reference to the event they want to attend.  So the logic flow is:

  1. Check how many open spaces are available for the event we are trying to register for.
  2. If there is space in the event, save the new person data, and show a success message.
  3. If there isn't space, update the person "Waitlisted" field to be true, save the data, and show a message saying that the person is on the wait list. 

 

In the demo video below I'm showing how to:

  • Define declarative conditional flow of steps based on results from custom code
  • Traverse relationships between custom object through code
  • Execute a conditional query and run through the results from a custom object with code
  • Set the value for a property of a custom object through code

For reference here is the complete code from the sample:

require([
    'operation/js/api/Conditions',
    'operation/js/api/Operator'
], function (Conditions, Operator) {
    var lab = Abcs.Entities().findById('Lab');
    var id = lab.getProperty('id');
    //condition is to find a lab with the id that is in the page's drop down box
    var condition = Conditions.SIMPLE(id, Operator.EQUALS, $Person.getValue('ref2Combo_Box'));
    var operation = Abcs.Operations().read({
        entity: lab,
        condition: condition
    });
    //if query returned value we loop over the rows and check the capacity and registration columns
    operation.perform().then(function (operationResult) {
        if (operationResult.isSuccess()) {
            operationResult.getData().forEach(function (oneRecord) {
                if ((oneRecord.Capacity - oneRecord.Registered) < 1) {
                    $Person.setValue('Waitlisted', true);
                    reject("error");
                } else
                {
                    resolve("ok");
                }
            });
        }
    }).catch(function (operationResult) {
        if (operationResult.isFailure()) {
            // Insert code you want to perform if fetching of records failed
            alert('didnt worked');
            reject("error");
        }
    });
});

More information on the JavaScript APIs used here are in the Oracle ABCS Documentation.

Categories: Development

A Guide to the Oracle UPDATE Statement

Complete IT Professional - Mon, 2016-12-19 05:00
Have you ever needed to update data that was already in a table in Oracle? Learn how to do this with the Oracle UPDATE Statement. What Is the Oracle UPDATE Statement? The Oracle SQL UPDATE statement allows you to change data that is already in a table in SQL. The INSERT statement lets you add […]
Categories: Development

Start to develop in APEX 5.1, you will gain at least an hour a day!

Dimitri Gielis - Sat, 2016-12-17 05:19
Yesterday APEX 5.1 (5.1.0.00.43) was installed on apex.oracle.com.
This means that you can start developing your apps in APEX 5.1 from now on. Unlike the early adopter releases (apexea.oracle.com) you can develop your apps on apex.oracle.com and later export them and import in your own environment once the on-premise version of APEX 5.1 is available.

APEX 5.1 is again a major update behind the scenes. The page processing is completely different from before; where previously full page reloads were done, now there's much more lightweight traffic and only necessary data is send across.

The big features in this new release are the introduction of Interactive Grids, which is both a successor for Interactive Reports as for Tabular Forms. The other big feature is the integration of Oracle JET, which you see mostly in the data visualisation (charts) part of APEX, but more components will probably follow in future versions. Although those two features addresses the most common issues we previously had (outdated tabular forms and charts), APEX 5.1 brings much more than that. Equally important for me are the "smaller" improvements which makes us even more productive. Below you find some examples...

When creating a new application, the login page is immediately a great looking page:


Previously in APEX 5.0 you had to adapt the login page, see my blog post Pimping the Login Page.

When you want your item to look like this:


APEX 5.1 has now a template option to display the Pre and Post text as a Block:


Or when you want an icon inside your item, there's an Icon CSS Class option selector which shows the gorgeous looking new handcrafted Font APEX icons:



You could do all the item customisations above in APEX 4.2 or 5.0 too, but it would require custom css and some code, whereas now it's declarative in APEX 5.1.

And there's so much more; ability to switch style by user, new packaged apps, warn on unsaved changes, no reload page on submit etc. features that haven't been talked about much yet, but which before you had to do with a plugin or a lot of custom code and now it's just there.

So those "smaller" features are actually not so small, they are an enormous timesaver and bring your apps in warp-speed to modern and great looking applications.

In the next blog posts I'll go in more detail on some specific features that will gain you at least an hour a day, but in the meantime, embrace APEX 5.1 and start earning those extra hours :)
Categories: Development

Oracle SQRT Function with Examples

Complete IT Professional - Fri, 2016-12-16 05:00
In this article, I’ll explain the Oracle SQRT function and show you some examples. Purpose of the Oracle SQRT Function The purpose of the Oracle SQRT function is to find and return the square root of a provided number. The square root of a particular number answers this question: “Which number, when multiplied by itself, […]
Categories: Development

Oracle LNNVL Function with Examples

Complete IT Professional - Thu, 2016-12-15 05:00
In this article, I’ll explain what the Oracle LNNVL function does and show you some examples. Purpose of the Oracle LNNVL Function The purpose of the LNNVL is to perform a “logical not null” on the expression that has been provided. It allows you to evaluate data that contains a NULL value, which is something […]
Categories: Development

Markus Winand on Database Optimizers

Gerger Consulting - Tue, 2016-12-13 19:52
If you are a DBA or a developer and would like to learn more about database optimizers, there is no one better in the world than Markus Winand to learn from!



Markus is hosting a free webinar on December 15th. Attend his webinar and learn how you can build better performing applications.

Register at this link.

Categories: Development

Why You Need a Long Term Career Plan and How to Create One

Complete IT Professional - Mon, 2016-12-12 19:57
Why should you have a career plan? Do you even need to know what your job will be in the long term? Learn why and how to create a career plan in this article. The answer is “yes”. You need to know what your career will look like, long term. Or at least have an […]
Categories: Development

A Guide to the Oracle ALTER TABLE SQL Statement

Complete IT Professional - Mon, 2016-12-12 05:00
The Oracle ALTER TABLE statement allows you to make changes to an existing table. Learn how to use it and see some examples in this guide. What Is The Oracle ALTER TABLE Statement? The ALTER TABLE SQL statement lets you change a table that has already been created. Using the CREATE TABLE statement lets you create […]
Categories: Development

Oracle LN Function with Examples

Complete IT Professional - Fri, 2016-12-09 05:00
In this article, I’ll explain what the Oracle LN function is, and show you some examples. Purpose of the Oracle LN Function The purpose of the Oracle LN function is to calculate the natural logarithm of a number. if you’re not sure what the natural logarithm means, you can read more here. I’m not a […]
Categories: Development

Oracle TAN Function with Examples

Complete IT Professional - Thu, 2016-12-08 05:00
In this article, I’ll explain the Oracle TAN function, what it is, and show you some examples. Purpose of the Oracle TAN Function The purpose of the Oracle TAN function is to calculate the tangent of a number. The tangent is ratio of the length of the side opposite the angle to the length of the […]
Categories: Development

Oracle Certification Dumps Can Ruin Your Career

Complete IT Professional - Mon, 2016-12-05 05:00
Are you looking to get certified? Want to get your hands on some Oracle certification dumps for an exam to help you pass? That’s a bad idea. I’ll explain why in this article. What Is a Brain Dump? So what is a brain dump, when you talk about IT certifications? A brain dump is a […]
Categories: Development

New York OUG Winter Event

Gerger Consulting - Fri, 2016-12-02 11:55
On December 7th, Gitora founder Yalim Gerger will be at the NYOUG Winter Event to talk about version control of PL/SQL using Git. Click here for the full agenda. We hope to see you there!


Categories: Development

Oracle SIN Function with Examples

Complete IT Professional - Fri, 2016-12-02 05:00
In this article, I’ll explain what the Oracle SIN function is and show you some examples. Purpose of the Oracle SIN Function The purpose of the SIN function is to calculate the sine of a number. The sine is the ratio of the length of the side of the triangle opposite the angle to the […]
Categories: Development

Oracle COS Function with Examples

Complete IT Professional - Thu, 2016-12-01 05:00
In this article, we look at the Oracle COS function and see some examples. Purpose of the Oracle COS Function The COS function will return the cosine of a number. If your knowledge of cosine is a bit rusty (like mine), then you might find this definition helpful.   Syntax The syntax of the COS […]
Categories: Development

Video&Slides: Version Control for PL/SQL

Gerger Consulting - Mon, 2016-11-28 18:45
Last week we hosted a webinar about how PL/SQL developers can manage their PL/SQL code bases with Gitora, the version control tool for PL/SQL. Many thanks to everyone who attended. You can watch the recording of the webinar and view the slides below.

The webinar consist of two parts:

1) Version Control Strategies for PL/SQL
2) Live Demo of Gitora

Video:



Slides:

Categories: Development

11 Tips to Improve Focus and Concentration at Work

Complete IT Professional - Mon, 2016-11-28 05:00
Do you often find yourself not focusing at work? Or, you try to focus, but something else comes along and distracts you? I know how this feels. I’ve listed eleven ways to remove distractions and increase focus in this article. I’ve been able to improve my focus by removing some of the distractions I have […]
Categories: Development

Pages

Subscribe to Oracle FAQ aggregator - Development