Results for category "Ajax"

12 Articles

Vom Zwittern … äh Twittern und sinnlosen Anwendungen – Twitter als semantische Datenbank

Heute habe ich die Messlatte für den Geekfaktor in unserem Büro doch relativ hoch gelegt: Seit einigen Wochen besitze ich einen Twitter-Account um meine Profilneurose und meinen Netzhibitionismus -welch schöner Neologismus- zu befriedigen. Der ursprüngliche Grund war, dass mein Cousin und die Entwickler von QuakeLive twittern. Außerdem kam Marc vor einigen Tagen hinzu.

Wie dem auch sei – bis heute war ich der Meinung, Twitter ist schrott. Was interessiert mich, dass bklynplayboy gerade über das Next Top Model lacht? Die rhetorische Frage beantworte ich mal nicht…

Nach unserem heutigen Kickerspiel im Büro kam mir eine Idee: Warum nicht Twitter als Datenbank nutzen?
Eine konkrete Anwendung hatte ich dafür auch schon. Seit einiger Zeit überlegt das Kicker-Team aus der Firma, ob wir über unsere Spiele Statistik führen. Bisher habe ich mich immer davor gescheut, extra eine Datenbank dafür anzulegen und irgendetwas mit PHP oder Java zusammenzufrickeln. Das ist schließlich 0815 und auf solchen Krams habe ich keine Lust mehr.
Kommen wir zuerst zur Analyse-Phase: Ein Kickerspiel besteht aus mehreren Sätzen und hat immer zwei Teams mit je maximal zwei Spielern. Ein Spiel wird immer mit einem Sieg beendet – unentschieden gibt es nicht. Zu einem Spiel kann man noch ein kurzes Statement abgeben und außerdem muss der Tweet gehasht werden und das war es. In einem Twitter-Post kurz zusammengefasst würde das so aussehen:

CKL:CST 5:4 – Prokuristen können nicht kickern #büro #kickern

CKL und CST sind die Benutzerkürzel der Spieler, Zwei Spieler werden mit Komma getrennt (CKL,MBI:CST,FWE).
An sich ist das Datenformat völlig egal. Theoretisch könnte man für so etwas auch JSON benutzen. Aber egal.

In der nächsten Iteration – ja, mein Nachmittag hatte etwas von Agiler Entwicklung – ging es daran, die richtigen Einträge zu finden. Die API von Twitter beschreibt das recht gut und somit erledigt sich die Suchanfrage nach den Ergebnissen mit dem Aufruf von http://search.twitter.com/search.json?q=from%3Aschakko+%23kickern+%23büro wie von alleine. Zur Info: Es wird nach den Hash #kickern und #büro vom Benutzer “schakko” gesucht. Die Datensätze werden im JSON-Format zurückgegeben.

Damit hatte ich zwei meiner drei Fragen geklärt: Wie sind die Daten zu speichern, wie finde ich die Daten, die ich brauche. Nun folgte für mich der interessanteste Part: Wie verbinde ich mich mit der API von Twitter? Wie schon oben geschrieben, hatte ich auf PHP/Java-Gefrickel keine Lust. Meine Anwendung sollte schließlich nur die Matches der vergangenen Wochen anzeigen und für jeden Spieler und jede Team-Kombination die Statistik anzeigen (gewonne Matches, verlorene Matches, Erfolgsquote). Eine Proxy-Klasse (Service bildet die End-API nach und liegt auf dem selben Server) oder lokaler Routing-Service (Service tunnelt die Anfragen an die End-API) in einer serverseitigen Programmiersprache zu erstellen, wäre Overkill gewesen. Nun wusste ich aber, dass jQuery seit einiger Zeit Cross Domain AJAX beherrscht. Damit ist es über JSONP möglich, AJAX-Anfragen an Hosts zu stellen, die nicht auf dem Server liegen, von wo die JavaScript-Applikation ausgeführt wird. Mit Cross Domain Requests werden Proxy-Klassen oder Routing-Services also unnötig.

Gesagt getan, meine Zutaten für meine Kicker-Applikatin waren gefunden: Twitter durch die Hashtags als semantische Datenbank, jQuery als Framework und somit JavaScript als Programmiersprache und HTML als Ausgabeformat.

An der gesamten Anwendung – inklusive Analyse – programmierte ich knappe 3 Stunden. Mein eigenes Format wandelte ich über eine kurze Regular Expression in die passenden JavaScript-Objekte um.

Der momentane Stand ist, dass die Statistiken in tabellarischer Form mit den obigen Vorgaben pro Spieler oder pro Team dargestellt werden. Wünschenswerte Sachen sind noch:

  • Eintragen der Ergebnisse über ein Formular in der Applikation
  • Sortierung der Tabellen – sollte relativ einfach funktionieren
  • Grafische Auswertung der Statistik anhand von Charts

Diese kleine Anwendung war seit einiger Zeit das agilste und pragmatischste Vorgehen, dass ich an den Tag gelegt habe – weg von alten und zig-mal durchgekauten Pfaden und einfach mal etwas Neues ausprobieren.

Analyse der Google Mobile Maps API

Den heutigen Abend war ich damit beschäftigt, mich um das Thema GPS-Lokalisierung zu kümmern. Dabei kamen dann einige interessante Dinge zu Tage. Zum einen wusste ich gar nicht, dass o2 einen Handy-Lokalisierungsdienst für lau anbietet. Nachdem man sich in das o2-Portal eingeloggt hat, kann man dort sein Handy lokalisieren. Nach einigen Sekunden erscheint in einer -billig gemachten- Karte der ungefähre Bestimmungsort des Handys. Mein Handy wurde ca. 1.6 Kilometer zu weit nördlich angezeigt, aber das bleibt nun mal nicht aus.
Meine andere Erkenntnis war, das man mit Google Maps Mobile http://www.google.com/gmm/tour.html?hl=de sich ebenfalls den Standort des Handys anzeigen lassen kann. Die J2ME-Applikation sucht sich die Cell ID des Betreibers heraus, in dem das Handy eingeloggt ist. Google hat wohl mit den großen Handynetz-Betreibern Verträge geschlossen, so dass sie auf die Zell-Datenbanken zugreifen können.

Leider konnte ich die J2ME-Anwendung auf meinem P910i nicht installieren. Ich schaute deshalb nach, ob man eventuell die Demo benutzen kann, um die API mit anderen Tools zu benutzen.
Nachdem ich die passende JAR-Datei heruntergeladen habe, musste ich leider feststellen, dass über die Sourcen ein Obfuscator gejagt wurde – ok ich hätte das wohl auch so gemacht 😉

Ich baute mir ein kurzes Shellscript:

#!/bin/bash
find -name "*class" | sed 's/.class//g' | sed 's/.///g' >> files.txt

for clazz in `cat files.txt`;
do
    echo "FILE $clazz" >> code.txt
    javap -c $clazz >> code.txt
done

Und hatte somit von den allen Klassen den dekompilierten Byte-Code. Viel anfangen konnte ich damit leider nicht, ich stellte nämlich fest, dass die komplette Verbindung zwischen J2ME-Client und Google Maps Mobile im Binärformat abgewickelt wird.
Frontcontroller der Server-API ist http://www.google.com/glm/mmap – und das war es auch schon. Also leider nix mit REST o.ä.
Der Client stellt eine Anfrage über POST als Client “MobileRunner” im Binärformat, der Server sendet die Antwort ebenfalls als Binary zurück.

Tja, leider blöd gelaufen. Ich hätte gerne ein paar Anwendungen geschrieben, die auf die Google Mobile Maps-API setzen würden.

Arbeiten bei gefühlten 45 Grad

Sommerzeit bedeutet nicht immer Ferienzeit – für mich hieß es in den letzten Tagen: Fehler in unserer IT-Infrastruktur fixen, bis die Tastatur glimmt. Unter anderem konnte die Administrationsoberfläche des McAfee ePO 3.61 nicht mehr aufgerufen werden. Überraschenderweise stellte ich nach einiger Zeit fest, dass unsere MSSQL MSDE-Instanz, auf der das ePO liegt, alle Benutzer aus der Datenbank gedroppt hat. Ich konnte mich weder mit Domänen-Administrator, noch mit sa einloggen. Wie das Problem zustande gekommen ist, ist mir ein Rätsel – aber jetzt läuft wieder alles und ich habe gleich auf das ePO 4.0 geupgradet.
Nebenbei etabliert sich langsam aber sicher Trac als ein gutes Bugtracking-System. Unsere komplette Infrastruktur wird über das Trac-Wiki dokumentiert, alle aufgetretenen Fehler kommen inkl. Lösung in den Bugtracker. Unsere Scripte für Backup, Tools u.s.w. liegen in einem zentralen SVN-Repository, das an das Trac angebunden ist.
Sicherlich ist dieser Lösungsansatz nicht unbedingt ITIL-konform, aber er funktioniert und das ganz gut.
Vor zwei Tagen ist in mir auch langsam die Idee des Deployens unserer Anwendungen gereift. Da alle bestehenden Deployment-Tools nicht direkt unseren Anforderungen entsprechen, habe ich beschlossen, etwas eigenes zu bauen.
Unser Deployment-Client läuft als Java-Tool auf den jeweiligen Deploy-Server. Sobald von einem zentralen Server über REST ein Deployment-Prozess getriggert wird, lädt sich das Tool das jeweils zu deployende Artefakt aus unserem Artefakt-Repository und führt die Installation aus. Alle Artefakte sind als ZIP-Datei verfügbar und besitzen eine deploy.xml-Datei. Diese wiederum benutzt Ant-Tasks.
Florian kümmert sich um den Client, damit er auch mal in den Geschmack einer zu programmierenden Servlet-Anwendung unter Java kommt (eingesetzt wird Java 1.5, Jetty und Ant) 😉

Unser momentaner Praktikant hat in den letzten Tagen von mir die Aufgabe bekommen, sich mit dem Zend Framework, CakePHP, Doctrine und Propel auseinander zu setzen. Für den Serverteil unseres Deyploment-Tools, den ich entwickle, habe ich mich für das Zend Framework und Doctrine entschieden.
Was mir besonders beim Zend Framework fehlt, ist die Möglichkeit des Scaffoldings. Zwar existiert ein Proposal, das ist aber weder ausgereift, noch für den Einsatz mit Doctrine gedacht. Im Internet existiert bis dato auch keine vernünftige Zend_Doctrine_Scaffolding-Klasse.
Deshalb habe ich mich heute Nachmittag daran gesetzt, und eine rudimentäre Klasse zusammenzuschustern. Die Ergebnisse lassen sich sicherlich hier in ein paar Tagen bestaunen.

Die Scaffolding-Klasse werde ich übrigens auch für meinen neuen Blog einsetzen. Sobald die Tage wieder etwas länger und dunkler werden, werde ich die komplette Seite auf das Zend Framework und ebenfalls Doctrine umstellen. Unter anderem ist für die neue Seite Google Maps-Integration, Post-Deployment über XML-RPC an andere Blogs, eine neue Bildergalerie, eventuell Anbindung an das Active Directory der Firma und ein bissel AJAX geplant. Das Design soll weiter bestehen bleiben und natürlich bleiben auch alle Einträge erhalten.

Zwischenstand Xtopia 2007

Am Dienstag sind Marci, Robin und ich um 17 Uhr mit dem ICE nach Berlin aufgebrochen. Während der Zugfahrt saß eine wohl Alzheimer-Kranke Oma neben mir, ansonsten war die Fahrt relativ unspektakulär. ICE finde ich übrigens klasse: Eine Stunde hats für die Strecke Wolfsburg-Berlin gedauert.
Wir fuhren mit dem Taxi vom Ostbahnhof zu unserem Hotel und waren erstmal begeistert. Klasse Zimmer, klasse Service und wie ich heute morgen feststellen musste: Auch ein klasse Frühstück. Den Dienstag Abend verbrachten wir damit, dass wir mit zwei Flaschen Wein durch Friedrichshain irrten. Auf der Suche nach einer kleinen Kneipe mit Kickertisch. Meinem untrüglichen Sinn für gute Bars ist es dann auch zu verdanken, dass wir in einer dunklen Straße eine alternative Kneipe entdeckten. Die spielten dort Reggae, ein bissel Metal und es gab zwei Kickertische. Die Preise waren der Hammer: Kickern war kostenlos, ein halber Liter Alster kostete 2.50 und ansonsten war die Location auch mein Ding – so ein bißchen Mischung zwischen Kaschpa und Ost. Bis um halb elf verbrachten wir dort und machten uns danach auf den Weg zurück ins Hotel. Ich schaute mir -leicht angetrunken- nochmal den Saunabereich an und ging schließlich um kurz Mitternacht ins Bett.

Am Mittwoch Morgen ging es dann relativ früh aus den Betten, so dass wir pünktlich zur Keynote um zehn Uhr im Kosmos ankamen. Die Keynote war recht interessant.
Danach folgte nach einer kleinen Pause der erste Vortrag. Wir belegten den Designer Track über das Thema “Neue Möglichkeiten im Web und auf dem Desktop. Eine Einführung in Microsoft Expression Studio und Microsoft Silverlight”. Der Vortrag war vom Inhalt äußerst interessant. Die Moderatoren Oliver Scheer und Steffen Ritter konnten trotz einiger technischer Probleme eine gelunge Präsentation vortragen. Nach dem Vortrag sah ich dann, dass im Bewertungsbogen für die einzelnen Vorträge den Leuten von Microsoft ein dicker Fehler passiert ist. Anstatt “Microsoft Corporation” stand dort “MicroDoft Corporation”.
Wie dem auch sei, es folgte das Mittagessen. Es gab sehr leckeres Curry-Schnitzel mit Reis. Anschließend besuchten Robin und ich den Developer Track mit dem Thema “RIAs mit ASP.NET AJAX und dem Toolkit”, präsentiert durch Daniel Walzenbach. Leider war der Vortrag ziemlich langweilig und von den fünf vorbereiteten Demos funktionierten lediglich drei. Im Nachhinein stellte ich auch fest, dass wir in der Firma das Thema ASP.NEt nicht weiter verfolgen sollten. Die strikte MVC-Trennung ist nicht gegeben und der Code ist einfach nur grausam. ASP.NET-Entwickler mögen mir diese Aussage verzeihen.
Der kurzen Kuchenpause folgte im Designer Track der Vortrag “Mehr Freiheit für besseres Design. Was hat ein Designer von XAML?”. Jana Paetzold referierte ausgesprochen nervös und viele Teile der Präsentation wurden bereits im ersten Vortrag des Tages angesprochen. Der größte Fauxpax unterlief ihr, als sie auf eine Frage aus dem Auditorium antwortete: “Wir können das Thema ja nachher mal unter fünf Augen besprechen. Es können gerne noch mehr hinzukommen.” Was sie mit fünf Augen meinte – ich weiß es nicht. Aber ich dachte definitiv an etwas Anderes als sie. Der Großteil des Publikums auch, dem Gelächter nach zu urteilen *g*
Als letztes folgte am Dienstag für mich der Developer Track, wo Alexander Straus über “Entwicklung und Integration von Datenservices für das Web 2.0” spricht. War spannend und hatte einen guten technischen Tiefgang.

Nach dem Track gab es noch Abendessen und danach machten Marci, Robin und ich uns erstmal wieder auf den Weg zurück ins Hotel um Notebook + Sachen abzugeben und kurz zu duschen.
Um 20 Uhr ging es wieder zurück ins Kosmos. Die Party, die dort stand fand war ziemlich cool. Nur Entwickler dort, Freibier und -wein für alle, eine aufgebaute XBox, nette Leute. Ging gar nicht besser. Ich hatte das Vergnügen, mit vielen Leuten aus Süddeutschland, der Schweiz und Österreich zu reden. Unter anderem habe ich durch Zufall auch den Chef bzw. Arbeitskollegen von Mirko Stocker (blog.misto.ch) kennen gelernt.
Gegen ein Uhr wurden wir von den Securities als letzte Anwesende hinaus geworfen. Robin, Marci und ich waren derbe dicht – machten aber mit ein paar Studenten noch einen kurzen Abstecher zu Macces. Marci hatte denen kurz zuvor unsere Visitenkarten zugesteckt, da sie Interesse hatten, nach dem Studium bei uns anzufangen.

Die Nacht war recht kurz: Um zwei nach Hause gekommen, um halb sieben wieder aufgestanden. Mein Restalkohol war äußerst beachtlich. Robin hatte es hingegen wesentlich schlimmer erwischt: Beim Frühstück aß er fast nichts und wirkte auch ziemlich abwesend.
Somit erlebten Robin und ich die erste Präsentation des Developer Tracks im angetrunkenen Zustand. Oliver Scheer machte seinen Job bei “Silverlight – der erste Kontakt” sehr gut. Ist ein echte Alleinunterhalter. Der zweite Vortrag von Frank Fischer über “Dynamische Sprachen” war technisch recht anspruchsvoll. Fischer berichtete über die Implementierung von IronPython bzw. IronRuby in .NET. In den meisten Gesichtern der Anwesenden erkannte ich, dass das Thema wohl recht kompliziert war. Zumal war ich einer der wenigen, die die Code-Beispiele unter Ruby bzw. Python sofort nachvollziehen konnte. Entwickler in diesen Programmiersprachen waren fast gar keine vorhanden.
Robin machte sich nach dem Vortrag erst einmal zurück zum Hotel, ich hörte mir den nächsten Vortrag von Oliver Scheer an: “Silverlight – Hard Rock im Web”. Dort wurde noch einmal Popfly präsentiert und Oliver zeigte, wie man Code-Behind in Silverlight benutzt. Für mich als .NET und Silverlight Neuling war es ganz interessant. Bei einigen Sachen musste ich feststellen, dass Silverlight bei einigen Sachen des GWTs abgeschaut hat.
Zur Mittagspause futterte ich ein bissel was, allerdings nicht so viel wie am Mittwoch. Das Essen hatte mir heute nicht sonderlich gut geschmeckt.

Um halb drei referierte Dirk Primbs über “Deep Diving XAML und WPF”. Die Präsentation hatte es mir echt angetan. Primbs zeigte die Möglichkeiten, die man mit dem WPF hat. Ich bin begeistert, wie einfach man GUIs mit XAML entwerfen kann.
Gegen 16 Uhr begann Christian Weyer seinen Vortrag zum Thema “Ein Rückgrat für das Web 2.0: Services mit WCF jenseits von SOAP”. Weyer präsentierte das Thema so spannend, dass meine Nachmittagsmüdigkeit ratzfatz verflog.
Während der Präsentation fragte Weyer, wie viele Entwickler denn im Publikum seien. Es meldeten sich fast alle. Dann kam die Gegenfrage, wer denn Designer sei. Marci, der neben mir saß, hob als Einziger die Hand und handelte sich damit einiges Gelächter ein 😉
Als letzten Act wohnten wir “Prototyping” von Christian Lutsch bei. Der Vortrag war auf eine Art langweilig, die ich wiederum spannend fand. Lutsch hat eine komische Art von Humor und ich musste mehrmals herzhaft lachen.

Ich werde nun kurz unter die Dusche springen und schließlich mit Marci und Robin ein romantisches 4-Gänge-Candlelight-Dinner einnehmen 🙂

Eine stressige Woche

Die letzten Tage sind echt stressig – es gibt an unserem Projekt viel zu tun und nächste Woche beginnt für mich wieder der reguläre Dienst im Freizeitheim.
Gestern habe ich z.B. den halben Tag damit verbracht, folgende Funktion in das Projekt zu integrieren:

Man hat links und rechts jeweils eine “Liste”. Die Elemente aus der der rechten Liste soll man in die linke Liste ziehen können. Natürlich so oft man will. Dann soll die linke Liste automatisch in der Datenbank gespeichert werden. Hört sich einfacher an, als man denkt: Diese Funktionalität soll mit PHP5 (Zend Framework) serverseitig realisiert werden. An sich kein Problem. Client-seitig kommt stinknormales HTML, CSS und JavaScript zum Einsatz. Und genau da liegt der Hase im Pfeffer vergraben. Die Library Scriptacolous sollte allgemein bekannt sein und bietet die Listefunktionalität, wie wir sie gebraucht haben.
Also habe ich sie in das Projekt integriert. Das Problem bestand nun darin, dass die Elemente in der rechten Liste in die linke Liste nicht kopiert sondern verschoben wurden. Bringt mir persönlich wenig, da man mehrere Elemente vom Typ A in der linken Liste haben soll.
Die komplette Lösung hier zu präsentieren, wäre ein wenig umfangreich, deshalb hier die Vorgehensweise:

Zuerst muss die linke und die rechte Liste dynamisch mit JavaScript erzeugt werden. Die rechte Liste deshalb, weil sie bei JEDER erfolgreichen Verschiebe-Aktion neu generiert werden muss.
Danach werden mit Hilfe von Scriptacolous die beiden Listen Sortable gemacht (Sortable.create(‘listeA’, {onUpdate:function() { _buildListeRechts(); _buildSortables() })).
In onUpdate lege ich fest, dass nach dem Verschieben zuerst die Quell-Liste (rechts) neu erstellt wird und dann die beiden Listen von neuem sortiert werden.

Nun kommt der nächste Punkt: die Methode _buildListeRechts() muss die einzelnen id-Attribute der Listenelemente bei jedem Aufruf sequenziell erhöhen. Ansonsten lassen sich die Elemente nicht verschieben, weil sie nicht eindeutig identifizierbar sind.

Im letzten Schritt muss die linke Liste noch gespeichert werden. Backendmäßig ist das kein Thema – das Problem liegt beim Frontend und bei der Serialisierung: Wir setzen JSON ein, die Methode Sortable.serialize() erzeugt einen GET-String. Könnte man auch verwenden, bricht aber unsere Vorgehensweise.
Deshalb müssen die serialisierten Daten nochmals nach JSON serialisiert werden.
Folgende Hilfsmethode erledigt das für uns:

    /**
     * Wandelt ein serialisiertes Sortable-Objekt in ein Array um.
     * Das Array wird so zurückgeliefert, dass auch das erste Element in der sortierten Liste den Index 0 hat.
     * @param string Name der Liste
     * @return array Sortierte Elemente
     */
    function _convertSerializedSortableToArray(aSortableObject) {
        var serialized = Sortable.serialize(aSortableObject);
        var entries = serialized.split("&");
        var regexp = aSortableObject + "\[\]\=(\w+)";
        var rArray = new Array();

        for (var i = 0, m = entries.length; i < m; i++) {
            var match = entries[i].match(regexp);
            rArray.push(match[1]);
        }

        return rArray;
    }

Wie schon geschrieben: Gestern saß ich da den halben Tag dran. Danach folgte dann ein Refactoring unserer JavaScript-AJAX-Klasse. Dies machte ich aber zu Hause und schickte mir die Klassen per Email. Gegen viertel nach elf nachts bin ich dann halbtot ins Bett gefallen.

Heute morgen startete ich dann mein Outlook und wollte die JavaScript-Dateien aus dem Anhang speichern. Outlook zeigte mir aber folgendes an: “Outlook hat den Zugriff auf die folgenden potenziell unsicheren Anlagen blockiert”.
Um die Dateien dennoch zu speichern, musste ich der Registry unter HKCUSoftwareMicrosoftOffice11.0OutlookSecurity die Zeichenfolge “Level1Remove” erstellen.
Als Wert mussten die Dateinamenserweiterungen eingetragen werden, die von Outlook ignoriert werden sollen. Also: “.js;.htm”.

Now to something completely different: Am Freitag spielt Boxing Fox in Gifhorn, Samstag werde ich wahrscheinlich nach Fallersleben aufs Altstadtfest. Also: hin da!

Zend Framework

Wie ich in einer der letzten Posts bereits schrieb, setzen wir für ein Projekt das Zend Framework ein. Ich schrieb ebenfalls, dass die Nutzung nicht intuitiv ist.
Ich muss meine Meinung nun aber revidieren – am Sonntag Abend habe ich die komplette Dokumentation noch einmal gründlich durchgelesen. Montag auf der Arbeit machte ich dann meine ersten “Gehversuche”. Und es ging gut.
Ich hatte in ein paar Stunden die Architektur unserer Anwendung niedergeschrieben, danach folgten mehrere Refactoring-Prozesse.
Unter anderem baute ich für die Konfiguration Server-abhängige Einstellungen ein, reduzierte die Methodenaufrufe für das Weiterleiten zu bestimmten Controllern und baute die Templates so um, dass für jeden Controller ein bestimmtes Template herangezogen wird. In dieses Template wird die View der Action gerendert. Im nächsten Schritt wird die erzeugte View in ein Standard-Template eingebunden, so dass allgemeine Inkludierungen wie CSS-Dateien, Logo etc. nur noch in genau einer Datei eingetragen werden müssen.
Am Dienstag diskutierten wir das Datenbank-Schema, änderten einige Sachen und Marci begann mit den Überlegungen für Design & Layout. Dabei kam dann heraus, dass wir AJAX einsetzen wollen und auch müssen.
Bei meinen bisherigen Projekte – sei es in Java oder PHP – war die Anbindung mit AJAX relativ aufwendig, da ich immer bestimmte Anpassungen machen musste. Mit relativ meine ich wirklich relativ. Ich habe gestern unseren Eltern-Klasse, von denen alle Controller erben, refactort und innerhalb von einer halben Stunde eine funktionierende Benutzersuche integriert.

Ich bin mittlerweile davon überzeugt, dass bei großen Projekten das Zend Framework enorme Vorteile bringt. Die vorhande MVC-Architektur macht das Entwickeln von Web-Anwendungen sehr einfach und ich finde es gut, dass Zend bereits in der Dokumentation den Code-Style definiert.
Zwei Sachen vermisse ich allerdings noch: Objekt-Relationales Mapping und einen Generator, wie er bei RubyOnRails existiert.
Das OR-Mapping könnte ich mit meinem DAO-Framework lösen, beim Thema “Generator” bin ich am Überlegen, ob ich so etwas selbst programmiere.

Kniffelig: Raute (#) in JSON-Request funktioniert nicht ohne Weiteres

Meine letzte Stunde habe ich damit verbracht, in unserem Arbeitszeitabrechnungs-Tool einen Bug zu beheben: Sobald man für eine Tätigkeit einen Kommentar mit einer Raute (#) hinterließ, wurden alle Daten, die danach folgten abgeschnitten.
Dazu ist folgendes zu sagen: Unser Tool ist eine klassische Web 2.0-Anwendung, alle Anfragen laufen über JavaScript, codiert wird mit JSON.
Auf der Serverseite nimmt mein DAOFramework (PHP5) die JSON-Daten entgegen und unserialisiert diese.

Das Problem besteht darin, dass die Javascript-JSON-Library von http://www.json.org das Raute-Zeichen nicht URL-codiert. Ich hatte deshalb die JavaScript-Methode encodeURI() benutzt, die dieses eigentlich manuell nachholen sollte. Funktionierte aber ebenfalls nicht. Damit man eine Raute in einem JSON-Request absetzen kann, muss der String ERST mit Hilfe von encodeURIComponent() codiert und danach JSON.stringify() aufgerufen werden.
Nun haut das auch hin.

Aus AJAX wird SJAJ

SJAJ? Richtig gelesen: “Synchronous JavaScript and JSON”. Zugegebenermaßen: nicht besonders einfallsreich, aber ich dachte mir: “Hey, machste mal eine Wortneuschöpfung”.

Synchrone JavaScript-Calls sind an sich ziemlich unsinnig, da das gegen die AJAX-Idee spricht.
Allerdings gibt es unter Umständen dafür einen Verwendungszweck.
Ich brauchte diese Funktionalität für die Erweiterung von “AZE Online”:
Darin existieren zwei Select-Boxen. Die eine enthält die Kunden, die andere die zugehörigen Projekte eines Kunden.

Wenn ich nun einen bestehenden Arbeitszeiteintrag editieren will, werden die passenden Einträge der Select-Box selektiert. Was passiert nun aber, wenn ich die Id des Projekts setzen will, aber der Inhalt der SelectBox an sich noch gar nicht geladen ist?
Vor diesem Problem stand ich nun. Die logischste (und umständlichste) Methode wäre nun, eine Funktion zu schreiben, die die Daten vom RTOGateway (ich benutze mein DAOFramework) lädt und im Anschluss die Id selektiert, die als Parameter übergeben wurde. Damit kommt man aber zu einer gewissen Methoden-Redundanz – die Methode, die dies tut wird an andere Stelle ebenfalls aufgerufen.

Ich habe deshalb unsere JS-AJAX-Klasse -die mit JSON zusammenarbeitet- um eine blockingHttpRequest-Methode erweitert:

/**
 * httpRequest()
 *
 * Setzt einen XMLHttpRequest ab.
 *
 * @param string uri URI des aufzurufenden AJAX-Servers
 * @param object objData JS-Objekt mit den Daten, die an den AJAX-Server gesendet werden sollen
 * @param function ResponseHandler Name der Funktion die die Antworten vom AJAX-Server empfangen soll
 * @param boolean Ist der Request synchron bzw. blockiert? (Optional, kann weggelassen werden. Default ist FALSE)
 * @return
 */
function httpRequest(uri,objData,ResponseHandler, isBlocking) {
	var ajax = new AjaxClass;

	if (isBlocking)
	{
	  ajax.blockingHttpRequest(uri, objData, ResponseHandler);
	}
	else
	{
	  ajax.httpRequest(uri,objData,ResponseHandler);
	}
}

/**
 * blockingHttpRequest()
 *
 * Setzt einen blockierenden HTTP-Request ab. Kann benutzt werden, damit auf bestimmte Ereignisse gewartet wird, widerspricht aber dem AJAX-Prinzip.
 * @param string uri URI des aufzurufenden AJAX-Servers
 * @param object objData JS-Objekt mit den Daten, die an den AJAX-Server gesendet werden sollen
 * @param function ResponseHandler Name der Funktion die die Antworten vom AJAX-Server empfangen soll
 * @return
 */
function blockingHttpRequest(uri, objData, ResponseHandler) {
  var ajax = new AjaxClass;
  ajax.blockingHttpRequest(uri, objData, ResponseHandler);
}

/**
 * class AjaxClass()
 *
 * Klasse die von httpRequest() benutzt wird, um einen XMLHttpRequest abzusetzen.
 */
function AjaxClass() {
// ....

	/**
	 * __init()
	 *
	 * Private Funktion zum Initalisieren der Daten
	 *
	 * @param uri - URI der abzurufenden Seite
	 * @param value - Wert des Parameters
	 * @param targetID - ID des Elements, dass die Ausgabe anzeigen soll
	 */
	function __init(uri, objData, ResponseHandler)
	{
		// Default-Postfix
		var postfix = "?", completeURI;

		//alert('request absetzen');
		externalResponseHandler = ResponseHandler;

		// Ueberpruefen, welches Anhaengsel wir an die URI pasten muessen
		// URI der Form http://domain/?data1=wert1... => ?-Postfix
		if (uri.match(/?/)) {
		  postfix = "&";
		}

		// Komplette URI zusammenbauen
		this.completeURI = uri + postfix + 'params=' + JSON.stringify(objData);
	}

	/**
	 * AjaxClass_blockingHttpRequest()
	 *
	 * Blockierender AJAX-Aufruf / ***NICHT*** synchron. Wird teilweise benötigt für Events.
	 *
	 * @param uri - URI der abzurufenden Seite
	 * @param value - Wert des Parameters
	 * @param targetID - ID des Elements, dass die Ausgabe anzeigen soll
	 */
	function AjaxClass_blockingHttpRequest(uri, objData, ResponseHandler) {
		// initalisieren
		__init(uri, objData, ResponseHandler);

		//alert(completeURI);
		http.open('GET', completeURI, false);

		// Daten senden. In unserem Fall nix! / Dieser Aufruf blockiert!!!
		http.send(null);
		// Antwort handlen
		this.handleResponse();
	}
// ....

Die Methode httpRequest() besitzt den optionalen Parameter isBlocking. Sobald dieser auf TRUE gesetzt ist, wird die JavaScript-Ausführung “synchron” ausgeführt.
Soviel dazu.

In einer 3/4h Stunde ist hier in Weyhausen BV und mir knurrt der Magen ohne Ende… Freu mich schon auf die geschmierten Brötchen 😉