Übersetzung des Tutorials von David Nash
Wie ich im vorigen Artikel schon erwähnt hatte, hat David Nash in seinem Blog ein tolles Tutorial über Autocomplete (Auto-Vervollständigen) mit Hilfe von AJAX in WordPress geschrieben. Ich habe von David die Erlaubnis, es zu übersetzen und auf dieser Seite zur Verfügung zu stellen. Das mache ich doch mit dem grössten Vergnügen – viel Spaß beim Nachbauen, und viel Erfolg!
Einleitung
Dies wurde für ein Projekt mit einer umfangreichen Datenbank realisiert, mit ca. 14.000 eingetragenen Geschäftsadressen. Es gibt eine Anmeldungsseite, auf der die Benutzer auswählen können, für welche Firma sie arbeiten. 14.000 sind viel zu viele Optionen für ein SELECT (drop-down) Feld, und ich wollte auch nicht so viel Last auf der MySQL Datenbank erzeugen.
Meine Lösung: ein Autocomplete-Textfeld, das die WordPress-Datenbank ausliest.
Ich gehe schrittweise vor, und stelle sicher dass jeder Schritt korrekt läuft, ehe ich den nächsten beginne. Hier ist das schrittweise Vorgehen:
Front-End JavaScript
Wir benutzen ein Child-Theme, weil wir ein Premium-Theme anpassen. In die functions.php kommt folgender Code, um die JavaScript-Datei zu laden:
Wenn man jetzt irgendeine Seite auf der Site neu lädt, kommt „jQuery loaded“ in einer JavaScript-Alertbox, das funktioniert also. Man hätte auch console.log(‘hello’) benutzen und die Developer Console in Chrome überpüfen können.
Als nächstes habe ich mir jQuery-autocomplete heruntergeladen. Ich hätte auch das jQuery-UI autocomplete benutzen können, aber ich benutze es sonst nicht und belasse die Sache lieber leichtgewichtig.
Aus dem Download kopiere ich mir die Dateien jquery.auto-complete.css und jquery-autocomplete.js nach /js/ – das selbe Unterverzeichnis, in dem mysite.js liegt.
Dann wird die functions.php angepasst um die Bibliothek zu laden:
function mysite_js() { wp_enqueue_script('autocomplete', get_stylesheet_directory_uri().'/js/jquery.auto-complete.js', array('jquery')); wp_enqueue_script('mysite-js', get_stylesheet_directory_uri().'/js/mysite.js', array('jquery', 'autocomplete')); wp_enqueue_style('autocomplete.css', get_stylesheet_directory_uri().'/js/jquery.auto-complete.css'); } add_action('wp_enqueue_scripts', 'mysite_js');
Jetzt die Seite neu laden, und sicherstellen dass die Library in der Chrome Developer Console unter dem „Sources“-Tab auftaucht.
Der AJAX Code
Als nächstes wird die mysite.js upgedatet, um etwas sinnvolles zu tun:
jQuery(document).ready(function($) { $('#company_works_at').autoComplete({ source: function(name, response) { $.ajax({ type: 'POST', dataType: 'json', url: '/wp-admin/admin-ajax.php', data: 'action=get_listing_names&name='+name, success: function(data) { response(data); } }); } }); });
Dabei ist #company_works_at das Textfeld auf der Registrierungsseite, das den Autocomplete bekommen soll. Ich bin dabei der Dokumentation auf der Autocomplete-Seite gefolgt – die Source-Funktion braucht ein „response“-Callback um zu funktionieren, dies ist die „success“-Funktion im Aufruf von jQuery $.ajax().
Das PHP, das die AJAX Daten von WordPress schickt
In der functions.php kommt Folgendes hinzu:
//get listings for 'works at' on submit listing page add_action('wp_ajax_nopriv_get_listing_names', 'ajax_listings'); add_action('wp_ajax_get_listing_names', 'ajax_listings'); function ajax_listings() { global $wpdb; //get access to the WordPress database object variable //get names of all businesses $name = $wpdb->esc_like(stripslashes($_POST['name'])).'%'; //escape for use in LIKE statement $sql = "select post_title from $wpdb->posts where post_title like %s and post_type='job_listing' and post_status='publish'"; $sql = $wpdb->prepare($sql, $name); $results = $wpdb->get_results($sql); //copy the business titles to a simple array $titles = array(); foreach( $results as $r ) $titles[] = addslashes($r->post_title); echo json_encode($titles); //encode into JSON format and output die(); //stop "0" from being output }
Das JavaScript, das den AJAX Call absetzt schickt die Daten in „name“. Ich benutze stripslashes() damit Namen mit Apostrophen etc. auch funtionieren. Ich benutze esc_like() aus Sicherheitsgründen. Das ‚%‘ am Ende bewirkt, dass nur auf die führenden Buchstaben gematcht wird. Wenn zum Beipsiel ein Benutzer „The“ eingibt möchte ich „The Best Business“ sehen, und nicht „Not the best business“. Aber wenn „Not“ einegegeben wird, möchte ich „Not the best business“ sehen.
Update: Wenn man alle Posts sehen will, das „and post_type=‚job_listing'“ aus dem $sql oben entfernen.
Testen, ob es funktioniert
Ich klicke auf das Autocomplete-Feld, tippe drei Buchstaben und bekomme eine ziemlich rasche Reaktion. Es schlägt mehrere Firmen vor, aus denen der Benutzer auswählen kann.
Dies ist nur ein Textfeld, und es erlaubt es dem Benutzer auch einen Namen einer Firma einzugeben, die nicht in der Datenbank ist. Wenn man möchte könnte man mehr Restriktionen anlegen, und statt dem Text auch die ID der Firma speichern. Man könnte dann auch in einem anderen Template einen Link auf die Firma einfügen.
Das war’s – so sollte es es klappen
Soweit das Tutorial von David Nash. Hier noch einmal der Link zu seinem Blog. Es lohnt sich, dort auch einmal durch die Kommentare durchzuschauen, da sind noch viele wertvolle Tipps drin.