Logo Oracle Deutschland   Application Express Community
Funktionstasten in APEX nutzen: Zum Beispiel "Speichern mit F10"
Erscheinungsmonat APEX-Version Datenbankversion
Juli 2011 ab 4.0 ab 10.2

Viele Anwender verwenden gerne Funktionstasten - schließlich kennt man das von Desktop-Anwendungen her: F1 ruft die Hilfe auf, F10 speichert und vieles mehr. Die Funktionstasten können auch in einer Web-Anwendung verwendet werden, allerdings erforderte das in der Vergangenheit immer recht aufwändiges JavaScript-Coding. Doch mit den neuen Dynamic Actions in APEX 4.0 lässt sich die Anforderung aber ganz einfach umsetzen - in diesem Tipp erfahren Sie, wie das geht. Zunächst wollen wir erreichen, dass die Taste F10 wie ein Klick auf den "Save"-Button wirkt, also die Seite absendet und die Daten somit speichert. Das soll bei allen Formularen gelten.

Das APEX-Formular soll mit der Taste F10 gespeichert werden können

Abbildung 1: Das APEX-Formular soll mit der Taste F10 gespeichert werden können

Die Umsetzung erfolgt, wie gesagt, mit den in APEX 4.0 neu eingeführten Dynamic Actions. Damit wir die dynamische Aktion nur einmal für alle Formulare erzeugen müssen, erledigen wir das auf der Seite 0. Navigieren Sie also zur Seite 0. Wenn diese in Ihrer Anwendung noch nicht existiert, legen Sie sie neu an.

Seite 0

Abbildung 2: Seite 0

Klicken Sie bei den Dynamischen Aktionen die rechte Maustaste und wählen Sie Erstellen aus dem Kontextmenü aus. Nehmen Sie dann eine Erweiterte dynamische Aktion und geben Sie ihr den Namen Taste F10. Beim nächsten Dialog wird es nun spannend: Die dynamische Aktion soll ausgeführt werden, wenn eine Taste nach unten gedrückt wird. Das soll auf der ganzen Anwendungsseite gültig sein, nehmen Sie daher das DOM-Objekt "document". Allerdings soll natürlich nicht jede Taste zum Speichern des Formulars führen, sondern nur F10. Das geschieht mit einer Bedingung. Nehmen Sie hier einen JavaScript-Ausdruck und tragen Sie this.browserEvent.keyCode == 121 ein (Abbildung 3).

Auslösen der dynamischen Aktion: Beim Drücken der Taste F10

Abbildung 3: Auslösen der dynamischen Aktion: Beim Drücken der Taste F10

Der JavaScript-Keycode für die Taste F10 ist 121. Die Taste F1 trägt den Code 112. Demnach hat F2 die 113 und so fort.

Wenn die Taste F10 gedrückt wurde, die Bedingung also wahr ist, soll APEX sich verhalten, als ob die Schaltfläche SAVE geklickt wäre, die Seite soll also abgesendet werden. Das geschieht mit der JavaScript-Codezeile doSubmit('SAVE').

Das alleine reicht aber noch nicht aus: Normalerweise aktiviert die Taste F10 die Menüleiste des Browsers - genau das ist nun aber nicht mehr erwünscht. Also muss zusätzlich zum Absenden der Seite noch verhindert werden, dass die Standardfunktion des Browsers ausgeführt wird. Es werden also noch zwei JavaScript-Aufrufe benötigt. Nehmen Sie als Aktion mit Status True also JavaScript-Code und tragen Sie folgenden Code ein.

this.browserEvent.stopPropagation();
this.browserEvent.preventDefault();
doSubmit('SAVE');
Die "true"-Action: Absenden der Seite

Abbildung 4: Die "true"-Action: Absenden der Seite

Eine Aktion mit Status False müssen Sie nicht vergeben. Achten Sie darauf, dass das Kästchen Beim Seitenladen auslösen nicht angeklickt ist. Auch ein Betroffenes Element wählen Sie nicht aus. Wenn Sie fertig sind, speichern Sie alles ab.

Wenn Sie nun auf eine Formularseite gehen, einen vorhandenen Datensatz zum ändern in das Formular laden und auf F10 drücken, sollte die Seite abgesendet und die Änderungen gespeichert werden. Die Taste F10 wirkt nun genauso wie ein Klick auf die Schaltfläche SAVE. Nun ist aber nicht jede Seite eine Formularseite - manche Seiten enthalten nur Berichte oder Diagramme - hier stört die dynamische Aktion wahrscheinlich mehr als sie nützt. Insofern möchten wir die dynamische Aktion nur auf den Seiten haben, die einen SAVE-Button enthalten - und das ist, wie immer in APEX, mit einer Bedingung ganz schnell erledigt. Navigieren Sie nochmals zur dynamischen Aktion auf der Seite 0 und dort zu den Bedingungen (Abbildung 5).

"F10" soll nur aktiv sein, wenn ein "SAVE" Button enthalten ist

Abbildung 5: "F10" soll nur aktiv sein, wenn ein "SAVE" Button enthalten ist

select button_name 
from apex_application_page_buttons 
where application_id = :APP_ID 
  and page_id = :APP_PAGE_ID 
  and button_name = 'SAVE'

Damit sind Sie soweit erstmal fertig. Wenn keine Schaltfläche mit dem Namen SAVE vorhanden ist, wirkt die Taste F10 wie immer: Sie aktiviert die Menüleiste des Browsers. Ist sie dagegen vorhanden, wirkt F10 wie ein Klick darauf. Allerdings gibt es bei APEX-Formularen keine Schaltfläche SAVE, wenn das Formular leer ist und damit eine neue Tabellenzeile erzeugt wird. In diesem Fall heißt die Schaltfläche CREATE. Auch in diesen Fällen soll F10 zum Speichern führen; es muss also noch etwas getan werden.

Dazu ändern wir den JavaScript-Code: Wenn ein SAVE-Button vorhanden ist, soll die Seite mit SAVE abgesendet werden. Wenn kein SAVE-Button vorhanden ist, wird nach einem CREATE-Button gesucht. Ist auch dieser nicht vorhanden, so tut die dynamische Aktion nichts. Wenn Schaltflächen in der Anwendung nicht mit dem HTML Tag Button erzeugt werden (richtet sich nach den Templates), muss der JavaScript-Code entsprechend angepasst werden. Navigieren Sie also zum JavaScript-Code der Aktion mit Status True und ändern Sie ihn wie folgt.

var l_req = "";

// Auf der Seite vorhandene Buttons durcharbeiten ...
$("button").each( function(i,l) {
  // ist ein SAVE-Button vorhanden ..?
  if (String(l.getAttribute("onclick")).indexOf("SAVE") > -1 && l_req == "") {
    l_req = "SAVE";
  } 
  // ist ein CREATE-Button vorhanden ..?
  else if (String(l.getAttribute("onclick")).indexOf("CREATE") > -1 && l_req == "") {
    l_req = 'CREATE';
  }
})

  // Wenn Button gefunden: Default-Event abschalten und Page Submit durchführen
if (l_req != "") {
  this.browserEvent.stopPropagation();
  this.browserEvent.preventDefault();
  doSubmit(l_req);
}

Auch die Bedingung muss geändert werden. Die dynamische Aktion soll dann aktiv werden, wenn die Seite entweder die Schaltfläche CREATE oder SAVE oder beide enthält.

select button_name 
from apex_application_page_buttons 
where application_id = :APP_ID 
  and page_id = :APP_PAGE_ID 
  and button_name in ('SAVE', 'CREATE')

F10 wirkt nun wie ein Klick auf die Schaltflächen CREATE oder SAVE, wobei SAVE Vorrang vor CREATE hat. Ist keine dieser Schaltflächen vorhanden, so geschieht nichts. Ein weiteres Beispiel sei vorgestellt: Die Taste F1 soll einen Hilfetext zur aktuellen Seite anzeigen - die Standardfunktionalität des Browsers (nämlich die Hilfetexte für den Browser selbst) nutzt ohnehin fast niemand.

Zunächst müssen Sie die Hilfetexte hinterlegen. Hierzu nutzen wir natürlich das APEX Repository, wie schon im letzten Community-Tipp beschrieben. Navigieren Sie also zu den Seitenattributen und tragen Sie unter Hilfetext etwas ein. HTML-Markup können Sie gefahrlos verwenden: Da nur Sie als Entwickler diese Inhalte pflegen, besteht keine Cross-Site-Scripting-Gefahr (Abbildung 6).

Hilfetext im APEX-Dictionary hinterlegen

Abbildung 6: Hilfetext im APEX-Dictionary hinterlegen

Als nächstes benötigen Sie einen Anwendungsprozess, der den Hilfetext ausliest und zurückgibt. Navigieren Sie also zu den Gemeinsamen Komponenten, dort zu den Anwendungsprozessen und dann klicken Sie die Schaltfläche Erstellen. Nennen Sie Ihren Prozess getPageHelp und legen Sie fest, dass er Bedarfsgesteuert ausgeführt werden soll (Abbildung 7).

Anwendungsprozess "getPageHelp" einrichten

Abbildung 7: Anwendungsprozess "getPageHelp" einrichten

Hinterlegen Sie dann den folgenden PL/SQL-Code:

declare
  v_helptext varchar2(32000); 
begin
  select dbms_lob.substr(help_text, 32000, 1)
    into v_helptext
  from apex_application_pages
  where application_id = :APP_ID 
  and page_id = :APP_PAGE_ID;
  owa_util.mime_header('text/html', false);
  htp.p('Content-Length: '||lengthb(v_helptext));
  owa_util.http_header_close;
  htp.p(v_helptext);
exception
  when others then
    htp.p('Beim Lesen der Seitenhilfe ist ein Fehler aufgetreten.');
end;

Speichern Sie den Prozess schließlich ab. Danach navigieren Sie wiederum zur Seite 0 und erzeugen dort eine neue Dynamische Aktion. Wiederum verwenden Sie das Ereignis Taste nach unten und als Bedingung nehmen Sie wiederum JavaScript-Ausdruck. Der keyCode ist nun allerdings 112 für die Taste F1 (Abbildung 8).

Neue dynamische Aktion für die Taste F1

Abbildung 8: Neue dynamische Aktion für die Taste F1

Als True-Aktion wählen Sie JavaScript-Code. Hinterlegen Sie folgendes:

// Standard-Event für F1 unterdrücken
this.browserEvent.stopPropagation();
this.browserEvent.preventDefault();

try {
  document.onhelp = function() {return(false);}
  window.onhelp = function() {return(false);}
} catch (e) {}

// Hilfetext aus dem APEX-Repository holen
var lGet = new htmldb_Get(null,$v('pFlowId'), 'APPLICATION_PROCESS=getPageHelp', $v('pFlowStepId'));
var lReturn = lGet.get();
lGet = null;

// Hilfetext als jQuery-Popup anzeigen ...
var lDialog = apex.jQuery('<div id="apex_popup_page_help">'+lReturn+'</div>');
lDialog.dialog({
                title: 'Hilfe',
                bgiframe: true,
                width: 500,
                height: 350,
                show: 'drop',
                hide: 'drop' });

Achten Sie darauf, dass das Kästchen Beim Seitenladen auslösen nicht aktiviert ist. Speichern Sie schließlich alles ab und probieren Sie es aus. Sie können nun auf jeder Seite Ihrer Anwendung die Taste F1 drücken, woraufhin der hinterlegte Hilfetext als Popup-Fenster dargestellt wird.

Drückt man die Taste F1, so wird die Seitenhilfe angezeigt

Abbildung 9: Drückt man die Taste F1, so wird die Seitenhilfe angezeigt

Dies waren zwei Beispiele zur Belegung von Funktionstasten in einer APEX-Anwendung. Das kann natürlich noch beliebig fortgesetzt werden - den Möglichkeiten sind eigentlich keine Grenzen gesetzt. Insbesondere wenn es um die Datenerfassung geht, kann dies sehr hilfreich sein, denn im Arbeitsablauf ist das Drücken einer Funktionstaste meist viel effizienter als der Griff zur Maus.

Zurück zur Community-Seite