Friday, April 17, 2020

5 Schritte zur COVID-19 Web-App (APEX REST Services)




In diesem Blog möchten wir zeigen wie einfach es ist eine APEX App zu erstellen, die anhand von REST Services Daten aus dem Web ausliest. Passend zur aktuellen Situation (COVID-19) erstellen wir eine Beispiel Anwendung, die uns tagesaktuelle Daten anzeigt. Hierzu benötigen wir gerade mal 5 Arbeitsschritte!


  • Neue APEX-App erstellen
  • Web-Source´s hinzufügen
  • Classic Report hinzufügen
  • List-of-Value erstellen
  • Filter hinzufügen



1. Neue APEX-App

Als erstes erstellen wir eine neue Anwendung in APEX. Hierzu als Workspace-Administrator einloggen und unter Create Application eine neue App erstellen.




2. Web-Source´s hinzufügen

Als Nächstes werden wir die benötigten Web-Sources anlegen. In unserem Beispiel beziehen wir uns auf die API´s von COVID-19. Welche unter anderem zur Verfügung stehen und eine passenden Dokumentation findet Ihr unter folgenden Link: https://covid19api.com/


Wir wollen in unserer Anwendung die Fallzahlen je Land auswerten. Dafür benötigen wir 2 Web-Sources.


  1. GET COUNTRIES: https://api.covid19api.com/countries
  2. GET SUMMARY: https://api.covid19api.com/summary

Die API "SUMMARY" liefert uns die aktuellen Zahlen. "COUNTRIES" liefert uns Länderdaten.

Um die API`s in APEX einbinden zu können müssen wir nun unter "Shared Components > Web Source Modules" neue Web-Sources erstellen. Hierzu auf Create klicken und im nächsten Schritt "From Scratch" auswählen. 

Dann folgende Einträge eingeben:

  • Web Source Type: Simple HTTP
  • Name: COVID19 SUMMARY
  • URL Endpoint: https://api.covid19api.com/summary




Anschließend Next klicken und den nächsten Schritt ebenfalls mit Next bestätigen.
Da wir für diese API keine Authentication benötigen können wir den darauffolgenden Schritt direkt wieder mit Discover überspringen. Zuletzt wird noch eine Vorschau angezeigt, die wir dann mit Create Web Source final abschließen können.

Das gleiche machen wir anschließend noch mit unserer zweiten API "COUNTRIES".

Hier dann folgende Einträge eingeben:


  • Web Source Type: Simple HTTP
  • Name: COVID19 COUNTRIES
  • URL Endpoint: https://api.covid19api.com/countries

Und alles weitere wie zuvor durchklicken.

Nun ist unser zweiter Schritt erledigt und wir haben die API´s in unserer APEX App eingebunden, so dass wir im nöchsten Schritt darauf zugreifen können.


3. Classic Report erstellen

Jetzt wollen wir die Daten aus den zuvor angelegten Web-Sources in Form von einem Classic Report anzeiegn lassen. Hierzu gehen wir zur Page 1 und fügen dieser einen Classic Report hinzu.

Unter Source wählen wir die Location "Web Source" und Module "COVID19 SUMMARY".




Jetzt können wir bereits die Anwendung ausführen und sehen einen Report mit den Daten aus der COVID-19 API. Als Filtermöglichkeit wollen wir aber noch eine Auswahlliste der Länder zur Verfügung stellen. Hierzu benötigen wir zunächst eine List-of-Value.


4. List-of-Value "Countries" erstellen

Wechselt wieder zu den Shared Components und erstellt unter "List of Values" eine neue LOV mit der Option "From scratch". Diese nennen wir "Countries" und wählen den Type "Dynamic" aus. Im nächsten Schritt wählen wir dann als Data Source "Web Source" und nehmen als Module unsere zuvor angelegte Web Source "COVID19 COUNTIRES".




Als Return Value wählen wir "ISO2" und Display Value "COUNTRY" und klicken dann zum erstellen Create. Jetzt haben wir die LOV erstellt und können im letzten Schritt noch die Select-Liste zur Auswahl eines Landes hinzufügen.


5. Filter hinzufügen

Zuletzt wollen wir für den Classic Report noch einen Filter hinzufügen, worüber wir nach einem Land auswerten können. Hierzu eine "Select-List" auf der Seite 1 hinzufügen. Unter List of Values den Type "Shared Components" und die zuvor erstellte LOV "Countries" auswählen. 




Damit die Auswahl den Report filtert benötigen wir jetzt noch eine Where-Clause
Hierzu unter Local Post Processing folgende Where Clause eintragen: 

COUNTRYCODE = :P1_COUNTRY
or :P1_COUNTRY is null


Zuletzt noch unter Settings bei Page Actions on Selection "Submit Page" auswählen, damit der Report nach einer Auswahl automatisch aktualisiert wird.


Fertig ist unsere COVID-19 App in nur 5 Arbeitsschritten :-)


Hier geht es zur Demo-App: COVID-19 Demo

Labels: , ,

Monday, April 13, 2020

Benutzerfreundliche Checkbox im Interactive-Grid




In diesem Tutorial möchten wir zeigen wie man eine Checkbox mit einer benutzerfreundlichen UI in einem Interactive Grid implementieren kann. Natürlich bietet APEX Out-of-the-Box auch die Möglichkeit, jedoch ist die Handhabung nicht immer für jeden Anwender so wie er es sich vorstellt. Aber mit ein wenig zusätzlichen JavaScript Code sieht das ganze gleich freundlicher aus und lässt sich für den Anwender deutlich komfortabler bedienen.

Zunächst benötigen wir für unser Tutorial eine Demo Tabelle, die wir nachher in der APEX-Anwendung für unseren Interactive-Grid verwenden werden. Wir benutzen in diesem Beispiel eine Mitarbeiter-Stammdaten Tabelle die zusätzlich die Information enthält ob der Mitarbeiter verheiratet ist oder nicht. Dieses Feld soll nachher im Grid mit einer Checkbox angezeigt werden.

Hierzu zunächst das folgende Create Table Skript ausführen:


CREATE TABLE EMP 
(
  EMPNO NUMBER(40NOT NULL 
, ENAME VARCHAR2(10 BYTE) 
, JOB VARCHAR2(9 BYTE) 
, MGR NUMBER(40
, HIREDATE DATE 
, SAL NUMBER(72
, COMM NUMBER(72
, DEPTNO NUMBER(20
, ISMARRIED NUMBER 
CONSTRAINT PK_EMP PRIMARY KEY (EMPNO)
);


Jetzt noch ein paar Dummy Daten hinzufügen. 
Dafür das folgende Insert Skript ausführen:


SET DEFINE OFF;
Insert into EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,ISMARRIED) values ('7839','KING','PRESIDENT',null,to_date('17.11.81','DD.MM.RR'),'5000',null,'10','1');
Insert into EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,ISMARRIED) values ('7698','BLAKE','MANAGER','7839',to_date('01.05.81','DD.MM.RR'),'2850',null,'30','0');
Insert into EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,ISMARRIED) values ('7782','CLARK','MANAGER','7839',to_date('09.06.81','DD.MM.RR'),'2450',null,'10','0');
Insert into EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,ISMARRIED) values ('7566','JONES','MANAGER','7839',to_date('02.04.81','DD.MM.RR'),'2975',null,'20','0');
Insert into EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,ISMARRIED) values ('7788','SCOTT','ANALYST','7566',to_date('19.04.87','DD.MM.RR'),'3000',null,'20','0');
Insert into EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,ISMARRIED) values ('7902','FORD','ANALYST','7566',to_date('03.12.81','DD.MM.RR'),'3000',null,'20','1');
Insert into EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,ISMARRIED) values ('7369','SMITH','CLERK','7902',to_date('17.12.80','DD.MM.RR'),'800',null,'20','0');
Insert into EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,ISMARRIED) values ('7499','ALLEN','SALESMAN','7698',to_date('20.02.81','DD.MM.RR'),'1600','300','30','0');
Insert into EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,ISMARRIED) values ('7521','WARD','SALESMAN','7698',to_date('22.02.81','DD.MM.RR'),'1250','500','30','0');
Insert into EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,ISMARRIED) values ('7654','MARTIN','SALESMAN','7698',to_date('28.09.81','DD.MM.RR'),'1250','1400','30','0');
Insert into EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,ISMARRIED) values ('7844','TURNER','SALESMAN','7698',to_date('08.09.81','DD.MM.RR'),'1500','0','30','1');
Insert into EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,ISMARRIED) values ('7876','ADAMS','CLERK','7788',to_date('23.05.87','DD.MM.RR'),'1100',null,'20','1');
Insert into EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,ISMARRIED) values ('7900','JAMES','CLERK','7698',to_date('03.12.81','DD.MM.RR'),'950',null,'30','1');
Insert into EMP (EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO,ISMARRIED) values ('7934','MILLER','CLERK','7782',to_date('23.01.82','DD.MM.RR'),'1300',null,'10','1');
commit;


Anschließend eine neue APEX-Anwendung erstellen und ein Interactive Grid hinzufügen.
Das Grid muss editierbar sein. Dafür unter "Attributes" Edit auf Enabled setzen.
Dem Grid zusätzlich eine Static-Id vergeben, damit wir dieses in unserem JavaScript Code einfacherer ansprechen können (zum Beispiel "MYGRID").

Dann noch folgendes SQL Query als Source einfügen:


select EMPNO as checkbox,
       case when ismarried = 1 then 'fa-check-square-o' else 'fa-square-o' end as checkbox_value, 
       EMPNO,
       ENAME,
       JOB,
       MGR,
       HIREDATE,
       SAL,
       COMM,
       DEPTNO
  from EMP


Wichtig hierbei ist, dass das Select Statement zusätzlich zwei weitere Spalten erhält.
  1. Empno as checkbox (Primary Key Id)
  2. case when ismarried = 1 then 'fa-check-square-o' else 'fa-square-o' end as checkbox_value
    (Das case when in Zeile 2 wird benötigt um die Checkbox je nach Wert vorzuverlegen)
Der "case when" Befehl wird benötigt, damit beim initialisieren die Checkboxen je nach Status ausgewählt sind. Möchte man nur leere Checkboxen angezeigt bekommen, so muss der SQL Befehl auf " 'fa-square-o' as checkbox_value " geändert werden.

Da die Spalte "EMPNO" in unseren Table einen Primary Key hinterlegt hat müssen wir dieses bei der Column im Interactive Grid auch angegeben.

Folgende Einstellungen noch bei der Spalte „checkbox“ hinterlegen:

  • Type: „Link“
  • Target-Type: URL
  • URL: javascript:checkbox("MYGRID",&CHECKBOX.)
  • Link-Text: <span id="checkBoxID_&CHECKBOX." aria-hidden="true" class="fa &CHECKBOX_VALUE."></span>
  • Link-Attributes: id="clickCheck_&CHECKBOX."
  • Column-Filter: disabled
  • Enable Users to sort: disabled
  • JavaScript Initialization Code:

function(options) { 
    options.defaultGridColumnOptions = { 
       noHeaderActivate: true 
     } 
     return options
   }


Der JavaScript Initialization Code wird hinterlegt, damit das Menü der Spalte deaktiviert ist, da wir dieses nicht benötigen.

Als letztes und muss auf Seitenebene im Code-Editor „Function and Global Variable Declaration“ folgender JavaScript Code hinzugefügt werden:


function checkbox(pIDGridpLine) {

    if((apex.region(pIDGrid).widget().interactiveGrid("getActions").get("edit"))){

        var my_view = apex.region(pIDGrid).widget().interactiveGrid("getCurrentView");
        var my_model = my_view.model;
        var my_record = my_view.view$.grid("getActiveRecord");

        var my_class = $("#checkBoxID_"+pLine).attr("class");

        if (my_class == "fa fa-square-o" ){
           my_model.setValue(my_record"CHECKBOX_VALUE""1");
           $("#checkBoxID_"+pLine).removeClass("fa fa-square-o").addClass("fa fa-check-square-o");
        }
        else {
              my_model.setValue(my_record"CHECKBOX_VALUE""0");
              $("#checkBoxID_"+pLine).removeClass("fa fa-check-square-o").addClass("fa fa-square-o");
        }
    }
    else {
          apex.region(pIDGrid).widget().interactiveGrid("getActions").set("edit"true);
          checkbox(pIDGridpLine);
    }

}


Dieser JavaScript Code macht folgendes.
  • Die erste "if" Bedingung prüft ob das Interactive-Grid im Edit Mode ist
  • Falls ja erstellen wir eine Variable von dem View-Object und dem Model-Object.Damit wir auf der aktiven Zeile zugreifen können, benutzen wir noch die Methode "getActiveRecord" und speichern diese Zeile in eine Record Variable.
  • Als nächstes lesen wir das "class Attribute" von der Checkbox aus welche geklickt wurde und überprüfen ob die Checkbox nicht ausgewählt ist. Wenn dieses zutrifft ändern wir den Wert von der "Checkbox_Value" auf "1" und ändern noch das "class Attribut" auf "ausgewählt" indem wir erst die alte class entfernen und dann die class "fa fa-check-square-o" hinzufügen.
  • Das gleiche machen wir ebenso wenn die Bedingung nicht zutrifft, nur in andere Reihenfolge. Der Wert von der "Checkbox_Value" auf "0" setzen und die class auf "fa fa-square-o" ändern.


Fertig ist die eigentliche Funktion zum aus- und abwählen einer Checkbox im Interactive- Grid :-)


Die Spalte „checkbox_value“ kann je nach Bedarf auf „hidden“ gesetzt werden. Wichtig hierbei wäre dann jedoch das „Value Protected“ deaktiviert wird, da sonst der Wert über unsere JavaScript Function nicht überschrieben werden kann.

Zuletzt benötigen wir noch ein Update Process, der nach dem editieren im Interactive Grid ausgeführt wird. Hier unter „Processing“ den vom IG erstellten Process auf PL/SQL Code ändern und folgendes Skript einfügen:


case :APEX$ROW_STATUS
when 'U' then
    update emp
       set ismarried = :checkbox_value
     where empno = :empno;

end case;


Das war´s…ab sofort steht euch eine benutzerfreundliche Checkbox zur Verfügung 😊




Hier könnt Ihr unsere Demo starten.

Labels: ,