AJAX in Aktion: Textfeld mit "automatischem Filter"

AJAX (Asynchronous JavaScript and XML) macht mehr und mehr von sich Reden. AJAX erlaubt es, Teile von Web-Seiten zu ändern, ohne die komplette Seite neu laden zu müssen. Wie man die AJAX-Technologie mit Application Express nutzt, wurde vor einigen Monaten auf dieser Seite bereits mit einigen Beispielen vorgestellt. Heute erfahren Sie, wie Sie mit Hilfe von Application Express und AJAX ein Eingabefeld erstellen, welches reagiert, wie in Abbildung 1 dargestellt.

Das Ziel: Eingabefeld mit automatischem Filter

Abb.1: Das Ziel: Eingabefeld mit automatischem Filter

Solche Eingabefelder kennen Sie bereits von vielen Desktop-Anwendungen her. Beispielsweise reagiert die Adressleiste Ihres Web-Browser auf diese Art und Weise. Wenn Sie die URL der Internet-Seite eingeben, bietet Ihnen der Browser eine Liste mit zur Eingabe passenden Adressen (die Sie bereits besucht haben) an. Das hier vorgestellte Eingabefeld arbeitet analog. Sobald ein Zeichen eingegeben wird, werden alle dazu passenden Einträge aus der Tabelle selektiert und in einer Auswahlliste angeboten. Der Anwender kann den Namen dann entweder vollständig eingeben oder aus der Auswahlliste heraussuchen.

Dieses Eingabefeld mit automatischem Filter wird im folgenden in drei Schritten erzeugt. Beginnen Sie mit der Server-Komponente - sie bekommt die eingegebenen Zeichen übermittelt und selektiert alle passenden Einträge aus der Tabellenspalte. Dazu benötigen Sie einen Anwendungsprozeß und zum Übergeben der Parameter einige Anwendungslemente. Der Anwendungsprozeß soll generisch sein, er soll mit jeder beliebigen Spalte in jeder beliebigen Tabelle funktionieren. Erstellen Sie also zunächst eine neue Anwendung (1 leere Seite reicht) oder navigieren Sie in ihrer bereits existierenden Anwendung zu den Gemeinsamen Komponenten, dort zu den Anwendungselementen und erstellen Sie drei Anwendungelemente: TF_SL_TABLE, TF_SL_COLUMN und TF_SL_SEARCH.


Erstellen der Anwendungselemente als Parameter für den Anwendungsprozeß

Abb.2: Erstellen der Anwendungselemente als Parameter für den Anwendungsprozeß

Erzeugen Sie als nächstes den Anwendungsprozeß. Navigieren Sie in den Gemeinsamen Komponenten zu den Anwendungsprozessen und erstellen Sie einen neuen Bedarfsgesteuerten Anwendungsprozeß. Verwenden Sie dabei den Namen getSearchList.

Erstellen des Anwendungsprozesses

Abb.3: Erstellen des Anwendungsprozesses

Verwenden Sie folgenden PL/SQL Code:

declare
  TYPE CurTyp IS REF CURSOR;

  v_row varchar2(4000);
  rec   CurTyp;
begin
  :TF_SL_SEARCH := replace(:TF_SL_SEARCH, '&','&');
  :TF_SL_SEARCH := replace(:TF_SL_SEARCH, '&lt;','<');  
  :TF_SL_SEARCH := replace(:TF_SL_SEARCH, '&gt;','>');
  :TF_SL_SEARCH := replace(:TF_SL_SEARCH, '&quot;','"');

  owa_util.mime_header('text/xml', FALSE);
  htp.p('Cache-Control: no-cache');
  htp.p('Pragma: no-cache');
  owa_util.http_header_close;

  htp.prn('<rowset>');
  
  -- Add some code to prevent SQL injection attacks 
  -- on :TF_SL_TABLE and TF_SL_COLUMN here ...
  
  open rec for 
    'select distinct ' || :TF_SL_COLUMN || ' ' ||
    'from ' || :TF_SL_TABLE || ' ' ||
    'where '||:TF_SL_COLUMN||' like :1||''%'' ' ||
    'and rownum < 100  ' ||-- change this to the maximum of rows you want to return
    'order by '||:TF_SL_COLUMN
  using :TF_SL_SEARCH;
  loop
    fetch rec into v_row;
    exit when rec%NOTFOUND;
    htp.prn('<row>' || htf.escape_sc(v_row) || '</row>');
  end loop;
  htp.prn('</rowset>');
end;          

Anhand der Werte in den soeben angelegten Anwendungselementen TF_SL_TABLE und TF_SL_COLUMN wird dynamisch eine SQL-Abfrage zusammengesetzt. Im Element TF_SL_SEARCH werden die bereits eingetippten Zeichen übergeben. Mit einer SQL LIKE-Abfrage werden die passenden Einträge selektiert und als XML-Dokument zurückgegeben. 

Damit ist die Server-Komponente fertig. Nun geht es an die Einbettung in das jeweilige Application Express-Formular. Das "J" in AJAX steht für JavaScript - das Laden der jeweils passenden Einträge nach Eingabe eines Zeichens wird also mit JavaScript realisiert. Navigieren Sie nun zu den Gemeinsamen Komponenten, von dort zu den Statischen Dateien und laden Sie die JavaScript-Bibliothek textfield_autofilter.js als statische Datei hoch. Weisen Sie keine Anwendung zu - damit ist der JavaScript-Code für alle Anwendungen im Workspace verfügbar.

Hochladen der JavaScript-Datei

Abb.4: Hochladen der JavaScript-Datei

Die Einbindung des JavaScript-Code erfolgt am besten im Seitentemplate. Fügen Sie im HTML-Header des Templates folgenden HTML-Code hinzu:

<script type="text/javascript" src="#WORKSPACE_IMAGES#textfield_autofilter.js"></script>
Einbinden des JavaScript-Codes im Seitentemplate

Abb.5: Einbinden des JavaScript-Codes im Seitentemplate

Damit sind alle Vorbereitungen gemacht. Ihnen steht nun die JavaScript-Funktion register zur Verfügung. Sie ist in der hochgeladenen Bibliothek texfield_autofilter.js definiert und verbindet ein beliebiges Textfeld mit einer Tabellenspalte in der Datenbank und wird wie folgt aufgerufen:

function register(
  p_TextFieldName,     // Name des Eingabefelds (PX_FELDNAME)
  p_TableName,         // Name der Tabelle, gegen die der Filter laufen soll (bspw. EMP)
  p_ColumnName,        // Name der Tabellenspalte (ENAME)
  p_matchColor,        // Darstellungsfarbe, solange es passende Einträge gibt
  p_noMatchColor       // Darstellungsfarbe, wenn es keine passenden Einträge gibt
)             

Navigieren Sie zu den Seitenattributen und rufen Sie im Footer die Funktion register dort wie folgt auf (Angenommen, Ihr Textfeld heißt P1_REPORT_SEARCH)

Verknüpfen des Texteingabefelds mit der Tabellenspalte durch die JavaScript-Funktion register

Abb.6: Verknüpfen des Texteingabefelds mit der Tabellenspalte durch die JavaScript-Funktion register

Wenn Sie die Seite nun neu starten, sieht das Ergebnis wie folgt aus:

Das Ergebnis

Abb.7: Das Ergebnis

Zurück zur Community-Seite