Quantcast
Channel: ODTUG Aggregator
Viewing all 2258 articles
Browse latest View live

APEX Plugin: Execute PL/SQL code and return content to page (updated)

$
0
0
Oracle APEX has a built-in Dynamic Action called "Execute PL/SQL Code" that executes a block of PL/SQL code on the server via an Ajax call (ie does not do a regular submit and reload of the whole page).

But what if you want to do something on the server AND also return some content back to the client? Back in 2012 I released an APEX Dynamic Action plugin called "Execute PL/SQL Code and Return Content" that allows you to do just that. Read the original blog post for more information.



Since then, the APEX framework has evolved and the old Ajax workhorse function called "htmldb_Get" has been deprecated and replaced with functions in the "apex.server" namespace. Hence I have updated my plugin to use the modern API.

You can find the updated version (1.1) of the plugin on my GitHub page for APEX plugins. Note that the new plugin has been exported from APEX 18.1 and therefore requires at least that version to import and use.

Enjoy! :-)



2018 Was Good – Looking Forward To Serve You in 2019!

$
0
0

2018 was good - look forward to serving you in 2019

While starting off this new year (It’s still January, isn’t it?), I wanted to take the opportunity to offer you, our readers, my best wishes for 2019. Thanks for your interest in our work, your questions, and the conversations. I also wanted to give you a summary of the year just past. It was another good one. In fact, 2018 brought several big wins and strong moments, and the year that has just started seems to be putting us on the same path to success. We very much look forward to serving you in 2019.

Continued Growth and Development

We’ve continued developing new markets such as France, where we toured last spring. We organized a successful Meetup in Paris on March 14th. It generated some very interesting collaboration opportunities with our European partners. The South-American market is also booming. We had the opportunity to complete several new mandates in Peru.

Our acquisition of C2 Consulting, a Boston firm whose consultants’ expertise is highly regarded in the Oracle APEX community, was certainly one of our pivotal moments in 2018. This transaction allowed us to increase our number of resources specialized in strategic consulting, and strengthen our position in the USA.

Thanks to a full order book, close to twenty new people joined the Insum team in 2018. We remain committed to hire, train, and mobilize the best Oracle APEX specialists so we can continue to be the World’s Center of Excellence in Oracle APEX.

Recognition by our peers

The awards our team members earned during the year confirm, once again, that we stand apart thanks to the quality of our projects and services.

  1. Two of our colleagues were honored during the annual ODTUG Kscope conference:

 

  • Named Oracle ACE Associate: Senior APEX Consultant Adrian Png. Adrian joins a team of seven Oracle-recognized people at Insum who have been helping strengthen the Oracle community by regularly sharing their expertise, thus contributing to Insum’s reputation.
  • Recipient of the Best Presenter in the Database category: Innovation Director Martin D’Souza
  1. We also received the Montreal Abe-Limonchik Intercultural Award (Business category). This recognition is a testimony of our commitment and exceptional contribution to the promotion of intercultural relations and diversity.

 

  1.  Named Oracle Cloud Infrastructure 2018 Certified Architect Associate: Our Cloud and DBA Practice Director Luc Demanche. According to Oracle, only 75 people in North America out of 300 in the entire world have this certification.

We were able to win these awards thanks to the exceptional work of all of our experts as they completed various large-scale projects.

Speaking of which, our cloud services are booming. We have already supported and facilitated data migration for several of our clients. We are also noticing a growing adoption of our E‑Business Suite (EBS) integration offer.

International Reach

We favor strong community involvement. We strive to share our knowledge to help train other APEX experts. This is why, each year, we take part each year in several conferences and events gathering people interested in APEX. In 2018, we presented at large‑scale events such as Alliance (Salt Lake City), Oracle Code (Boston), Collaborate (Las Vegas), and Kscope (Orlando). After Kscope, we noted the community’s avid interest in webinars on the topics presented during the conference. So, we decided to develop a series of nine webinars, the first of which took place in July. The series was tremendously successful, with unparalleled attendance numbers. We also participated in two conferences in South America, including the Oracle Developer Community LAD Tour 2018 (Augusta and Barranquilla in Colombia)  and the XXV International Symposium Engineering  Day, in Peru.

 

In the end, if we’ve managed to accomplish this much in 2018, it’s because of our employees, our clients, and our partners, who’ve allowed us to grow and with whom we will continue sharing this beautiful adventure.

Thank you again, and we look forward to hearing from you in 2019.

 

 

Michel St-Amour, Co-Founder and President of Insum

 

 

 

 

 

 

Photo by Spenser Sembrat on Unsplash

 

The post 2018 Was Good – Looking Forward To Serve You in 2019! appeared first on Insum.

Oracle APEX Social Sign-On with Microsoft Azure

$
0
0
My co-worker Adrian Png has written a few great posts on social sign-on with APEX. I'd like to provide a quick cookbook with some interesting details here. If you get a chance, take a look at Adrian's posts:
https://fuzziebrain.com/content/id/1709/
https://fuzziebrain.com/content/id/1711/

Here is the quick cookbook.

Let's assume your APEX url is
https://myapex.com/ords/

Log in to the Azure registration portal
https://apps.dev.microsoft.com/

and click "Add an app"
Enter a name and click "Create"


Click "Generate New Password"






COPY THAT PASSWORD! You won't have another chance!
hbUChicago1990){(upzadLTF3%

While you're at it, grab the application ID:
dbf9c4ac-a7d1-4885-84c4-5b80777703f3

(Careful readers may see that I altered the secret and application ID in the text. I never saved the pic above on Azure, but figured I'd change it in the text anyway.)

Click "Add Platform" and choose Web






Enter
Redirect URLs
https://myapex.com/ords/apex_authentication.callback

and here is the magic!! The logout URL can NOT have a ? in it. I tried several times to use something like this:
https://myapex.com/ords/f?p=logout
and I got a very vague error when trying to save:

The problem is the logout URL but it's not at all obvious. So, you'll need to figure out another way to logout. I used an apache rewrite rule, which allows me to do this:
https://myapex.com/logmeout


Add a home page url if you want:
https://myapex.com/ords/f?p=myapp

Scroll to the bottom and save your changes.

At this point the Microsoft portion is functional but users will get a notice asking them if they consent to share some information with the application. It's not a big deal, but you can avoid that notice by having an admin consent for everyone in the organization. There is certainly a way to do it within the Azure admin...well, I would guess there is, but I couldn't find it. I did discover this method, though. Go to the following URL:


https://login.microsoftonline.com/common/adminconsent?client_id=<APPLICATION_ID>&state=12345&prompt=admin_consent

in our example

https://login.microsoftonline.com/common/adminconsent?client_id=dbf9c4ac-a7d1-4885-84c4-5b80777703f3&state=12345&prompt=admin_consent

log in as an admin and consent.


OK, on to the APEX installation portion.

Here's an important item...the client secrete (or password) that we got from the application registration is hbUChicago1990){(upzadLTF3%. That's a great secret, but it won't work just as you see it. You'll get the following error:

AADSTS50012: Invalid client secret is provided. Trace ID: 830c95a3-9bb7-9de1-8a22dcca1600 Correlation ID: 572ef7ea--4329-9674-9e9e3468982a Timestamp: 2019-01-15 22:05:41Z





The problem is that the secret needs to be url encoded. So, let's do that first.

Log into the APEX builder and navigate to SQL Workshop > SQL Commands and do what needs to be done:

select apex_util.url_encode('hbUChicago1990){(upzadLTF3%') the_stuff
  from dual





That's the stuff:

hbUChicago1990)%7B(upzadLTF3%25



Now navigate to App Builder > Workspace Utilities > Web Credentials. Create credential.



I put the secret in the comments so you can see it.

Almost there. Now go to your application and create an authentication scheme.






Name: Your Choice
Scheme Type: Social Sign-In
Credential Store: MyAppAzure (the one you created)
Authorization Endpoint URL: https://login.microsoftonline.com/common/oauth2/v2.0/authorize
Token Endpoint URL: https://login.microsoftonline.com/common/oauth2/v2.0/token
User Info Endpoint URL: https://graph.microsoft.com/v1.0/me
Scope: User.Read
Username Attribute: userPrincipalName

You might be done...if you have the root cert for https://graph.microsoft.com/v1.0/me already in your wallet. If not get your dba to add the certificate from https://graph.microsoft.com/v1.0/me to the Oracle wallet.

The other option is to follow Adrian's post (link at the top) to use a reverse proxy instead.

That does it!




Icon Picker

$
0
0
Demo app https://apex.oracle.com/pls/apex/f?p=94650 GitPage https://github.com/grlicaa/IconPicker

My APEX Application Got Hacked : Change Passwords Into Passphrases

$
0
0

While I will discuss APEX specifically later in this article, the content here really applies to any web based application.

Most of us as developers fall into a false sense of security when we establish our password policy. I too was guilty of this until I took the time to look into the subject more thoroughly.
Hopefully by the end of this article you will understand the issues with your current password policy and how it can lead to vulnerabilities. Remember that behind your application, there is a database that holds a lot of organisational data as well as client specific information that you are responsible to protect.

All the time in the news we hear of very large corporations that have experienced password breaches resulting in critical customer information being exposed. We are horrified by this and put the blame squarely on the company that we have trusted with our personal information  regardless of  their privacy policy. If big corporations can be hacked, then why can’t our simple user facing application be hacked.

It is a known fact that most users create very bad passwords.

I am not going to insult you by pointing out that the storage of passwords as a string in the database is a monumentally bad idea. None of us I hope would ever do this. In a moment we’ll discuss how to do this in a better way.

Clearly you do need a password policy, but you do need to think carefully about the components of that policy.

In terms of hacking passwords, I will really be discussing offline file hacking as opposed to online directly against your application. Hackers are very intelligent and sophisticated in their methods. The offline file approach would mostly be the method they would use to access your data.

An offline file simply means that your user passwords have been accessed as a file that the hacker can find and use to crack passwords. We'll look at some real examples of how this is done.

Obviously how you store the passwords in the database is a key issue. You absolutely must encrypt the passwords as first line of defense. You need to store the passwords as a hash value.

There are two kinds of hashes – a “one way”  hash and a “two way” hash.

A two way hash means that you have some sort of key or function that allows you to unhash the value stored in the database. Some organisations use this to enable them to send an  email to their user if the user has forgotten their password. This is an unforgivable mistake.  

A one  way hash means that you can never your self  access the value in the database. The hash is created in the  value of the hash can only be accessed by the end user. You do this  by hashing values that only the user knows. One way of doing this is to hash the combination of the username and the password  

So the point is here that you will always want to use a one way hash to ensure that it cannot be unhashed by any database administrator or developer.

Now that we have a good method to store the passwords in the database we can move on to looking at our password policies.

To assess the real strength of the passwords against an attack, I will use the following site:

http://www.howsecureis my password.net

These sorts of sites are not really accurate but it is at least a place to start.

First let’s consider the situation where we have no password policy at all. I’ll use the typical password below:

Password1

When we type this in to the password analysis on the site, this password can be cracked instantly. This is absolutely insecure.


Now what if we require the user to have at least one number and a special character. My password now will be:

p@word1

When we type this in we can see that this password can be cracked in only 2 seconds. Clearly we still have a huge risk.

Well we can changed our policy to require a length of 7  and two numbers and one uppercase letter and one special character. Here we go:

Or@cl3!

Probably looks familiar doesn’t it? A much more complex policy has been used here. When we type this into the site we see that it can be cracked in 7 minutes.

You might be very surprised that the complexity is not so important as is the length of the password. This time my password will only have lower case letters and nothing else.

Here we go:

iliketodrinkwineatlunch

A pretty simple password,right? Type it into the site and look at the result. This password will take 277 trillion years to crack.

So with an 11 or more length requirement really protects us much more and the vulnerability is significantly reduced.

Now it is time to see the really scary stuff.

I have installed a program called Hashcat that is a popular cracking program among hackers.

I will show you how a malicious hacker might actually crack your passwords.

I am going to assume that a list of our hashed passwords has been exposed and the hacker got a hold of this file.This could happen in a lot of ways such as sql injection against your application

The password file I am using contains around 6,500 md5 hashed passwords. You can create your own file by using one of the many online hash generators.

We will try and crack passwords using a number of different attacks.Be aware that I am doing this on my PC with only one GPU. Hashcat uses the GPUss to process. This should make things even a bit more scary.

The first attack we will perform is called a Brute Force attack. It is probably the simplest of all attacks and will deal with passwords that have letters and numbers and are of a length around eight digits.

The attack starts looping through the hashes by first guessing something like “aaaaaa: and then “aaaaaaab: and so on. It will iterate all of the possible combinations and compare them to the hashed password.

We call hashcat and give it the file.



It recovered 1020 hashed passwords at a rate of 139 million hashes attempts  per second.
Here is an example of the passwords it recovered:



The cracked passwords appear after the “:” on each line. You can see that the passwords are not very long nor complex. But this is likely the first attack type a hacker will attempt. The attack completed very quickly and you can see that we matched and cracked a fairly large number of the hashed passwords.

The attack results were pretty good but we still have a ways to go.

Now using the same file we will use a dictionary attack.

A dictionary attack is much more sophisticated than the Brute Force attack

A dictionary may be a list or words in the English language or it may be a list of passwords that have already been cracked through previous breeches. Since hashes always are the same for a specific value, we can compare the hashes to  previously  cracked passwords against our current hash file. These lists of previously cracked passwords come from other very large hacks of large organisation. It is unlikely that a user’s password, or part of it, has been used by another user for another system.

But we don’t want to just use the dictionary. We want to also apply rules to the dictionary values.

For instance, we can toggle between lowercase and uppercase values. Or try using symbols to replace letters. Now the possible combinations greatly increases.

I am using a dictionary of about 12 million words and a rule set of a lot of different rules and combinations. Basically the attack tests each hash by comparing it to the dictionary and then applies the rules . It has a fair bit of work to do so it will take a bit longer.
Let’s run the dictionary attack against our hashed password file : 



This time it recovered another 2,299 hashed at a rate of 20 million hash attempts per second.

Here is an example of the passwords it cracked this time.


You can see that the passwords are a lot longer and complicated.

I could keep going and use other dictionaries and rule sets. In a normal attack the password file may be a lot larger and the passwords more complicated.

Remember the speeds we are getting are based on only one GPU.

Scared yet?

When you use a crack time estimator like the site we have been using here, you should know that they are not entirely accurate. They indeed do give us an indication of how long it might take a hacker to crack our password, but it can only predict in a general way.

The estimators do not really consider the processing speed that may be available to the hacker. Hackers use some powerful tools but they all rely on GPUs or graphic cards. These GPUs are getting more powerful every day. Usually a hacker will have a machine made up of several GPUs rather than just one. The number of crack attempts could be up to several billion per second. The crack time estimators have no way of determining the exact hardware that a hacker might be using.

Another way that the estimators cannot really assess is the sophistication of some of the dictionary attacks is they don’t know the hashing algorithm that the developer has used to store the passwords.

Generally you should understand that md5 is no longer acceptable. There have been so many breeches based on md5 hashes, that it has become very easy to crack them if the dictionary is long enough. It is now best to use SHA256 or SHA512. Oracle 12c has support for using a SHA256 hash.

Here’s what I mean In the earlier dictionary attack we recovered the password “energizer000000”. It was recovered in the first 11 minutes of the attack.

Going back to our estimator site and typing in the password “energizer00000” the result is that it will take 175 thousand years. Not quite as we have seen.

If you consider the password “iliketodrinkredwine” it is made up of the following words:

I like to drink red wine

The phrase will not truly be that difficult to crack. There are several words that appear to be standard phrases:

I like    red wine

In other words, these words would often follow each other in the English language. The associated familiarity of the phrase makes the dictionary attack easier.

But consider the following password:

drawerbufferturtlepalm

It consists of the following individual words:

drawer  buffer turtle palm

These are not very common words and there is no real connection between the words. A dictionary attack is much harder as it would have to combine all four words in exactly this same order.

Now, let’s at this minor change:

draw@er!bufferturtlepalm

A slight change has been made here. Special characters have been added to the phrase but note that they are not used to replace characters but are inserted into the words. The dictionary attack becomes very difficult as the individual words won’t be found exactly as they appear here.

When you replace letters with special characters rather than inserting them into the word, you are not really fooling the hacker. Users, for instance, often replace “a” with @ or an “I” with 1. Hackers know these tricks and they software they use already evaluates in this way.

How then do I deal with things in an APEX Application?

This is exactly the  same for APEX since it accesses key data from our Oracle database and uses public database connections to process data.

When it comes to APEX, the security of passwords really has to do with the authentication. The authentication we use is a way of identifying the user and ensuring the password they use is correct.

There are some preconfigured authentication methods available to us. One of them is to authenticate the user by reference to LDAP. This is a good method since as a user joins or leaves an organisation, the LDAP information is updated. The only issue here is that the user will be able to access all of your applications with the same credentials. You need to control this.

You can create your own custom authentication and this might work best for you as it is flexible and can validate the authentication of the user to address your specific needs including the method by which you encrypt the password for storage in the database.

Now this might be another surprise. As of Apex 18.1, we have another authentication method available to us. We can allow the user to be identified by way of their social media account such as Google or Facebook. In reality, this is a very secure method. In essence you are turning the issue over to them. Each of the social media accounts have really strong password policies and storage. They also, in some instances,  use what is called “two factor verification". This means that they have used two ways to validate the user. Often it may be an OTP or an SMS with a verification code. Since only the user has this information, the validation of the user is much more secure. Generally, most social media accounts store their passwords in quite sophisticated ways and thus may be a good choice for your application.

In addition to your authentication scheme in APEX, you must also define an authorisation scheme. APEX does not require this as default, but you must never overlook the importance of defining an authorisation scheme.

You can think of authorisation in APEX as defining  responsabilities or roles. Think about it. If you do not define specific authorisations, any user that is in LDAP account can access all of your APEX applications and view data or transact.

I usually use a custom authentication as it gives me more control over the password processing as well as an ability to do some fine grain authorisation.

But, here is where my approach is somewhat different and is based on all the information above.

Where I have a “change or reset password page”, I replace the the placeholder of the password field to “Passphrase”.

The password policy I implement is really quite simple :

-- It must be at least 14 characters long
-- It cannot contain the user's first or last name
-- The same passphrase cannot be used twice in a row 
--The passphrase will expire every 30 days.

A lot of web applications are starting to use the concept of a “PassPhrase”. User’s need to be educated on what a passphrase is. So on the page I make sure there is a link that will help the user to understand what it is and how to select one.

The guidance I usually provide is something like this:

-- Your passphrase should be something that you can easily remember and type
-- Choose three or four words 
-- Choose words that are unusual and really don’t belong together
-- You might want to use your favourite band name or something like that for one of the words 
-- You can use symbols as part of the words but insert them rather than replacing letters with them 
-- Here are a few examples but you are not allowed to use these exact ones:

 eyelemonsink@level
tornattackfridgelink

·        - Do not use the same phrase for any other application or web service

Next I maintain a blacklist of words that cannot be used as part of any passphrase. This list may include such words as:


Password
Apex
Login
,,, and so on.

When validating a user’s selected pass phrase, I first check that it does not contain any of the blacklist words, and then make sure that it complies with the policy.

Passphrases, if done correctly are very secure and are less prone to any kind of attack. They are very easy for the user to remember and less likely to be typed with any errors. It will just take a bit of time to educate the user but in my experience they really like it and have provided some very positive feedback on the concept.

Some people recommend that users make use of some sort of password manager in to manage the specific passwords for applications and only require the user to remember one master password. Users can then create very random strings that are difficult to crack. This is a pretty good idea but with APEX I do not use a password manager.

It is my view that with APEX a password manager makes it very difficult, if not impossible, to access a APEX Workspace or an Apex application from any other machine than yours. I often do training and consultation where it is not always possible to use my own machine. If an APEX application is truly a web application, you should be able to access it from anywhere and from any machine.

I hope that at at the very least this article has got you thinking and reassessing how you store passwords in the database and how you set a policy that will be secure now and going forward.

Hackers get more and more advanced in their techniques all the time. We owe it to our users and our customers to protect their access security now and tomorrow. Secure access to your application is a constant process of evaluating your current measures against the current advances in password cracking across the internet.'

Want to see if you have been hacked?

Many applications set your email address as the username for your account. And, sadly, a lot of users tend to use the same password on more than one site.

You can check if your email address has ever been subject to a password crack on any site by going to the following URL:

https://haveibeenpwned.com/

Just type in your email addressed and it will show you if any password associated with the email addressed has ever been compromised.

ORA-600 [ossnet_assign_msgid_1] on Exadata

$
0
0
On a Exadata system with Oracle v12.1, a MERGE statement with parallelism was frequently failing with below ORA errors:

                   ORA-12805: parallel query server died unexpectedly
        ORA-06512

A quick look in the alert.log, an ORA-600 is noticed.

ORA-00600: internal error code, arguments: [ossnet_assign_msgid_1], [],[ ] 

The best and easy way to diagnose any ORA-600 errors is to utilize the ORA-600 tool available on MOS.

In our case, with large hash join, the following MOS note helped to fix the issue:

On Exadata Systems large hash joins can fail with ORA-600 [OSSNET_ASSIGN_MSGID_1] (Doc ID 2254344.1)

Cause:
On Exadata Systems large hash joins can fail with ORA-600 [OSSNET_ASSIGN_MSGID_1] and the root cause if often a too small default value  for _smm_auto_min_io_size  and  _smm_auto_max_io_size'

and the workaround to fix the issue is to set the following underscore (_) parameters:

_smm_auto_max_io_size = 2048
_smm_auto_min_io_size = 256

In some cases, the below MOS notes helps to fix ORA-600 [ossnet_assign_msgid_1] error.

ORA-600 [ossnet_assign_msgid_1] (Doc ID 1522389.1)
Bug 14512766 : ORA-600 [OSSNET_ASSIGN_MSGID_1] DURING RMAN CONVERSION

Oracle APEX 19.1 Early Adopter Now Available!

$
0
0

The Early Adopter program for Oracle APEX 19.1 is now available, and it's open to everyone!  The URL to access it is:

https://apexea.oracle.com

Prior to every major release of Oracle APEX, we conduct a hosted Early Adopter (EA) program.  This is similar to a hosted beta, and everyone is welcome to participate and provide feedback.  It's a great opportunity for the community to participate in the release process of APEX.  We welcome your feedback about features, user interface, bugs, functionality, and more.  Ultimately, it is your feedback which helps us shape Oracle APEX into a high-quality, polished framework.

 

There are some exciting new features in this release, including:

  • REST Enabled Forms
  • Data Loading Wizard
  • Dark Mode for the App Builder
  • PL/SQL API for Data Loading & Parsing (APEX_DATA_PARSER)
  • Oracle JET and jQuery Library Upgrades
  • JET Chart and Interactive Grid enhancements
  • and much more... 

 

A few things to keep in mind:

  1. This is hosted only.  We do not make early releases of APEX available for on-premises installation.
     
  2. Everything you do on the Early Adopter instances of APEX should be considered throw-away.  There is no guarantee that APEX applications you build in the Early Adopter instance will even be installable in the production release of Oracle Application Express. 

If you're reading this blog post after APEX 19.1 is released, you will find that the Early Adopter at https://apexea.oracle.com is no longer available.

We look forward to your feedback.  And thanks for being such strong supporters of Oracle APEX.  Our community is magnificent! 

Oracle APEX 19.1 Early Adopter ya está disponible!

$
0
0
¿Qué hay de nuevo en Application Express 19.1?

¡Esta versión ofrece una serie de nuevas características que incluyen formularios habilitados para REST, un asistente de carga de datos completamente nuevo con soporte para Excel nativo, una versión mejorada de Oracle JET, una nueva interfaz de usuario en modo oscuro y mucho más!

Visita: http://apexea.oracle.com


Quick and Easy Data Loading with APEX 19.1

$
0
0

A new, improved Data Loading facility is one of the new features in Application Express 19.1. This new feature is not only a dramatic improvement of the existing CSV Data Upload utility - it also supports more file types, detects settings automatically, runs in the background and comes with a PL/SQL API, which application developers can use.

This blog posting will introduces the new Data Upload facility in Application Express SQL Workshop. You can try this feature out on the APEX 19.1 Early Adopter Instance, available on https://apexea.oracle.com.

SQL Workshop Data Loading

To access the new Data Loading utility, Navigate to SQL Workshop> Utilities> Data Workshop.

Click on Load Data

You'll see a drop zone which allows to drag files to be uploaded. 

Drag a file to be uploaded here. The Data Loading utility supports Delimited files (CSV, tab-delimited), as previous APEX versions did. Beyond that, also XLSX files (Excel workbooks), JSON and XML files are supported. 

CSV Files

CSV Files must have an extension of either .txt or .csv. After dropping such a file ...

  • it will be uploaded
  • the parser will auto-detect the delimiter character
  • the parser will sample the first 200 rows of the file to detect data types

APEX will present a preview of the file contents as follows:

If APEX does not get the parser configuration right, settings can be adjusted ...

  • The delimiter character can be chosen as the comma (,), semicolon (;), pipe (|), hash (#) or the tab character. APEX detects this automatically
  • Choose whether the first rows contains column headers (default is Yes).
  • Choose whether contents are optionally enclosed by quotes. APEX assumes Yes by default. If you know that this is not the case, you might switch that off.
  • The file encoding as assumed as Unicode (UTF-8). If that is not the case, pick the right file encoding from the select list.

Click the Configure button and then the Columnsto Load tab in order to get some insight on the detected data types. 

APEX shows which data types it has detected. All format masks for NUMBER, DATE or TIMESTAMP data types are also detected automatically. Decimal and group characters are detected individually for each NUMBER column.

For larger data sets, it might make sense to increase the Rows to Sample (click the 1000, 5000 or All Rows pill button) in order to have APEX sample more rows. The more rows APEX samples, the more accurate the detected data types will be.

Once you you're sure that settings are fine, click the Save Changes button. The dialog closes and the previous dialog reloads.

Now provide a name for the new table to be created. The Error Table Name will be used to create a second table: This error table will be used to store rows, which cannot be inserted into the target table.

That can happen, if APEX e.g. only samples the first 200 rows and detects a column as NUMBER. But later on, the file contains non-numeric values for that column - those rows will be stored in the error table (for the experts: APEX leverages the DML Error Logging database feature here).

The error table is a normal Oracle table with the same columns as the target table, but all defined as  VARCHAR2(4000). You can review the error table in SQL Workshop after load and manually process these rows. If APEX is able to load all rows to the target table successfully, it will drop the (empty) error table automatically.

When the Use Column Data Types checkbox is unchecked, APEX will not use the detected column data types - instead the target table columns will all be created as VARCHAR2(4000).

On Database 12c or higher, you can choose whether the Primary Key column will be generated using the Identity Column feature or whether a globally unique identifier (SYS_GUID) shall be used. The difference is values and space requirements. Identity Column values are like sequences - they start with 1 and increase. SYS_GUID values are globally unique, hard to predict, but require more space than the compact Identity Column numbers.

Configure your load as desired and click the Load Data button. Add loading will be executed in the background, so if you close the dialog while loading is in progress, it will continue.

Once Data Loading is finished, you shall see a success message. In this case, all data has been loaded to the target table successfully. The (empty) error table has been dropped.

If some rows cannot be loaded to the target table, they will be stored to the error table. The success message will then look as follows:

One option is to drop the tables and retry the data loading operation, the other one would be to continue with the target table as-is. The error table is available for manual processing in SQL Workshop, SQL Developer, SQL*Plus or other development tools.

Loading XLSX files

Loading XLSX files is similar to loading CSV files. Of course, there is no need to detect or to choose delimiter or enclosing characters. So, the preview dialog looks as follows after uploading an XLSX file.

If the uploaded XLSX file contains multiple worksheets, APEX will pick the first sheet by default. To load another sheet, pick it from the Select Sheet select list. The First lines contains headers checkbox works similar to CSV files. The same is true for the Configure dialog: the behavior is the same as it is for CSV files. Uploading XLSX files is limited to 20MB for each file.

Loading XML files

XML files can also be uploaded to APEX. However, APEX supports only "flat" XML structures, like the following, which can easily be mapped to a table and columns. XML structures with multiple levels of nesting cannot be loaded by the new Data Loading wizard.

APEX will look for the first repeating XML (here: PLANT) Tag inside the document (root) element (CATALOG). All XML tags within the PLANT tag will be treated as columns.

Of course, there are no delimiter or enclosing characters to choose. Also the column names are derived from the XML tag names, so there is no First lines contains headers checkbox. XML files are limited to 10MB each.

Loading JSON files.

Loading JSON files works similar to loading XML files. Only "flat" structures are supported - deeply nested JSON structures cannot be loaded.

JSON files are limited to 20MB on 11g and 12.1 databases. For Oracle Database 12.2 or higher, there is no size limit for JSON files.

Summary

The new Data Loading wizard in Application Express 19.1 makes it super-easy to load Spreadsheet, CSV, XML or JSON data as a table into your APEX workspace. Unlike previous versions, APEX detects almost everything automatically - there is no need any more to manually pick data types, provide format masks or decimal characters. 

The actual Data Loading runs in the background - so the dialog can be dismissed if a larger file is being uploaded. If "bad" rows cannot be inserted into the target table, the whole load is not "lost" any more - all rows are still accessible in the error table and can be post-processed manually.

But there is more ...

The fundamental piece of functionality, the new file parser, is available as a PL/SQL API as well: Using the PARSE function within the new APEX_DATA_PARSER package, developers can parse JSON, XML, CSV or XLSX files themselves - and implement their own processing of uploaded data.  This will be explained in more detail in a separate blog posting. 

Stay tuned.

Mystery and imagination of DELETE RETURNING INTO

Oracle APEX Less Social Sign-On with MS Azure and Office 365

$
0
0
After my last blog post a natural question came up: what if I'm a little anti-social?

Specifically, what if I do NOT want to make my APEX application available to everyone on the planet that has (or is willing to get) a Microsoft Azure / Office 365 account? What if I only want people in my company, that uses Azure AD, to be able to log in?

There are several ways you can do this, and I recommend you employ at least two. No, recommend is too lenient, I insist you employ at least two :). The first is to change the way you call the Microsoft OAuth2 provider. Instead of using the values in my last blog post:


Authorization Endpoint URL: https://login.microsoftonline.com/common/oauth2/v2.0/authorize
Token Endpoint URL: https://login.microsoftonline.com/common/oauth2/v2.0/token

Use the following:

Authorization Endpoint URL: https://login.microsoftonline.com/yourCompanyDomain/oauth2/v2.0/authorize
Token Endpoint URL: https://login.microsoftonline.com/yourCompanyDomain/oauth2/v2.0/token

For Insum, this would be insum.ca:

Authorization Endpoint URL: https://login.microsoftonline.com/insum.ca/oauth2/v2.0/authorize
Token Endpoint URL: https://login.microsoftonline.com/insum.ca/oauth2/v2.0/token

The method above does NOT secure your application to just your domain. It just makes it harder for someone to use another domain. A savvy user can bypass that by just typing "common" in the url.

The REAL step to secure your application is to do one or both of the following:

  1. Create an Authentication Scheme sentry function that makes sure the username includes @yourdomain
  2. Create Authorization Scheme that makes sure the username includes @yourdomain and apply it to the application.

I am often logged into multiple Azure AD accounts at the same time. By adding yourCompanyDomain to the Endpoint URLs you have the added bonus that users do not need to select a login each time they go to your application. Microsoft will detect the correct one to use.

Oracle APEX and Google reCAPTCHA v3

$
0
0

Google reCAPTCHA v3

 

How to integrate reCAPTCHA v3 into APEX?


Oracle APEX and reCAPTCHA v3 integration


Some of you may know that APEX plugin for reCAPTCHA v2 has been available for a while which you can download here thanks to Mohamed Zebib.  



In October 2018 Google announced new version which now does not require any user interaction what so ever unlike version 2 where websites had


and users had to click I'm not a robot checkbox. 

This post is about integration it into your APEX apps. Let's have a look how.

For simplicity we will do it on Login page - P9999 where before user is allowed to login we will run a reCAPTCHA check.
All about reCaptcha v3 you can find at https://developers.google.com/recaptcha/intro

Implementation

Step 1.
To start using reCAPTCHA, you need to sign up for an API key pair for your site. Why? 
"The key pair consists of a site key and secret key.

The site key is used to invoke reCAPTCHA service on your site or mobile application.
The secret key authorizes communication between your application backend and the reCAPTCHA server to verify the user's response. "

Step 2.
Create Application settings that will store your public and secret keys like

Give them any name you want. 

Also create application process and application item. Something like this
:APP_RECAPTCHAV3_SITE_KEY := APEX_APP_SETTING.GET_VALUE( p_name => 'RECAPTCHAV3_SITE_KEY');

Where APP_RECAPTCHAV3_SITE_KEY is application item getting set.

Step 3.
On your login page add lines to initialize reCAPTCHA as per https://developers.google.com/recaptcha/docs/v3



Try running the page if you have done all things correctly you should get the famous logo running on the page. 

Step 4.
Now create P9999_TOKEN and P0_MESSAGE items on page 9999 and page 0. We will store the return message into global P0_MESSAGE element so that we can show it once landing page shows up.

Step 5.
Add application process with similar package call.


begin
  authentication_util.process_recaptcha_reply (p_token => :P9999_TOKEN, p_message_out => :P0_MESSAGE);
end;





Step 6.
Change condition on the standard Login process




All there is to do is download the PL/SQL package body here and compile it. 


Your apps should be even more secure now. :D


Happy APEXing,
Lino

Region only shown in development mode in Oracle APEX

$
0
0
In the last months, I had to look up several times in different projects how to show a region only when I was logged in into the App Builder in Oracle Application Express (APEX). So I thought to write a quick post on it.

In one project we had to log in with different users to test the behavior of the authorization schemes, so people saw the things they should see and could do the things they are allowed to do. As the logins where not straight forward we created a region with those test credentials. Other people were testing too with their own credentials, so we really wanted to keep the original login page, and decided to just add a region on the page we would only see when we were logged in into APEX itself.

Today I added some new pages to an app and wanted to make sure the navigation to those pages were only visible to me. I know, you should do this in DEV, and then when all is fine, propagate the app to TEST and PROD. The truth is, I've some applications that only exist in one environment and so I update straight in "production". Those apps are still backed up automatically every night, so worst case I can always take the version of the previous day. But just to be clear, this is not good practice ;)

So how do you show a region only when you are in development mode in Oracle APEX?

You go to the Conditions section of your region, list entry or any component in APEX really, and add a PL/SQL Expression: apex_application.g_edit_cookie_session_id is not null


It would be cool if there was a condition type "Development Mode", but maybe I'm the only one needing this...

Typically you would use Build Options (see Shared Components) to include or exclude certain functionality in your APEX app, but in the above two use cases, it won't really work.


Another enhancement would be that the Status of the Build option would include "Dev Only" next to Include and Exclude.

Forms in APEX 19.1: More power, more Flexibility

$
0
0

The latestAPEX Early Adopter Release 19.1 introduces a lot of new functionality for forms. First, there is REST Service and REST Enabled SQL support for forms, as outlined in the Statement Of Direction. This will be covered in a separate blog posting in more detail.

Today we have a look at some other, general changes to form pages in APEX 19.1. The most straightforward way to do this is to log into the Application Express 19.1 Early Adopter Instance, create a new application and create a form. In the Create Page wizard, click Form and the Next button.

The most easy way to experiment with a form is the Report with Form option. That will allow us to play with creating new rows as well as changing or deleting existing rows.

The next wizard step also looks similar to previous APEX releases. Provide names for the report and forms pages, adjust the page numbers (if required), decide whether the form should be a modal dialog or a normal page and so on. When finished, click the Next button and decide whether you want to have a navigation menu entry for the new pages. Click Next again - you will be directed to the Data Source wizard step.

This step really looks different in the new APEX release: APEX continues its way to support multiple data sources, which has started with APEX 18.1: Now, not only report, charts or calendars can be created on external data sources, forms support this as well. As stated in the beginning, the Web Source Module option will be covered in a separate blog posting - today we'll focus on Local Database

Instead of creating a form on a table, we'll pick the SQL Query option. Forms can now also operate on the same query types as report, charts or calendars. Thus we can not only create a form on a table, but also on a SQL query and ... on a PL/SQL function returning a SQL Query (in the latter case, the column list of the SQL query generated by the PL/SQL code must be stable and not change at runtime). 

Use the following SQL Query to create the report and form pages:

select e.empno, e.ename, e.job, e.hiredate, e.sal, e.comm, e.deptno, (select dname from dept where deptno = e.deptno ) as dname from emp e where deptno = 10

This SQL query has two interesting aspects:

  1. In the WHERE clause, we have a restriction to DEPTNO = 10. So it should not be possible to use the form to edit rows with DEPTNO = 20

  2. The DNAME column columns from a subquery. This column is, of course, not updatable. 

In the next wizard step, pick a primary key column and then click the Create button in order to create your report with form pages.

As in earlier versions, APEX actually assumes that the primary key column is auto-generated (default value, sequence with trigger or identity column). Thus APEX will create the page item for the primary key columns as hidden items. If your primary key column is not auto-generated, you need to manually change the form page to make the primary key page item a visible form field.

When done, you will be redirected to page designer for the report page. Run that page to show the report. It shows only a subset of the EMP table - so far, so good.

Click the pencil icon to edit one of the rows. A modal page with the form should open. However, once you try to change the row, you will see an error message.

The error message is natural and had to come: the reason is that the form also tried to update the DNAME column of the SQL query. However, that column came from a subquery - and the Oracle Database is not able to perform such updates. And actually this column is only informational - since it is derived from the DEPTNO column. So let's apply a tiny change to the form in order to get it working:

  • Open Page Designer for the form page

  • Look up the PX_DNAME item and change its Read Only attribute to Always and its Query Only attribute (within Source) to Yes

Save your changes and retry the operation. The form looks slightly different - and all form operations now work.

A very interesting case is changing the DEPTNO value to 20. Since the form SQL query restricts the data to rows with a DEPTNO value of 10, this should be an invalid operation. And consequently, you will see an error message.

Let's now have a look at the form page itself. In earlier versions, a form consisted of the following:

  • One or more regions containing the page items

  • One Automated Row Fetch process in the Pre-Rendering section

  • One Automated Row Process process in the Processes section

The actual information on the table, the primary key columns and the optional WHERE clause to use, was stored in both the Row Fetch and the Row processing processes.

This changes with APEX 19.1: A new region type, the Form Region is introduced.

As all other region types, Forms now also store their data source information once at the region level. And the data source can be the local database, a REST Enabled SQL service or a Web Source Module. There are still two processes: Form - Initialization in the Pre-Rendering section and Form - Automatic Row Processing (DML) in the Processes section. Both processes reference the form region.

When a form region is on the page, a page item has two region references.

  • The Region attribute in the Layout section determines, where the item is displayed. This is unchanged in 19.1.

  • The Form Region attribute in the Source section determines where the data for this form region comes from. When this item is set, the form region and its processes control how the item is initialized on page load and processed on page submit. If this attribute can be empty, the item works as in previous APEX versions.

There are no restrictions regarding page, regions and item layout. Form region items can still be positioned on any other region. Let's now have a closer look at the items' Source section where the data source for a page item is configured.

Once the form region is chosen, the Column select list will be populated from the result columns of the data source configured in the form region. Once a column is picked, the Data Type will adjust automatically. It's not recommended to manually override the data type - always accept the APEX proposals. Only change the data type, if you know that the current selection is wrong (e.g. after a table change).

The most important switches are Query Only and Primary Key. A form region must have at least one primary key item; otherwise the page will not render. If Query Only is set to Yes, this item will only be fetched during initialization, but it will not participate in a DML operation. That is very useful for data source columns which are not updatable, like virtual columns or the subquery in our example.

Assigning an item to a form region has impact on its initialization behavior:

  • Items which are not assigned to a form region, will have their Default applied on page load, whenever the page item value is NULL. This behavior is consistent to earlier APEX versions. A default value can thus be also applied when a row was fetched from the data source by a custom PL/SQL process.

  • Once a page item is assigned to a form region, the Default value will only be applied when the primary key items are empty and thus no row is fetched from the data source. As soon as a row is fetched from the data source, the Default value will not be applied any more.

The old Used attribute which was either Always, replacing any existing value in session state or Only when current value in session state is null, was very confusing to APEX developers. Thus this attribute was removed for form region items and is not needed any more. The Always, replacing any existing value in session state option was actually only used by the old form pages, so for items not assigned to a form region, developers can always choose Only when current value in session state is null here.

Besides the data source, the form region offers additional settings in the Attributes section.

As for Interactive Grid, the developer can decide whether the form region is editable at all or not. When that attribute is set to No, the Automatic Row Processing (DML) process will be removed. This is useful for form page which are there to display data only. On editable forms, specific DML operations can be prohibited with the Allowed Operations checkbox. That information can also come from one of the data source columns (Allowed Row Operations Column). Finally the Lost Update Type can be chosen between a row checksum (Row Values) or one specific Row Version Column. This will control how APEX generally detects a lost update.

More interesting settings are configured in the Automatic Row Processing (DML) process.

The Target Type attribute determines whether APEX executes the DML processing on the table or SQL query from the Form Region source, an alternative table or whether it should execute custom PL/SQL code.

The Custom PL/SQL code option is particularly interesting here: Since the PL/SQL code is stored and executed as part the Automatic Row Processing (DML) process, developers can still use the Lost Update Detection feature. That was not possible in earlier APEX versions - as soon as developers wanted to use custom PL/SQL code, lost update detection was not available any more and had to be implemented manually. But the new form region allows to use custom logic to be executed as form DML - and still leverage built-in features like Lost Update Detection.

The new Automatic Row Processing (DML) process also provides more flexibility regarding lost update detection and whether rows should be locked or not. Both features can be turned on or off and are on by default. 

It's noteworthy that Lock Rows does not mean that rows are locked when the form page is loaded. APEX is still a web application and locking rows when the form is loaded into the browser would be a bad idea: How often are browsers just closed and such a lock would never be released. APEX never locks rows when the form page is loaded. But what does Lock Rows mean, then?

Lock Rows is all about that tiny time window between the (successful) lost update detection and the actual DML. So let's have a closer look what exactly happens:

  1. APEX performs lost-update detection. Either the row version column or a row checksum is fetched and compared with the value when the form page was loaded. If the checksums (or row versions) are identical, there is no lost update and APEX can proceed with its DML. If there is a difference, somebody changed the row in between - and APEX will raise an error message.

  2. APEX performs the actual DML operation.

But in that tiny fraction of a second between 1. and 2., another browser could have successfully executed a DML operation. And even with Lost Update Detection enabled, we would have a lost update. To prevent that, the Lock Rows attribute is set to Yes. That will lead to ...

  1. APEX performs lost-update detection. The row is locked and either the row version column or a row checksum is fetched and compared with the value when the form page was loaded. If the checksums (or row versions) are identical, there is no lost update and APEX can proceed with its DML. If there is a difference, somebody changed the row in between - and APEX will raise an error message.

  2. APEX performs the actual DML operation. The lock will be released after success.

Since the row was now locked between 1. and 2., we cannot have a lost update scenario any more.

For some data source types (Web Source Modules, complex SQL queries), it might be required to have no row locking or to use custom PL/SQL code to lock rows. Use the Lock Rows attribute to configure that.

 

Try the new form region and its various settings out. Since the data source is now available at the region level, APEX now also supports multiple form regions on a page. The new form region provides way more flexibility and power to the APEX developer.

Since its behavior is different to the old form pages and its processes, there is no(!) automatic migration of form pages. However, APEX offers an application upgrade tool to migrate old form pages (legacy forms) to the new form region. Navigate to your application, then to Utilities> Upgrade Application

An application upgrade is offered for legacy form pages, when a minimum set of requirements is met. For instance, the table, primary key and WHERE clause settings must be identical for the Automated Fetch and Automated Row Processing page processes. However, it is recommended to perform that upgrade on a copy of your application and to test afterwards - form pages typically have a lot of custom functionality, additional PL/SQL code and other things - so do test thoroughly after such a migration.

The Application Express Early Adopter Instance allows to get a workspace on APEX 19.1 today - so get your workspace, log in and try the new Form region out today!

 

APEX – A Well-Integrated, Web-Based Oracle Tool for EBS Development

$
0
0

APEX a Modern Web-Based Oracle Tool for EBS Development

In my previous blog, the first of four in this series, I explained how Oracle APEX, Oracle’s Rapid Application Development (RAD) platform allows you to improve the E-Business Suite (EBS) business processes you and your users find inefficient. Because APEX is a RAD platform, it can help you do this very quickly. As it is a fully supported no-cost feature of your licensed Oracle database, it is also a highly economical option.

In this blog, I’ll briefly explain why Oracle APEX integrates so well with EBS.

For starters, APEX is a 100% Oracle product. It is one of the most popular features of the Oracle database, integrated and secure for any scale deployment. This foundation enables applications built with APEX to be enterprise-ready from day one, just like your EBS instance is.

High-Level Architecture

Here’s a simple visual of database schemas showing how APEX and EBS interact. You can here a model of your EBS instance and an APEX installation.

EBS development APEX and EBS on Oracle Database

APEX lives directly in the database, right next to the database component of your EBS instance. This guarantees APEX-built applications are able to take advantage of all the security features and the scalability that your Oracle database offers.

As you can see in the image, the APEX database schemas stand apart from EBS schemas on your database.  In accordance with EBS development standards and best practices, it never modifies EBS source code, but rather works with it. In other words, you won’t risk breaking your EBS support with APEX.

Oracle APEX is also independent of the version of EBS you use. Whether you are using anything from 11i to R12.2.x, any updates you may make to your EBS system will have no impact on the APEX engine. As usual, APEX applications or extensions you are creating in the context of EBS need to go through regression testing, which is a practice every mindful organization should execute when applying EBS patches and updates.  By the same token, upgrades to Oracle APEX won’t impact your EBS installation.  This means reliable, headache-free application performance for years to come.

Here are a few more of the “special ingredients” that enable APEX to integrate so well with E-Business Suite:

 

A Familiar and Reliable Coding Language

EBS developers will find themselves at ease when developing EBS extensions with APEX as they can leverage their SQL and PL/SQL skills to develop applications more quickly and without learning a new language. No need to go through a period of trial and error to get started.  Your developers will become more productive, faster.

All of your EBS APIs, views and synonyms can be used just the way you are used to in EBS.

A Low-code Development Environment

APEX provides a development environment where a page or report can quickly be assembled using wizards, adding a high-level of functionality to your applications with limited coding.

For example, with a simple SQL statement like “select * from view where…”, you can generate an online report (called interactive report in APEX) where you empower users to manipulate the results (filters, group bys, highlights, etc.) on the screen without the need to call a concurrent program and wait for the “paper” report to come out.  Any APPS synonym or view can used in an APEX application, making sure your data security configuration is maintained.

A better Feedback Loop with Your Users

Not only can applications be quickly created, so can Proof of Concepts (POC). This is one of the great advantages of Oracle APEX. It allows your developers to quickly put together a working version of an application. This way, your users can examine and request adjustments on it before it goes into production. This frees your developers up to take in more user feedback and create more user-friendly applications, resulting in more productivity.

APEX comes with powerful templates that provide intuitive and good-looking layouts for EBS users. What’s more, the templates are highly customizable. I’ll show some examples of those in the next blog in this series.

A Modern Web-Based Tool

Because it is a modern tool, APEX can consume and expose web services. For example, when your EBS system must provide information to other services in your organization, such as supplier or sales order information, this data can be exposed as a web service, replacing Excel or text files, and improving data security and efficiency. Equally, APEX enables you to consume web services either from within your organization or anywhere on the planet. I’ll be talking about the exciting possibilities that APEX and web services bring to EBS in my presentation at Collaborate19, entitled « RESTful Web Services – Break the EBS Jail ». Collaborate19 happens  April 7th to 11th 2019 in San Antonio, Texas

Here at Insum we’ve developed a tool that enables APEX to integrate so completely into EBS, it is exactly as if you were in it. The experience is transparent, right up to the colors and the fonts used, as you’ll see in my next blog.

Moreover, the Insum tool also enables APEX to integrate perfectly with the EBS menu and it can recognize data security for operating units and multi-org access, and function security including responsibility exclusions already set up in your EBS system.

 

A Technical Overview

Finally, If you or your developers would like to see more technical detail on how APEX can extend a variety of EBS functions, I recommend reading our EBS Extensions Technical Brief

 

If you’d prefer to talk to us now about how you, your developers, and your users can benefit from our APEX integration solutions, contact us!

The post APEX – A Well-Integrated, Web-Based Oracle Tool for EBS Development appeared first on Insum.


Oracle APEX Consolidated Help

$
0
0
I recently had the need to show "most" of the application help on a single page in my APEX application. In order to make the procedure generic and easy to use, I didn't want to create any additional database objects--just a procedure to output what I needed. I decided to create a separate APEX Navigation List to create the hierarchy of pages that I want to include in the consolidated help page. The easiest way was to copy my "Desktop Navigation Menu" and then modify it. Of course, I could have just used "Desktop Navigation Menu" if it met my needs. The result looks like this





Others may need to do the same thing so I'm providing the code here. I apologize that I don't have good code formatting on this blog. I'm providing it as a standalone procedure, but you should put it in a package.

https://github.com/ainielse/rando/blob/master/output_consolidated_help.sql

APEX 18.2 and IG Detail view issue

$
0
0

APEX 18.2 and IG Detail view

 

How to display url based images in your IG cards?

 

Interactive grid Detail view issue


While it is still fresh I want to write down very interesting feature we encountered working with Interactive grid Detail view last week.
 

Brief was simple we wanted to have a reporting region base on SQL query that would show us cards and ideally leverage lazy loading as infinite scrolling. Straight away IG rang a bell.
 

Cutting the story short, we started playing with IG Cookbook application that is great resource to learn about IG in general by John Snyders

Obvious candidate is page 20 titled IG Cards.

It is doing all what we wanted it has a card template embedded it is based on SQL query and has infinite scrolling support. Perfect!

Requirement #2 is let’s display image inside of the card but not one from Font APEX but any image accessible over URL.

Idea to get to this is to  
1. modify your query on page 20 add a column that would hold your URL. 
Something like'#WORKSPACE_IMAGES#any.gif' as img_src.

Then you reference this in your Attributes -> For Each row under a Detail view using a substitution string <img src=&IMG_SRC. />

Save and run the page. Great, image is there, all works as expected. Everyone is happy!???

Well not quite. Open your browser console network tab and refresh the page. You will see 404 resource not found error like below. 
After few days of trying to work out why this is happening we posted a question on #orclapex slack channel and OTN forum. 

As this is not something you would expect to get considering that our page is displaying correctly, IG is working and there are no other JS messages.

More in depth story you can find here.


Bottom line here is, there is a flaw in how IG creates this template and gets your data in so browsers can detect an empty/invalid URL in this process. 

Luckily, APEX community is a great community and Shaun Mauer jump to the rescue with his idea.
  


Workaround
  1. Change your Query column source to be 
  2. Change IMG_SRC to be of HTML Expression typewith &IMG_SRC.as a source
  3. Change your Card template so that it only uses &IMG_SRC. now in place where we had <img src=”&IMG_SRC.” />    
This should make 404 go away and now is time to celebrate. 

To add to this is that, maybe in next release of APEX we may see this fixed in IG detailed view.


Again big thanks goes to John as well for joining the conversations.

Happy APEXing,
Lino

Now Accepting Applications for the ODTUG Women in Technology Scholarship

$
0
0
As part of our continuing effort to offer learning opportunities in all areas relevant to our membership, ODTUG is pleased to announce the fifth annual Women in Technology Scholarship Program.
Viewing all 2258 articles
Browse latest View live