Artikel in der Kategorie 'Softwareentwicklung'

jQuery ist toll

Wo ich gerade bei jQuery bin… also das ist mal eine echt tolle Sache. So effizient habe ich glaube ich noch nie Code geschrieben. Da passt der Slogan “The Write Less, Do More, JavaScript Library” eindeutig wie die Faust aufs Auge. Ein kleines Codebeispiel zeigt m.E. recht gut, was ich meine:

// Hide more than 3 rows of a table
  1. if ($("#listbody tr").length > 3) {
  2.   $("#listbody tr").slice(3).hide();
  3.   $("#listbody").append('<tr><td><a id="moreitems" href="#">Zeige mehr Einträge</a></td></tr>');
  4.   $("#moreitems").click(function(){$("#listbody tr").slice(3).fadeIn("normal").end().filter(":last").remove();return false;});
  5. }

Zunächst wird überprüft, ob die Tabelle (eigentlich ist’s tbody) mit der ID #listbody mehr als 3 Reihen enthält. Wenn dies der Fall ist, werden alle Reihen ab der dritten versteckt. Dann wird ein neue Reihe mit einem Link angehängt. Dieser Link erhält dann eine Funktion für das onclick-Event. Die Funktion macht nun:

  1. Nimm alle Reihen ab der dritten.
  2. Zeige sie mit einem Fadeeffekt wieder an.
  3. Mache die letzte “zerstörerische” Manipulation rückgängig (hier slice(3)), womit wir wieder alle Reihen haben.
  4. Filter die letzte Reihe raus (unser hinzugefügter Link)
  5. Entferne diese letzte Reihe.

Dank des sogenannten “Chaining”, wobei ein jQuery-Aufruf immer wieder ein jQuery-Objekt zurückliefert, lässt sich das so wunderbar kompakt schreiben. :)

Bug in jQuery.tablesorter.js

Für jQuery gibt es ein wunderbares Plugin: den Tablesorter. Dieser erlaubt es einmal eingebunden, eine einfache HTML-Tabelle mit einem einfachen Befehl so umzuwandeln, dass der Nutzer sie nach Belieben sortieren kann. Ganz ohne irgendwelchen Programmieraufwand in der darunterliegenden Programmiersprache. Sicherlich kann man nun darüber streiten inwiefern man da eine Fallbackmöglichkeit brauch, aber wenn das Sortieren nur als Gimmick dient, reicht wohl die JS-Lösung.

Nun bin ich beim Rumexperimentieren aber auf ein Problem (was ich erst nach ein paar Irrungen und Wirrungen zuordnen konnte) gestoßen. Der tablesorter erkennt selbstständig die zu sortierenden Datentypen (also ob Text, Zahl, Datum, …). Dabei betrachtet er immer nur die erste Zeile der Daten. Nun hatte ich bei einer Version in der ersten Zeile zwei Zellen mit einer 0 (also Null). Und diese wollte er einfach nicht als Zahl erkennen. Ein Blick in den Code verriet, dass der zugrundeliegende reguläre Ausdruck eigentlich korrekt ist und die 0 als Zahl erkannt werden sollte. Hier der relevante Teilausschnitt (nach den … kommen noch ein paar Alternativen):

Ausschnitt jQuery.tablesorter.js
  1. this.isDigit = function(s,config) {
  2.   var DECIMAL = '\\' + config.decimal;
  3.   var exp = '/(^[+]?0(' + DECIMAL +'0+)?$)…/';
  4.   return RegExp(exp).test($.trim(s));
  5. };

Wobei config.decimal eine JS-Variable für das sprachabhängige Komma ist. Wie man sieht sind der Teil vor und nach der 0 beide optional. Trotzdem wird die 0 nicht erkannt. Erst nachdem ich ein (^0$) als Alternativgruppe hinzugefügt habe, erkennt er nun die 0 korrekt als Zahl… sehr seltsam.

Ich habe nun mal den Autor des tablesorters kontaktiert, um zu sehen, was dieser dazu sagt.

Gamestar 2.0 mal wieder

Was kann man bei so einem Restart einer Webseite noch falsch machen?

1. Man setzt im Newsfeed falsche Links. Statt auf Gamestar.de gingen am Anfang alle URLs auf irgendwas.idg (IDG heißt der Verlag).

2. Man veranstaltet ein Gewinnspiel und der Link im Newsletter auf das Gewinnspiel wird vom Server nicht erkannt.

Beides wurde natürlich recht schnell (2) bzw. langsam (1) behoben. Aber passieren sollte sowas eigentlich nicht. Mal sehen, was Gamestar 2.0 noch so bringt… :)

Strato und der include_path

Soeben hatte ich ein Problem mit einem Kunden, bei dem ein Skript nach dem Umzug von meinem Entwicklungsserver auf dessen Produktivserver bei Strato seinen Dienst verweigerte.

Die Ursache war, dass sich das PHP-Skript weigerte ein require_once(‘lokale_datei.php’) zu akzeptieren. Der Server behauptet klipp und klar, dass es die Datei, die direkt neben der aufrufenden Datei liegt, nicht gibt. Mit einem leeren(!) include_path auch kein Wunder. Seltsam, dass das Ganze eine Verzeichnisebene tiefer keinerlei Probleme macht.

Das Problem war ja leicht zu beheben, aber wo kommt es her?

AJAX 0.1

So… nun ist es geschehen, nachdem ich mit die Tage eine Reihe von AJAX-Frameworks angeschaut habe, habe ich mich heute für ein Framework entschieden und meine erste kleine AJAX-Anwendung programmiert. Entschieden habe ich mich dabei für jQuery. Warum das? So genau kann ich das nicht sagen. Ich habe mir diverse Vergleiche, die verschiedenen APIs und ein paar Tutorials angeschaut. jQuery hatte für alles, was ich in nächster Zeit realisieren möchte, ein paar Tricks (oder fertige Plugins :D ) auf Lager, und zudem zeichnet es sich durch seine geringe Größe (aktuell 15KB gzipped) aus.

Angefangen habe ich mit dem Einbinden dieses Bewertungsplugins und einer Auswertung via AJAX. Mein Dank gilt dabei auch Jörn Zaefferer für sein kleines Tutorial, was mir beim Verständnis geholfen hat.

Web 2.0 ich komme! ;)

FAQ = Frequently Ignored Questions?

Wo wir gerade bei Webseiten sind. Irgendwie macht man sich als Admin doch ein paar Gedanken, wenn einem die Nutzer regelmäßig Fragen stellen, die fast im gleichen Wortlaut im FAQ-Teil der Webseite beantwortet werden. Doch was ist die Ursache dieses Phänomens?

  1. Die FAQs sind zu gut versteckt?
  2. Die FAQs sind zu unübersichtlich?
  3. Die Nutzer wissen nicht, dass die FAQs existieren?
  4. Die Nutzer ignorieren die FAQs einfach?

Ich werde mich die Tage mal mit der Thematik beschäftigen und die Lage analysieren.

Gamestar.de 2.0 = Fehlstart 2.0 ?

Vor ein paar Tagen ist eine der größten Spielemagazinseite im Web 2.0 angekommen: Gamestar.de

Tja… dummerweise scheinen die Zuständigen nichts von entsprechenden Tests zu halten, denn anders kann ich mir nicht vorstellen, wie sooo viel Bugs und Fehler zu stande kommen können. Nun sind ja seit dem Relaunch ja schon ein paar Tage vergangen und die Fehlerzahl (von Java über Rails zu XML-Fehlern) im Verhältnis zu den aufgerufenen Seiten sinkt langsam, aber trotzdem ist das mE für so eine Branchengröße einfach ein Unding.

Bereits vor einer Weile hat das Magazin ein neues klares und sauber strukturiertes Design bekommen. Die neue Webseite ist aber durch möglichst viel Communityfeatures sehr, sehr überladen und es wird auch eine Weile dauern bis man sich zurecht findet.

Auch so manche Entscheidung kann ich nicht nachvollziehen. So hat z.B. jeder registrierte Nutzer (wenn man es denn durch die Fehler schafft) die Möglichkeit einen Blog einzurichten. Ob man das nun unbedingt auf einer Spielewebseite machen muss, ist jetzt eine andere Frage, aber jeden Blog jedes Users schon mit einem “Blog-Tutorial” genannten Begrüßungseintrag zu versehen, ist doch einfach nur dämlich. Somit tummeln sich hundertausende dieser Dummyeinträge auf der Webseite und somit zwangsläufig wohl auch in der Datenbank. Nunja… man kann den eigenen DB-Server aus selbst zumüllen. Die Performance freut sich immer. ;)

Auch das Caching hatte am Anfang arge Probleme, war ich doch ohne mich zu registrieren oder einzuloggen als User xyz eingeloggt. Den Datenschutz wird’s freuen. ;)

Die Redaktion selbst nimmt es mit Humor… kann ja auch nichts dafür. Laut Impressum sind die Schuldigen Zuständingen bei der nbsp GmbH su suchen… irgendwie erinnert mich das ein wenig an die Mautumsetzung. Das Ganze war jetzt wohl keine prestigeträchtige Glanzleistung, auch wenn so große Projekte natürlich kein Zuckerschlecken sind, und hat wohl so manchem Angstellten das Osterfest etwas versaut.

Naja… ich warte nunmal ab, was da so demnächst passiert. :)

Kontextmenü in einem DataGridView

Eigentlich eine ganz einfache, normale Sache:

Man möchte via einem Rechtsklick ein Kontextmenü auf einer Zelle öffnen, die sich in einem DataGridView befindet. Dies sollte möglichst mit einem einzigen ContextMenuStrip geschehen, was am DataGridView hängt. Klingt immer noch ganz einfach. Nun soll sich das Kontextmenü zwar überall öffnen, aber nur auf einer Datenzelle bestimmte Optionen zulassen (z.B. Löschen), also nicht im Kopf und erst recht nicht im leeren Bereich. Klingt immer noch nach einem ganz normalen Vorgehen, was man jeden Tag brauchen könnte. Nun könnte man meinen, dass dies von den Herrschaften bei Microsoft auch so gesehen wird und .NET solch eine Funktion unterstützt… nunja… soweit die Theorie…

Praxis:

  1. dataGridView.CellContextMenuStripNeeded += new DataGridViewCellContextMenuStripNeededEventHandler(dataGridView_CellContextMenuStripNeeded);
  2. private void dataGridView_CellContextMenuStripNeeded(object sender, DataGridViewCellContextMenuStripNeededEventArgs e)
  3. {
  4.   if (e.ColumnIndex > -1 && e.RowIndex < -1)
  5.   {
  6.     //Menüitem aktivieren
  7.   }
  8.   else {
  9.     //Menuitem deaktivieren
  10.   }
  11. }

Ich hatte da eine etwas einfachere Lösung gehofft. Nun möchte ich sogar noch Daten sortieren, wenn man eine Kopfzelle anklickt. Klingt einfach? Lösung folgt die Tage…

ClickOnce updated nicht

Nachdem ich nun eine Weile mit der Mircosoft Visual C# 2008 Express Edition und der API-Doku im MSDN .NET Framework Developer Center gearbeitet, hatte ich nun ein – im Nachhinein recht witziges – Problem. Im Zuge einer ClickOnce-Anwendung habe ich die recht spartanisch gestaltete automatische Updatefunktion mit einer programminternen Variante ersetzt. Nach einer Reihe von Dummydeployments – man kann sonst ja nicht die Funktion testen – war ich schon nah am Rande der Verzweiflung, warum der asynchrone Updater einfach nicht updaten wollte. Alle relevanten Informationen wurden gefunden, aber er tat einfach nichts.

Read more »

Visual C# vs PHP

Ich weiß… der Vergleich hinkt etwas, da Visual C# und PHP nicht gerade im gleichen Bereich alternativ eingesetzt werden, aber das sind die beiden Programmiersprachen, mit denen ich z.Z. arbeite. Im direkten Vergleich merkt man aber mal die extremen Unterschiede in der Programmierung von (Standalone)Anwendungen und Webanwendungen… und was ein gutes Tool alles ausmachen kann.

Für C# nutze ich zZ die kostenfreie Visual Studio C# Express Edition 2008 von Microsoft. Interface zusammenklicken und generierten Code auffüllen. Das macht echt Spaß. Allein das Anlegen eines Eingabeformulars bzw. die Eingabekontrolle geht so locker von der Hand. Einfach einen ErrorProvider und ein paar Funktionen zur Kontrolle hinzufügen und der Rest geht von ganz allein. Wenn man dann an das HTML-Formularhandling denkt… *graus* … vor allem, da ich das Meiste noch wirklich per Hand im guten alten Phase5 mache. Ich habe mir zwar schon eine kleine Klasse geschrieben, die etwas beim Verwalten von Formularen hilft, aber Eingabekontrolle beherrscht sie noch nicht.

Kennt zufällig wer ein gutes Framework für PHP, was da Abhilfe schafft? Ich habe mir zwar schon 1-2 angeschaut, aber bis jetzt hatte ich noch nie die Motivation mich in eins einzuarbeiten.

« Vorherige SeiteNächste Seite »