Follow Us on Twitter

Apex 4, Dynamic Actions hands-on

Gepubliceerd in

September 2012 - Oracle Application Express staat al jaren bekend als een Rapid Application Development tool. Het is zeer geschikt om in korte tijd volledige webapplicaties te bouwen gebaseerd op een onderliggende Oracle-architectuur.

Alhoewel je out of the box snel complete functionaliteit kan maken, inclusief master- detailschermen, door gebruikers aanpasbare interactieve rapporten en tree datastructuren, moest er tot versie 4 al snel flink wat (Javascript)code geschreven worden om een wat meer dynamische pagina te creëren. Dat is tijdrovend en heeft een steile leercurve, zeker voor ontwikkelaars met een PL/SQL achtergrond.

Met Apex 4 is Oracle deze groep ontwikkelaars (en de rest ook) flink tegemoet gekomen door de introductie van de zogenaamde Dynamic Actions. Voor hen die ooit met Oracle Forms hebben gewerkt: ze doen in eerste instantie denken aan de triggers die afgingen op bepaalde gebeurtenissen, zoals een interface event (when-button-pressed, when-window-activated) of een navigatie event (pre- text-item, post-block).

Er is echter een aantal belangrijke verschillen tussen de Forms triggers en de Apex Dynamic Actions. In Forms kon alleen PL/SQL code in een trigger gebruikt worden. Dynamic Actions zijn veelzijdiger: naast PL/SQL kan bijvoorbeeld ook Javascript uitgevoerd worden. Daarnaast is het ook mogelijk om andere items op de HTML-pagina te bewerken, zoals de HTML-style of CSS-class van een item op de webpagina aanpassen, een item tonen of verbergen, leegmaken, verversen of gegevens een pagina opslaan. En waar Javascript gebruikt wordt, kan natuurlijk ook het krachtige jQuery ingezet worden.

De gebeurtenissen die een Dynamic Action afvuren zijn ook heel anders dan in het klassieke Forms: ze lijken bijna allemaal op events die in HTML en Javascript heel gebruikelijk zijn: Key Down, Mouse Enter, Page Load en After Refresh klinken voor webontwikkelaars vast heel bekend. Dat is natuurlijk geen toeval. Deze events corresponderen één op één met Javascript en HTML-events in de browser en in Application Express. Dat is ook te zien aan de wijze waarop ze gecategoriseerd zijn: Browser Events, Framework Events en Component Events.

Alhoewel Dynamic Actions heel krachtig zijn, kan het in het begin lastig zijn om er op de juiste manier gebruik van te maken. Ook kennen zij nog beperkingen. In dit Whitebook heb ik een aantal voorbeelden van toepassingen van Dynamic Actions uitgewerkt.

Hands-on: gebruik van Dynamic Actions in de praktijk

In deze hands-on wordt gebruik gemaakt van Apex 4.2. De voorbeelden zullen in 4.1 ook werken.

Tonen en verbergen van items

Dit is het meest voor de hand liggende voorbeeld van Dynamic Actions. Zolang Item 1 leeg is, wil je niet dat Item 2 getoond wordt. Dit is nuttig bij bijvoorbeeld cascading LOV’s (LOV=List of Values, ofwel een beperkte (select)lijst met waarden. In HTML heet dit een drop-down list).

Plaats 2 tekst items (P1_ITEM1 en P1_ITEM2) op een nieuwe pagina, en maak een nieuwe Dynamic Action (DA). Geef de volgende eigenschappen:

Hide/Show Dynamic Actions

Geef in de When sectie op bij welke gebeurtenis (Event) de DA moet afgaan, en op welk page element (Selection type en Item(s)). Ook geef je optioneel een voorwaarde (Condition) op. Dit deel zegt dus iets over het op welk moment en door welk item, en onder welke voorwaarde een DA afgaat.

Het gekozen Event is Change, ofwel als het element de focus verliest en dan een andere waarde heeft dan voor de focus, gaat deze af. Als dat gebeurt voor het item P1_ITEM1, en aan de conditie wordt voldaan (het item is leeg), dan zal er een actie plaatsvinden.

Deze acties staan in de True Actions en False Actions secties. True Actions vinden plaats als aan de voorwaarde in When voldaan wordt, False Actions als er niet aan voldaan wordt. Heel handig is dat er in de wizard automatisch een False action voor elke True action gemaakt wordt. Vaak wil je dat toch; als je wil dat een item getoond wordt als een ander item niet leeg is, moet het ook verborgen worden als het andere item wel leeg is.

Als het event geen conditie heeft, is het niet mogelijk om een False action te kiezen.

Show/Hide true

De eigenschappen van de True action zijn hier: Hide het item als de uitkomst van het event waar is (Fire when Event Result is True). Dat is logisch, het is tenslotte de True Action. Ook kun je aangeven of de actie ook uitgevoerd moet worden bij het laden van de pagina. In dit geval willen we dat. Tenslotte geven we dan aan welke page element we dan willen verbergen: het Type is Item en de naam is P1_ITEM2.

Run de pagina en probeer het uit: Het 2e invoerveld zal verschijnen als je het 1e veld verlaat en het bevat tekst. Maak het 1e veld leeg en het 2e veld zal verdwijnen. Het kan nog sneller! Verander het event type van “Change” naar “Key Release” en het 2e invoerveld verdwijnt of verschijnt al zodra je een toets loslaat. Maar op knippen en plakken met de muis gaat geen event af, dus die zal ook afgevangen moeten worden. Dit kan helaas niet in één DA, de oplossing is om de DA te kopiëren en een ander triggering event te geven. Helaas maakt het de code wel minder onderhoudbaar.

Het gedrag van vensters controleren

Een popup-venster kan een nuttig interface-element in een webapplicatie zijn, bijvoorbeeld om detailinformatie te tonen. Om een webpagina zich als een pop-up webpagina te laten gedragen, moet het 3 eigenschappen hebben:

 

  • De pagina opent in een nieuw scherm, en is bij voorkeur niet groter dan nodig
  • De pagina sluit zichzelf na opslaan of annuleren
  • De aanroepende pagina toont de gewijzigde gegevens

Met een DA kun je eenvoudig deze aanpassingen doen.

Het openen van een pagina in een nieuw scherm kan door middel van deze javascript functie als URL:

javascript:popupURL('f?p=&APP_ID.:1:&SESSION.::::P1_ID:#ID#',300,300) 

Tip: om de pagina er als een popup uit te laten zien, verander je de Page Template naar type Popup.

Dit werkt prima, totdat de gebruiker opslaat of annuleert. De popup brancht dan terug naar de aanroepende pagina, alleen niet in het aanroepende venster maar in het popup venster. Dat is niet het gewenste gedrag.

Standaard schiet de Submitknop het Submitproces af. Binnen één browserwindow werkt dat goed, maar met een popup is een flexibeler oplossing nodig.

Submit-schema

De Dynamic Action wordt een man in the middle, door het submitverzoek door te geven aan het submitproces en vervolgens zelf acties uit te voeren.

Submit-schema met Dynamic Action

Dit werkt als volgt: Stel de Action when button clicked property van de Button in als Defined by Dynamic Action.

Maak een Dynamic Action met als trigger event Click van type Button. De eerste actie is Submit Page (met Request/Button Name de naam van de button). De tweede actie is van het type Execute Javascript Code met de volgende code:

javascript:window.opener.location.reload(); window.close();

Die zorgt ervoor dat eerst de aanroepende pagina wordt herladen, daarna wordt het popupvenster gesloten.

Eventueel kun je de grootte en plaatsing van de popup ook nog sturen met een andere Dynamic Action, die op het Page Load event van het popupvenster afvuurt:

Windowgrootte aanpassen

De True Action is van het type Execute Javascript Code en heeft als inhoud:

window.resizeTo(750,350);
window.moveTo(200,400);

Dynamisch aanpassen van pagina-elementen

Door middel van een DA kun je verder gaan met het manipuleren van pagina-elementen dan alleen tonen en verbergen. Ook de HTML-style en classes zijn toe te passen en te verwijderen. Het volgende voorbeeld maakt de rand van een dropdown list rood, om de gebruiker te waarschuwen dat de gemaakte keuze niet aan bepaalde criteria voldoet (bijvoorbeeld de kredietstatus is onvoldoende).

Stijlvoorbeeld

Direct een Change Event maken met een Set Style actie op de select-list om de kleur te wijzigen werkt niet, er moet een stap tussen. Ook dit is een typisch voorbeeld van een beperking in DA’s die veel hoofdbrekens kan kosten.

Maak een hidden item P2_HELPER op de pagina. Maak een DA met de volgende instellingen:

Helper Dynamic Action

Helper DA action

Bij wijzigen van de drop-down list, wordt de waarde in P2_HELPER gezet. In dit voorbeeld wordt de waarde direct overgenomen, maar het wordt veel krachtiger als in de query bijvoorbeeld een functie wordt aangeroepen die een ‘Y’ of ‘N’ teruggeeft.

De volgende stap is om op P2_HELPER ook een DA te maken, die ook afgaat op een change event.

Validate DA

Validate DA - true

Validate DA - false

De False action heeft dezelfde instellingen, alleen Value is daar “red”. Met deze instellingen werkt het voorbeeld zoals beschreven. Zonder het helper-item ertussen gaat de trigger niet af.

Gebruik van jQuery in Dynamic Actions.

Gebruikmakend van de ingebouwde jQuery libraries is het heel eenvoudig om pagina-elementen te verbergen of de inhoud van items aan te passen.

Bovenaan de pagina zit de navigation bar van Apex. Een aantal elementen daarin zitten in de template en zijn niet eenvoudig te verwijderen. De gebruikersnaam zit als een div in de pagina met class app-user:

Gebruikersnaam verbergen

Maak een DA van eventtype Page Load, bij voorkeur op pagina 0 zodat hij op elke pagina afgaat. Voeg een action toe van type javascript, met deze code:

$('.app-user').remove();

Dit is jQuery code om alle classes met de naam app-user te verwijderen. Na aanmaken van de DA wordt de gebruikersnaam niet meer getoond.

Dynamic Actions in (dynamic) reports en tabular forms

Hier zit in mijn ogen de grote beperking van Dynamic Actions (en van Apex in het algemeen). Het is bijna onmogelijk om DA’s toe te passen op dynamic report overzichten. Als je aan een tabular form of standard report dynamische content wil toevoegen, kan dit alleen door een PL/SQL region te maken en het rapport zelf door middel van PL/SQL op te bouwen. Dan kan je zelf item ID’s toekennen aan alle te tonen items en daar in de DA gebruik van maken.

Conclusie

Wat krachtig is aan de Dynamic Actions in Application Express, is dat ze naadloos integreren met de bestaande Apex-functionaliteit (zoals page submit). Daarnaast zijn alle functies en mogelijkheden heel erg gericht op de mogelijkheden van Javascript en jQuery. Bijna voor elk probleem is wel een oplossing te vinden in een Dynamic Action, eventueel gecombineerd met bestaande acties zoals page submit en validaties.

Waar Dynamic Actions nog tekort schieten, is in het gebruik binnen tabular forms en rapporten. Nu zijn in Apex de mogelijkheden altijd al beperkter geweest in deze paginatypes, maar met de steeds uitgebreidere opties wordt dit alleen maar pijnlijker.

Een wat kleiner ongemak is, dat er niet meerdere triggering events in één Dynamic Action kunnen. Zoals in het eerste voorbeeld, waar je de DA moet kopiëren en één laat triggeren door een mouseup en de andere door een keyup om het gewenste resultaat te krijgen.

Los van deze beperkingen voegen Dynamic Actions wel ontzettend veel functionaliteit toe aan Application Express, en zijn de mogelijkheden in de UI enorm toegenomen. Als dit ook nog allemaal binnen rapporten en tabular forms te gebruiken was, zouden de mogelijkheden van Application Express grenzeloos zijn.

Waardering:
 

Reacties

Nieuwe reactie inzenden

De inhoud van dit veld is privé en zal niet openbaar worden gemaakt.

Meer informatie over formaatmogelijkheden

CAPTCHA
Deze vraag is om te testen of u een persoon bent en om spam te voorkomen
Image CAPTCHA
Enter the characters shown in the image.