Last revision: 27 sept 2022

The purpose of this project is to give to business users a no-code tool for generating forms.

This project called GFM Builder is at prototype stage. It relies mainly on API wich are not documented, even if there are widely used in APEX export App files (before 22.1 version). This approach is clearly no supported, so this tool must be considered as a playground and used in a sandbox only.

The application GFM Builder is available from Github.

Target audience

GFM Builder addresses mainly companies intranet requirements but citizen portals needs as well.

A common use case is to trigger an administrative process based on informations provided by an employee or a citizen. ie: renewal contrat, ordering internal good, signaling problem in a district, etc.

This tool will leverage, in a next version, the new approval task process which can be embeded in a page.

Once these limitations given, let’s see the functionnal aspects.

High level design

Persona and Role definitions

GFM Builder is dedicated to business users.
That means that we haven’t to declare users as APEX developers. Users will be able to author and publish forms without any knowledge of Oracle APEX.

We consider the following roles:

  • Regular APEX Roles
    • APEX Workspace Administrator
    • APEX Developer
    • APEX End User
  • Application Roles brougth with the tool
    • GFM Builder Administrator
    • GFM Builder Developer
    • Final user ( means an APEX End User or an anonymous user)

The GFM Builder Role is implemented as a Contributor Role in the APEX simplifed ACL model.

The GFM Builder Administrator role is maped on Admin Role

In order to build a form, the GFM Builder Developer role must be granted to an APEX End user.

Generated Form Samples

Below are sample of forms generated with GFM Builder.

In this case, we choosed to display fields grouped by sections (GENERAL, RH, ..)

A form can embed a detail array for multivalued informations. In this case, it’s a historic of entries.

Using a detail array inside a form

Apps Store

A sample catalog application (GFM Store) is provided as an exemple. Each time a form is tagged as Published, it will be displayed in this catalog.

Data collecting

All data are stored in a unique table GFM_DATA.

The data can be displayed by GFM Builder Admin and Forms owners.

Final users will not be able to display data. We suppose that a process will send data to the user, by any feedback way, email for instance. It’s not in the scope of the project.

Simplified report displaying data collected through a form

Form design

The design process is mainly declarative. It’s a matter of designing the items which constiture the form.

Instead of creating a data set then building the form (in in standard way), we create there both the data set and the form in the same user interface.

A form is comprised of items. An items is either a simple attribute (like text Field, date) or a multivalued attribute. This second kind of items is implemented as an Interactive Grid. This technical choice provides more flexibility during fields filling.

Items must be pick up from a predifined collection of components which are:

  • Basic items
    Text,Number, Date, email, Inline List (List of values declared inline)
  • Predifined List of values
    These lists are created in a dedicated page called ‘Components’, either by an administrator or the user himself.
  • Grids
    It’a an existing form wich is declared as been usable as a grid inside an other form. ie: Historic of positions, list of contracts, etc.

Reusing existing form definitions

It’s possible to copy all items of an existing form into an other form.

  • Inline declaration
    value and label are given the same value.
  • Specification declaration in component module
  • External declaration
    per declaring the name of the external table or view.

Sections

A section is a logical group of items which will be rendered as either a tab or a paragraph, depending a preference.

Fields are spreaded in sub-regions if there are two sections at least referenced by items. Navigation is provided by tabs, either with regular tabs or tabs and a first overall tab.

Example of navigation with preference $REGION_SECTION =DISPLAY_SELECTOR

User Interface

The user interface is very classic with very minimum usage of Drag n Drop. This is a weakness if we compare with other no-code tools on the market. But on an other hand, the tool priviliges flexibility in rendering, that is not the case with « Google Forms », for instance.
At the minimum, it’s possible by Drag’n Drop to re-order displayed items.

Rendering

Very Minimal Decoration

This image has an empty alt attribute; its file name is image-8-1024x547.png
Minimal decoration

Generation options

a set of preferences drives the generation process. We have reused APEX terminology in order to be in line with the regular Developer Interface.

For the moment, there are a few preferences:

  • $ITEM_TEMPLATE (FLOATING, ABOVE, BESIDE)
  • $ITEM_HELP (Y,N)
  • $PAGE_TEMPLATE (MINIMAL_NO_NAVIGATION)
  • $REGION_SECTION (STANDARD, TABS_CONTAINER,DISPLAY_SELECTOR

Below are some variants depending on « Navigation between sections » preference

Section in a standard rendering

Sections rendered with Tabs

List of Values

The creation of list of values is done by creating a new component with a LIST type. Then, a second page is used for entering the values.

List of components (The predefined lists are tagged List)
Entering the values for a List of Values component.

Conditionnal displaying

An item can be displayed or not depending the value of an other item. If the driving item is based upon a List, the list of values will be proposed for choosing a specific value which will trigger displaying of slave item.

Technical design

Data Model

Implementation

  • A data model for the form/Sections/Items, preferences and components
  • A main data store (GFM_DATA), designed in the same way that the apex_collection table. There are 50 items at maximum.
  • As many views there are forms. Each view is given an instead trigger.
  • For each form, a specific view maps columns on given columns of the gfm_data table.

Generating process

  • Re-generate specific view
  • Re-generate specific Trigger
  • Generate the corresponding Page in a target Application.

The target application must belong to an arbitrary Application Group called ‘GFM Apps’ and must be choosed in the setup page. The ‘GFM Apps’ is automatically created during installation of GFM Store application.

List of Values

All the data are stored in a dedicated table: GFM_LOV.

Objects are named in Oracle database with GFM_ prefix

Lifecycle

If an item is renamed, there are no impact in the mapping

If an item is dropped, the mapped column in the GFM_DATA table is preserved, and no other item won’t be mapped on it. The reason it that we want avoid to display old data with the new item.
An option menu allow to reset data and column mapping.

Security

Before form are deployed, they must by set « Published » state.

A form can be accessible either in a anonymous mode (no need to be authenticated) or in an authenticated mode.

because GFM Builder relies intensively on internal APEX API, some important flags have been set:

A compagnon Application called ‘GFM Store’ is provided as an example of an Apps store.

Appendices

Non documented APIs used in this project

  • wwv_flow_api.create_page
  • wwv_flow_api.create_page_plug
  • wwv_flow_api.create_page_button
  • wwv_flow_api.create_page_branch
  • wwv_flow_api.create_page_item
  • wwv_flow_api.create_page_process
  • wwv_flow_api.create_page_da_event
  • wwv_flow_api.create_page_da_action
  • wwv_flow_api.create_region_column
  • wwv_flow_api.create_interactive_grid
  • wwv_flow_api.create_ig_report_column

APEX export API have been rewritten in 22.1 (wwv_flow_imp). That means that the previous API are not garanteed to be working in the future, and therefore neither is this tool GFM Builder.

Plugins used in the project

This material should be implemented as a region Plugin but not enough time and overall, it’s quite easy to adapt it manually.
Approach used is to generate button from a pl/sql code and implement the needed JS code.

Another approach using regular APEX buttons with Dynamic Actions did’nt give acceptable result.
Color scheme is picked from Redwood Light look and feel.

Code

Create a region PL/SQL dynamic content

Add a page Item Pnn_RATE

Add the Following code intro the PL/SQL code property and change :P6_RATE by your item page name and choose between three or five emoticons (l_nb number :=5)

DECLARE
    l_css apex_t_varchar2;
    tout varchar2(32000) := '';
    l_emoji apex_t_varchar2;
    l_size varchar2(100) := ' fa-2x fa-lg ';
    l_gap varchar2(100) := '' ;     -- gap between two icons
    l_js varchar2(32000);
    l_rate varchar2(2);     -- rate value
    l_nb    number :=5;     -- number of emoji (3 or 5)


BEGIN
    l_rate := :P6_RATE;
    htp.p('
        <STYLE>
            .btn {
                padding: 0;
                border: none;
                background: none;
                font-size: 10px;
                cursor: pointer;
            }
            .btn1 {
                background: radial-gradient(#d63b25 50%, transparent 50%);
            }
            .btn2 {
                background: radial-gradient(#ac630c 50%, transparent 50%);
            }
            .btn3{
                background: radial-gradient(#d8d0b5 50%, transparent 50%);
            }
            .btn4{
                background: radial-gradient(#c2d4d4 50%, transparent 50%);
            }
            .btn5{
                background: radial-gradient(#bdd9ae 50%, transparent 50%);
            }
            
            .btnsel {
                padding: 0;
                border: none;
                color: white;
                //background: none;
                background-color: silver; //#bac9ba;
                font-size: 10px;
                cursor: pointer;
            }

        /* Darker background on mouse-over */
        
        .btn:hover {
            background-color: silver;
        }
    </STYLE>  
    ');
    if l_nb = 5 then
        l_emoji := apex_t_varchar2('fa-emoji-frown','fa-emoji-slight-frown','fa-emoji-neutral','fa-emoji-slight-smile','fa-emoji-sweet-smile');
        l_css := apex_t_varchar2('btn btn1','btn btn2','btn btn3', 'btn btn4', 'btn btn5');
    elsif l_nb = 3 then
        l_emoji := apex_t_varchar2('fa-emoji-slight-frown','fa-emoji-neutral','fa-emoji-slight-smile');
        l_css := apex_t_varchar2('btn btn1','btn btn3','btn btn5');
    end if;
    
    -- Displaying the icons
    
    tout := '<div>';
    if l_rate in (1,2,3,4,5) then
        l_css(l_rate) := l_css(l_rate)|| ' btnsel';
    end if;
    for i in 1..l_nb loop
        
        tout := tout ||
        '<button type="button" id = "pb' ||i || '" class="'||l_css(i) ||'" ><i class="fa '||l_emoji(i) || l_size ||'" ></i></button>'|| l_gap
        ;
    end loop;
    tout := tout || '</div>';
    htp.p(tout);        -- renders html markup

    -- Builds JS code

    l_js := '
    <script type="text/javascript">
        function clearcss () {
            for (i=1;i<=5;i++) {
            document.getElementById("pb" + i).classList.remove("btnsel");
            }
        }
        function setRate(pnro) {
            apex.item( "P6_RATE" ).setValue( pnro, null, true );
            clearcss();
            document.getElementById("pb" + pnro).classList.add("btnsel");
        }';
    -- adding Listeners
    for i in 1..l_nb loop
        l_js := l_js || '
        pb'||i||'.onclick = function() {
            setRate("'||i||'"); 
        }            
        ';
    end loop;
    l_js := l_js || '</script>';
    htp.p(l_js);

END;

Below, a color palette get using block css (u-color-nn) in a card template. Goal was to display scorecards with differents look and feels. CSS class has been set at the Card CSS classes level in the Attributes tab

For comparaison, the same palette with VITA Slate theme style. (Other VITA styles render colors identically)

J’ai eu l’occasion de faire une présentation sur le Low-Code et j’en ai profité pour faire auparavant un tour de l’offre des produits.

J’avais deux cas d’usage :

  • Publication d’un catalogue d’œuvres d’arts avec recherche et modification (CRUD classique)
  • Mini-Service après-ventes avec saisie des incidents via un formulaire et suivi des tickets sur une interface adaptée à un mobile

Dans la catégorie « Low-Code » Je connaissais essentiellement Oracle APEX

Je me suis plongé dans les autres produits suivants :

  • Microsoft Power Apps
  • Google Appsheet
  • OutSystems
  • Salesforce Lightning
  • Zoho Creator
  • Bubble
  • Glide
  • Zapier
  • Integromat
  • Airtable

Ce qui suit traduit mon ressenti. Ce n’est absolument pas un jugement sur les produits car ce ne serait pas leur rendre justice sans avoir été formé correctement au préalable.

Pour chacun, j’ai ouvert un compte trial, et cela n’a présenté aucune difficulté. A aucun moment je n’ai été obligé de présenter ma carte de crédit.

Microsoft PowerApps

PowerApps est parfaitement intégré dans l’écosystème Microsoft, évidemment.

Hyper complet et précis. Du bon ouvrage comme Microsoft sait faire. Des connecteurs à gogo Pas très intuitif, cependant.

Google Appsheet

Nouvelle mouture de leur outil de dev. Très facile d’emploi. On obtient un résultat de très bonne qualité sur mobile avec une intégration bluffante avec Maps ou une lecture intelligent de badge. Très bonne illustration du concept de no-code. J’apprécie énormément ce produit.

OutSystems

Pure player du low-code. Solide. Approche avec un IDE en local+ déploiement. Conçu à l’origine à Lisbonne. Du travail solide de « maçon ».

Salesforce Lightening

On rentre dans un monde préconstruit avec des objets métier prêts à l’emploi. Services de type CRM, vente, Field Service etc. et possibilité de créer ses propres applis en utilisant le même framework. C’est très impressionnant. Grand Clickodrome ! Modèle d’habilitation remarquable. L’écosystème est très stimulant car il est fait de telle manière qu’on peut gagner des points en augmentant son apprentissage.

Zoho Creator

Pas mal. J’ai survolé le produit.

Bubble

Typique du low code. Je n’ai fait que survoler le produit

Glide

Petit coup de cœur par rapport à la simplicité d’emploi et au résultat obtenu.

C’est du no-code pur. C’est le produit qui m’a fourni un catalogue d’œuvres d’art prêt à l’emploi sans que je n’ai à rien ajouter de plus. Glide a compris que certaines url contenaient des liens vers des images et il les a utilisées ainsi

Zapier

Service d’intégration. Le leader du domaine. Hyper simple à utiliser

Integromat

Service d’intégration. Sur le même domaine que Zapier. Très simple d’utilisation.

Airtable

Inclassable car il s’agit d’une sorte de mid-end qui ne s’occupe que de gérer les données dans des tableaux analogue à des sheets. Possibilité d’établir des associations entre les tableaux. On peut y ajouter des triggers qui déclencheront des actions. Google prépare un produit similaire qui s’appellera Google Table.

Le couple Airtable/Zapier est, par exemple, un bon moyen pour bâtir un backend gérant les données et les processus.

Oracle APEX

Je termine par celui que je connais le mieux. Je suis toujours épaté par le bon compromis proposé par ce produit. Le curseur est au bon endroit : Du no-code pour ceux qui veulent générer une application à partir d’un tableau Excel, par exemple, mais aussi la possibilité de construire une application plus sophistiquée, sans aucune limite.

Objet

Il est possible de manipuler des feuilles de calcul Google avec des APIs REST mais cela requiert un peu de codage pour la parsing du payload json.
— Ce POST n’est pas encore finalisé —

Normalement il est conseillé d’utiliser une API cliente selon le langage hôte (ph, python, nodejs…). Dans notre cas , PL/SQL, nous allons utiliser les appels REST natifs car il n’existe pas encore de client PL/SQL..

Pour lire une feuille Google Sheets, consulter la documentation Basic Reading: https://developers.google.com/sheets/api/samples/reading

Dans Oracle APEX, on pourrait utiliser une définition de REST Data Source mais le problème est que le parser ne reconnait pas les tableaux imbriqués dont voici un échantillon:
Exemple de payload renvoyé par l’API

{
"range": "'F2'!A2:D5",
"majorDimension": "ROWS",
"values": [
[
"test",
"4"
],
[
"test",
"3"
],
[
"test",
"2"
],
[
"zert",
"8"
]
]
}

1 error has occurred
Error during REST Data Source storage or discovery: ORA-40597: JSON path expression syntax error ('$.$.values[*]') JZN-00217: Key step contains unexpected characters at position 3
Found no data while parsing the service response.

Il faut donc se rabattre sur une approche manuelle. Celle qui est expliquée dans ce post consiste à effectuer un appel à la méthode GET dans un fonction PLSQL puis à retourner le contenu dans un pipe. Cela permet, au final, de manipuler la feuille à partir d’une requête SQL classique ou bien d’une vue.

l_clob := apex_web_service.make_rest_request(
p_url => 'https://sheets.googleapis.com/v4/spreadsheets/' || tsheet || '/values/' || trange,
p_http_method => 'GET',
p_token_url => 'https://oauth2.googleapis.com/token',
p_credential_static_id => 'GoogleSAV'
);

Pour le range, il faut remplacer les espaces éventuels dans le nom de la feuille par un signe +

ex: trange varchar2(200) := ‘Réponses+au+formulaire+4!A1:D5’;

Création optionnelle d’une vue

CREATE OR REPLACE FORCE EDITIONABLE VIEW "GOOGLE_SHEET1_V" ("C1", "C2", "C3", "C4", "C5", "C7", "C8", "C9", "C10") AS
select "C1","C2","C3","C4","C5","C7","C8","C9","C10" 
from google_pkg.get_rows('Réponses+au+formulaire+4')

Contrôle d’accès.

Comme pour la plupart des accès à des données privées de Google, il faut utiliser le protocole OAUTH2.

Celui-ci est bien expliqué dans le document de Google.

Même si on ne peut pas utiliser les sourec REST, on peut néanmoins s’appuyer sur les credentials pour alléger la partie authentification. Sans cela, il faut récupérer un code d’accès et le convertir en token.

Pour Gogle Drive, l’intégration est plus simple car les REST data source sont opérationnels.
… mais, comme il ‘agit d’une donnée privée, il faut une authentification lors de la phase de design ‘redirection vers la page Google) qui n’est pas supportée par l’assistant. Donc, il faut auparavant générer manuellement un token valide qu’on fournira en paramètre de type Header Authorization Bearer <TOKEN>. Le code pour générer ce token et decrit en annexe.

Une fois la découverte du data profile réalisée, on retire le paramètre Authorization qui devient superflu et on spécifie une autorisation basée sur un des credentials enregistrés (GoogleSAV dans notre exemple). L’emploi du paramètre p_credential_static_id dans l’appel de apex_web_service.make_rest_request est très pratique car il soulage la tâche du développeur de toute la gestion du cycle de vie du token

ANNEXES

Obtention d’un token pour tester une REST data source

Le principe consiste à :

Constituer une URL contenant les parametres :

  • response_code
  • access_type
  • redirect_url (https://xxxxxxxxxx.yyyyy.oraclecloudapps.com/ords/demo/mygoogle/token) . Cette url correspond à un module ORDS custom contenant un handler GET sur le template nommée token. Pour info, si on veut fourni un id de session qui sera retournée par Google, on ajoute le paramètre state qui contiendra ce qu’on veut bien y mettre.
  • client_id
  • Demande d’un code d’accès (dans une branch before Header d’une page afin de provoquer une redirection

Affichage d’un page d’authentification Google

Affichage optionnelle d’une page de consentement (envoyée par Google)

Redirection vers l’URL envoyée en paramètre

https://accounts.google.com/o/oauth2/auth?
scope=https://www.googleapis.com/auth/drive
&response_type=code
&access_type=offline
&redirect_uri=
&P0_REDIRECT.
&client_id=xxxxxxxxxxxxxx.apps.googleusercontent.com

Comme la string ne peut pas depasser 255 caractères, on préenregistre l’url de redirection dans une variable globale P0_REDIRECT que l’on mentionne avec la syntaxe &P0_REDIRECT.

Conversion du code d’accès en token (cf code source du package GOOGLE_PKG en annexe)

Affichage du token pour utilisation ultérieure. La durée de vie de vie est d’une heure environ. Ce token devra être fourni dans la variable de header nommée AUTHORIZATION et devra être précédé par le mot clef Bearer suivi d’un espace.

declare
l_token varchar2(500);
l_code varchar2(500);
begin
l_code := utl_url.unescape(GOOGLE_PKG.at_get_env_parameter('code')
);
l_token := GOOGLE_PKG.get_token(l_code);
htp.p('token=' || l_token);
htp.p('scope=');
htp.p(utl_url.unescape(GOOGLE_PKG.at_get_env_parameter('scope'))
);
end;

Goal: Call a modal page from Javascript code (Dynamic Action or other context) and pass javascript values as parameters.

If the parameter value is stored in a JS variable, no need to call an Ajax process.

Just write this kind of statement:
(assuming the modal page is 50)

var pid = '123456';
var purl = "f?p=&APP_ID.:50:&APP_SESSION.:::50:P50_ID:P_ID";   
purl = purl.replace('P_ID', pid);    
apex.navigation.redirect (purl);

It’s important to do the replacement of the parameter P_ID after declaring the purl variable, because APEX will parse the purl variable before the JS code be evaluated. (otherwise, the pid parameter value is put a the very end of the generated JS code (cf below)

Dont’ enclose the P50-ID with # (ie: #P50_ID#) because that doesn’t work.

The JS code generated (before variable substitution) looks like that:

javascript:apex.navigation.dialog('/ords/r/demo/xxxxx/change-owner?p50_id=P_ID&clear=50&session=109433551444631&dialogCs=xxxxxxxxxxxxxxxxxxxxxxxxxx',{title:'Change Owner',height:'auto',width:'720',maxWidth:'960',modal:true,dialog:null},'t-Dialog-page--standard '+'',this);

Lors de la rédaction d’un article Facebook, l’ajout d’un lien vers une application Oracle APEX peut entrainer l’affichage d’un raccourci défectueux. Un examen avec le débuggeur de Facebook indique alors qu’il y a trop de redirections et que les metadata Open Graph n’ont pas pu être récupérées et ont donc été fixées par défaut.

Une solution de contournement consiste à créer un proxy dont le rôle est, soit de fournir les metadata attendues par Facebook, soit de rediriger vers l’application APEX.

On peut réaliser ce proxy sous forme de module REST sous ORDS tel que ci-dessous:

select 'text/html', '
<html><head>
<meta property="og:locale" content="fr_fr" />
<meta property="og:site_name" content="MySitename" />
<meta property="og:title" content="mytitle" />
<meta property="og:description" content="myDescription" />
<meta property="og:url" content="https://xx.oraclecloudapps.com/ords/r/APP_APEX/" />
<meta property="og:image" content="https://xxx/icon-256x256.png" />
<meta property="og:type" content="website" />' ||
decode(substr(:agent,1,19),
'facebookexternalhit',
'',
'<meta http-equiv="refresh" content="0; URL=https://xx.oraclecloudapps.com/ords/r/APP_APEX/" />'
)
||
'</head>
<body>
</body>
</html>'
from dual

L’astuce consiste à analyser le user-agent envoyé par Facebook qui est:

facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)

Si ce n’est pas Facebook, on effectue une redirection vers l’application APEX.

Lors de l’ajout du lien dans l’article FB, on précisera le endpoint de la méthode GET qu’on vient décrire à la place de l’url de l’application APEX.

 

Cette variante concerne les régions où le couvre-feu est en application.

https://gotocity.eu/deplacement-covid-19/index.html

C’est une variante du site officiel qui présente l’avantage de mémoriser les infos de profil et de déclencher automatiquement l’affichage de l’attestation sur l’appui d’un seul bouton (en supplément du téléchargement standard)
L’heure est renseignée par défaut. L’attestation est téléchargée comme dans l’application officielle. Bien vérifier le pdf, on ne sait jamais !

Ci-dessous des questions/Réponses faisant suite au web Séminaire du mardi 30 juin 2020 organisé par Oracle.


Bonjour, Je suis intéressé par la précision que Patrick voulais faire sur l’affichage des liste sur mobile.
Le composant « Interactive Report » est très riche et il est bien adapté pour un écran de type Desktop. Cependant il est plus commun de proposer, sur un mobile, une liste simplifiée évitant le recours à du scrolling latéral. Il vaut ainsi mieux utiliser un autre type de liste qui s’appelle « List view » qui n’affiche la valeur que de quelques colonnes.

Au niveau implémentation, on peut :

  1. Soit installer les deux composants sur la même page et le rendu de l’un ou de l’autre sera sous le contrôle d’une simple classe de style.
    cf https://apex.oracle.com/pls/apex/apex_pm/r/ut/responsive-utilities
    classes : hidden-xxs-down et hidden-xs-up.
    C’est la « magie » du framework Bootstrap qui permet cet affichage conditionnel.
  1. Soit créer deux pages différentes avec dans chacune d’elles le composant adapté, installer un code javascript de détection de type de périphérique et router la demande de liste vers l’une ou l’autre des deux pages.

De façon plus générale, voici quelques liens utiles pour le développement destiné à des mobiles:
cf les patterns APEX pour les mobiles
Cf deux demos de Shakeeb Rahman, Product Manager APEX, autour d’APEX et des mobiles

Bonjour, quel fonctionnement en mode déconnecté ?
Ce mode n’est pas prévu en standard dans le produit APEX, mais cela est possible.
Il faut avoir recours à l’emploi du framework PWA qui permet de mettre en place un fonctionnement en mode déconnecté … au prix, il est vrai d’un peu (!) de programmation en Javascript.

Cf le très bon post de Vincent Morneau (Insum) sur le sujet: http://vmorneau.me/apex-pwa/

Comment dois-je faire pour développer des applications présentes dans une base de données autres que Oracle?
La société www.troiso.fr a évalué et documenté l’emploi d’un passerelle ODBC (Heterogeneous Services inclus dans le SGBD Oracle) pour se connecter à des données présentes dans une base PostgreSQL, ainsi que d’autres.
Sinon, il faut songer à exposer les données via des Web Services (REST ou SOAP) et les consommer dans APEX.

Est il possible de travailler avec des workflows d’approbation (du style BPM) ?
Oui, on peut déclencher des Workflows en effectuant un appel via un WebService (REST ou SOAP).
Si c’est Oracle

On peut également, depuis un Workflow externe, rentrer dans une application APEX dans une page spécifique avec le pre-positionnement d’un contexte. (deep linking).

Et il est bien sur possible d’appeler un service REST manipulant des données gérées avec une application APEX depuis un outil BPMN. Voir cet exemple avec Oracle PCS. Dans ce cas, il faudra developper un module REST soit dans l’interface d’Oracle APEX, soit via Sql Developer.

Par ailleurs, même s’il n’existe pas de capacité de workflow dans APEX, il existe des expérimentations intéressantes de couplage avec un framework open source de type BPMN. cf https://apex.mt-ag.com/apex/f?p=SHOWCASE:11:0&p_lang=en (basé sur bpmn-js qui est un sous-produit open source de Camunda)

Est-ce qu’on peut créer une application qui utiliseraient des données de différentes bases de données (Plusieurs moteur, un moteur oracle, aller chercher des données dans une base SQL Serveur, d’autres dans une base My SQL) ?
oui.

La société www.troiso.fr a évalué l’emploi d’un passerelle ODBC (Heterogeneous Services inclus dans le SGBD Oracle) pour se connecter à des données présentes dans une base PostgreSQL.
Sinon, il faut songer à exposer les données via des Web Services (REST ou SOAP) et les consommer dans APEX.
Tant qu’on est en lecture, tout va bien. Si on doit coordonner une transaction sur plusieurs systèmes, le problème se corse car il faut que les systèmes candidats supportent le « two-phase commit. »

Est-ce qu’on remplacer l’url par notre nom de domaine ?
Oui. S’il s’agit d’une instance Autonomous Database (appelée aussi ATP), il faut installer un custom ORDS (uniquement à partir de la version 19.4) sur une VM de type compute afin de se substituer au module ORDS utilisé par défaut. (ce dernier n’est absolument pas modifiable. C’est une sorte de boite noire)
En général, on installe un simple tomcat avec un Apache ou un Nginx en Reverse proxy, puis on installe un certificat afin de travailler en SSL. Un Load Balancer est également disponible sur la plateforme Free Tier.
Enfin, on redirige son nom de domaine (Record de type A) vers la VM.
https://docs.oracle.com/en/database/oracle/oracle-rest-data-services/19.4/aelig/installing-and-configuring-customer-managed-ords-autonomous-database.html#GUID-24F4D51F-0BAF-4D3B-A714-492ED02D1212

On dispose de deux VM de type Compute (micro-shape) dans l’environnement Free Tier. Donc tout va bien pour tester le concept !.

cf l’excellent blog de Dimitri Giellis

Même une base My SQL ou SQL Server, en gros autre que Oracle ?
oui pour la consommation des données.
Rappel: Oracle APEX DOIT être installé dans une base Oracle !

La société www.troiso.fr a évalué l’emploi d’un passerelle ODBC (Heterogeneous Services inclus dans le SGBD Oracle) pour se connecter à des données présentes dans une base PostgreSQL.
Sinon, il faut songer à exposer les données via des Web Services (REST ou SOAP) et les consommer dans APEX.
Tant qu’on est en lecture, tout va bien. Si on doit coordonner une transaction sur plusieurs systèmes, le problème se corse car il faut que les systèmes participants supportent le « two-phase commit. »

Patrick, c’est quoi le nom du plugin ? PWA, et le plugin carte ?
Le nom du plugin est: JK64 Report Map

Il est disponible depuis le site apex.world:

https://apex.world/ords/f?p=100:710:8140164595770::::P710_PLG_ID:COM.JK64.REPORT_GOOGLE_MAP_R1

Cf le très bon post de Vincent Morneau (Insum) sur le sujet: http://vmorneau.me/apex-pwa/

Peut on partir d’une modélisation pour faire notre appli ? Ou modéliser dans APEX ?
Dans APEX, on travaille au niveau du modèle relationnel. Pour modéliser à un niveau conceptuel, il faut utiliser des outils tiers. On pense, par exemple, à l’outil Oracle Data Modeler qui est basé sur une approche Entité/Association avec un formalisme de type Barker. (https://en.wikipedia.org/wiki/Barker%27s_notation)
Sinon, ou peut utiliser tout autre type de modélisation (objet par exemple) sachant qu’au final, il faut que cela se concrétise par un modèle relationnel sous forme d’un script SQL/DDL.

Peut-on intégrer de l’APEX dans du code PHP ou dans un CMS (ex: WordPress ou Drupal) ?
Oui en utilisant les deux approches suivantes:

Soit on consomme (depuis WordPress, Drupal …) des données gérées par une application APEX via des appels de services REST

Soit on embarque une page complète APEX (avec sa UI) dans le CMS en utilisant une iframe. Dans ce cas, il ne faut pas oublier d’autoriser le « deep linking » dans les propriétés de l’application Apex.

Possibilité de générer une application Native iOS ou Android ?
Non. Oracle APEX ne génère que des application en mode connecté ou semi-connecté (cf approche PWA), mais pas d’applications mobiles natives.

pour la création de compte free on ne trouve pas la region pour la France, il propose suisse, germany, uk ? quel region utiliser ?
Il faut utiliser la région de Francfort.

support apex free sur www.troiso.fr
Info donnée par Fred Brunet

Utilisable avec une base Mysql ?
Oracle APEX DOIT être installé dans une base Oracle, mais peut consommer des données depuis d’autres systèmes de base de données.

Voici un catalogue des produits developpés avec APEX https://www.builtwithapex.com/
Info donnée par Souleman Dembele

Y a t-il aussi un gestionnaire de code source pour intégré ainsi qu’un outil de build ?
Non. Il s’agit des deux points importants sur lesquels travaillent les équipes de développement d’Oracle APEX.

Pour le moment, il faut exporter régulièrement son application et l’enregistrer dans un CVS (Subversion,, Github…) Le format d’export est granulaire jusqu’au niveau Page.
La société Insum propose un outil qui va plus loin pour la granularité des objets: APEXCl
https://apexcl.dev/
Pour le build, il existe des guides de bonnes pratiques et aussi un plugin pour Maven, par exemple.(réalisé en 2014)

Y’a t-il une gestion des profiles d’utilisateurs sous APEX ?
Oui. On peut gérer des profils d’utilisateurs avec des préférences et chaque utilisateur a la possibilité de modifier celles qu’on aura exposées lors de la conception.
Les règles de complexité des mots de passe sont paramétrable.

En parallèle, il est possible aussi de créer des groupes d’utilisateur et mettre en place une gestion d’ACLs.
La méthode la plus sophistiquée pour élaborer une gestion de rôles complète consiste à utiliser l’option Oracle RAS (Real Application Security). Oracle APEX est nativement intégrée avec Oracle RAS.

cf http://gpmfactory.com/index.php/2019/12/14/oracle-apex-et-ras/

J’ai fait un rapide test sur apex.oracle.com pour vérifier la nouvelle fonctionnalité de production de rapport PDF (Report Printing) à partir d’un Interactive Grid.

Voici deux échantillons de rapport à partir d’un Interactive Grid. L’un est en orientation paysage, l’autre en portrait.

On remarque que les règles d’affichage ainsi que les ruptures sur valeur de colonne sont respectées. Il n’existe pas de possibilité d’influencer le modèle PDF. Il s’agit donc d’une fonctionnalité pratique mais qui ne peut pas se substituer à un outil d’édition sophistiqué comme BI Publisher, AOP ou FOP.

Il faut constater qu’un Interactive Report ne bénéficie pas (ou pas encore ?) de cette fonctionnalité