Mehrere Checkboxen mit Javascript markieren

Manchmal möchte man auf einer Webseite den Benutzen die Möglichkeit geben, mehrere Checkboxen aufs mal zu Markieren. So muss der Benutzer nicht jede Checkbox einzeln anklicken, sondern kann mit einem klick auf "Alle Markieren" alle Checkboxen markieren.

Dies ist keine grosse Sache. Mit einer JavaScript Funktion kann man das Problem recht simpel lösen. Über einen Link wird die Funktion aufgerufen, welche dann die Checkboxen markiert. Also mal angenommen, wir haben den folgenden HTML Code:
<input type="checkbox" name="box" value="1" />
<input type="checkbox" name="box" value="2" />
<input type="checkbox" name="box" value="3" />
<input type="checkbox" name="box" value="4" />
<input type="checkbox" name="box" value="5" />
<input type="checkbox" name="box" value="6" />
<input type="checkbox" name="box" value="7" />
<input type="checkbox" name="box" value="8" />
<input type="checkbox" name="box" value="9" />

Nun benötigen wir im Header der HTML Datei noch die folgende Javascript Funktion:
var marker=false;
function mark()
{
    var elements=document.getElementsByName("box");

    if(marker==false)
    {
        for(i=0;i<elements.length;i++)
        {
            elements[i].checked=true;
            marker=true;
        }
    }
    else
    {
        for(i=0;i<elements.length;i++)
        {
            elements[i].checked=false;
            marker=false;
        }
    }
}

Wenn diese Funktion nun aufgerufen wird, werden beim ersten mal alle Checkboxen markiert, beim zweiten Durchgang wird die Markierung wieder entfernt. Der Zustand der Markierung wird in der Variable marker gespeichert.

Aufrufen kann man die Funktion mit einem Link in der folgenden Art. Allerdings gibt es da auch noch viele andere Möglichkeiten.
<a href="#" onClick="mark()">Alle Markieren</a>

Bilder mit JavaScript preloaden

Ich versuche momentan eine kleine und simple Galerie zu Programmieren. Ein PHP Script soll die Bilder aus eine Verzeichnis auslesen und dann mit Lightbox anzeigen. Der Nachteil von Lightbox ist aber, dass es erst funktioniert, wenn die Seite komplett geladen ist. Und wenn es da mehrere Bilder gibt, kann das Laden der Seite auch mal länger dauern und die wenigsten Besucher wollen da warten.
Ich versuche diese Problematik nun mit einem Preloader zu umgehen. Bisher ohne grossen Erfolg. Aber immerhin weiss ich jetzt, wie man Bilder mit JavaScript "preloadet."
<script language="JavaScript" type="text/javascript">
    <!--
        if (document.images)
        {
            preload_obj=new Image();
            preload_obj.src="images/test.jpg";
        }
    //-->
</script>

Recht simpel. Es wird ein neues Objekt erstellt und danach mit src die Quelle der Datei zugewiesen. Natürlich kann man so mit PHP auch mehrere Bilder preloaden.

JavaScript Effekte mit Scriptaculous

Ich bin gerade etwas mit den Scriptaculous Libraries am Pröbeln. Eine sehr nette, und einfache Sache. Einige Teile sind sicher etwas Eyecandy, aber das kommt je länger desto mehr. Auch im Webbereich.
Mit Scriptaculous kann man "Aufklappeffekte" wie ich sie bei meiner Tourenverwaltung habe, ganz einfach und noch etwas schöner realisieren. Dazu benötigt man nur die neusten Scriptaculous (blödes Wort) Libraries. Dieso kopiert man zusammen mit der Datei prototype.js in einen Ordner. Vorzugsweise javascript/. Wie man erahnen kann, basiert Scriptaculous auf Prototype, allerdings muss Prototype nicht zusätzlich heruntergeladen werden.
Nun müssen die Libraries noch in die Seite eingebunden werden. Dies funktioniert wie bei jedem JavaScript. Bei Scriptaculous kann noch angegeben werden, welche Module geladen werden sollen. Dies macht man mit dem load Parameter. Wenn dieser Parameter nicht angegeben wird, werden alle Module geladen. Ich benötige aber nur das Effects Modul also lade ich auch nur dieses.
<script type="text/javascript" language="JavaScript" src="js/prototype.js"></script>
<script type="text/javascript" language="JavaScript" src="js/scriptaculous.js?load=effects"></script>
Auf der Scriptaculous Homepage hat es schon diverse Beispiele zu den verschiedenen Effekten. Mich interessierte der Effekt toggle mehr, da es damit möglich ist, ein Element auf und zu zu klappen. Mit einem Klick auf ein Element kann so ein anderes Element geöffnet oder geschlossen werden. Hier ein simples Codebeispiel.
<div onClick="new Effect.toggle($('element'),'blind')">click</div>
<div id="element"><div>test test test</div></div>
Damit kann man mit einem Click das Element element öffnen und wieder schliessen. Hier wird der Effekt blind verwendet. Wichtig ist, dass im zu öffnenden Element noch ein zusätzlicher Divcontaoiner ist, sonst funktionieren einige Effekte nicht korrekt. Das Beispiel sieht mit etwas zusätzlichem CSS dan so aus:
blind
test test test
test test test
test test test
test test test
test test test
test test test
test test test
test test test
test test test
test test test
test test test
test test test
test test test
test test test

Oft möchte man es ja so haben, dass das Element von Anfang an geschlossen ist. Dazu kann man ganz einfach das CSS Element display mit dem Wert none benutzen. Das sieht dann so aus.
blind

Zusätzlich gibt es noch die Effekte slide und appear welche mich persönlich nicht so ansprechen. Mit gefällt blind am besten. Zum Schluss aber noch je ein Beipsiel.
slide

appear

Achtung: Lightbox2 verwendet schon Scriptaculous und Prototype. So muss man diese Libraries nicht mehr laden.

Autokompletierung abschalten

Die autovervollständigen Funktionen der heutigen Browser sind ja schon schöne Sachen. Nur den ersten Buchstaben eintippen und schon werden schon benutzte Texte angezeigt. Manchmal möchte man das allerdings nicht. Zum Beispiel bei Ajax-Suchen wo die Vorschläge von eine Script zur Verfügung gestellt werden. Wenn nun der Browser auch noch seine Vorschläge anzeigt, kommt das zu hässlichen Überschneidungen.
Mit JavaScript kann man diese Funktion relativ simpel für bestimmt Textfelder deaktvieren. Die Methode setAttribute() macht das möglich. Zuerst schreibt man eine kleine Funktion, die entweder direkt in den Head oder halt in eine externe Datei eingebunden wird. Eine externe Datei hat en Vorteil, dass sie weniger Traffic verursacht, da sie gecacht werden kann.
function disableAutocompletion()
{
    var autocomplete=document.getElementById('user');
    if(autocomplete==null) return;
    autocomplete.setAttribute('autocomplete','off');
}

Diese Funktion wird nun via onLoad() beim Laden der Seite aufgerufen.
<body onLoad="disableAutocompletion()">

Und schon werden vom Browser keine Vorschläge mehr gemacht.

Update, 22.03.07 09:49:
Warum einfach wenns auch kompliziert geht. Mit autocomplete="off" direkt im Input-Feld lässt sich das auch abstellen.

Update 2, 22.03.07 10:24:
autocomplete scheint allerdings kein Valides XHTML Attribut zu sein.

Ajaxing

Für eine kleine Webapplikation im Geschäft, die wir verwenden werden um die Flugtarife zu verwalten, arbeite ich mich nun in Ajax ein. Ich war erstaunt wie einfach das war. Eine übersicht an Ajax Tutorial gibt bei Dr. Web. Ich habe mir die kürzeste Version rausgepickt und das ganze auf meine Bedürfnisse angepasst.
Als erstes benötigt man ein Objekt, mit dem man die Daten sendet bzw. empfängt. Dies sieht so aus:
function createRequestObject()
{
    var ro;
    var browser=navigator.appName;
    if(browser=="Microsoft Internet Explorer")
    {
        ro=new ActiveXObject("Microsoft.XMLHTTP");
    }
    else
    {
        ro=new XMLHttpRequest();
    }
    return ro;
}

var http=createRequestObject();

Um nun die Daten zu senden benötigt man eine weitere Funktion. Hier sendReq genannt:
function sendReq(url)
{
    http.open('get',url);
    http.onreadystatechange = handleResponse;
    http.send(null);
}

Diese Funktion sendet einen GET Request an die per Parameter übergebene URL. Danach wird die Funktion handleResponse() aufgerufen, welche die Daten verarbeitet.
function handleResponse()
{
    if(http.readyState == 4)
    {
        var response=http.responseText;
        document.getElementById('showData').innerHTML=response;
    }
}

Diese überprüft zuerst, ob die Übermittlung vollständig ist und schreibt die Daten dann in den div Container mit der ID showData. Hier die verschieden Werte und deren Bedeutung die http.readystate haben kann.
	0 = uninitialized
	1 = loading
	2 = loaded
	3 = interactive
	4 = complete

Diese funktionen werden aber nicht direkt aus der HTML-Seite aufgerufen. Ich habe dafür eine kleine Wrapperfunktion gebaut, die das ganze einwenig übersichtlicher macht.
function flights()
{
    var airline=document.filter.airline.value;
    var destination=document.filter.destination.value;
    var date=document.filter.date.value;
    var class=document.filter.class.value;

    sendReq('rpc.php?action=flights&airline='+airline+'&destination='+destination+'&date='+date+'&class='+class);
}

Wird nun also die Funktion flights() von der HTML-Seite aufgerufen, so liest das Script die Werte der Input-Felder airline, destination, date und class aus. Diese Daten werden mit einem GET Request an das PHP-Script rpc.php weitergegeben. Nach der Verarbeitung der Daten gibt das PHP-Script die Daten aus und die JS-Funktion schreibt sie in den Div-Container. Eigentlich recht simpel und es verweinfacht die Arbeit mit der Applikation merklich.

ClickHeat - Heatmaps

Einigen ist vieleicht CrazyEgg bekannt. Damit lassen sich sogenannte Heatmaps erstellen. Das heisst, es wird angezeigt, wo am meisten hingeklickt wird. Praktisch ist das vor allem, wenn man wissen will, was auf der eigenen Webseite am beliebtesten ist. CrazyEgg hat aber einen Nachteil. Nur die ersten 5000 Klicks sind gratis danach bezahlt man mindestens 19$ pro Monat. Un bei einer gut besuchten Seite hat man diese 5000 Klicks schnell durch.
Eine kostenlose Alternative dazu ist ClickHeat. Da ClickHeat in PHP und JavaScript geschrieben ist, gestaltet sich die Installation, zumindest auf einem Server mit PHP, relativ einfach. Benötigt wird, wie schon erwähnt, JavaScript auf der Clientseite, PHP und die GD Library auf der Serverseite. mySQL wird nicht benötigt, da alles in Files geschrieben wird.
Nun aber zur Installation. Eigentlich schon beschrieben auf der ClickHeat Seite aber ich mache hier noch eine Deutsche fassung.

Schritt 1 - Download
Als erstes muss man die aktuellste Version (momentan 0.4) von Sourceforge herunterladen und diese auf dem Computer entpacken.

Schritt 2 - Upload
Nun muss man die Dateien auf den Server laden. Am besten ist es, wenn man den Ordner /clickheat/ erstellt und die Dateien dort reinlädt. Es geht aber auch anders, allerdings wir das dann umständlicher.

Schritt 3 - Passwort anpassen
Die Seite, die die Heatmaps anzeigt ist Passwortgeschützt und damit nicht jeder dort reinkommt sollte man das Passwort ändern. Dies macht man in der Datei /clickheat/config.php und ändert dort den Eintrag CLICKHEAT_PASSWORT

Schritt 4 - Funktioniert es?
Nun los zu Check ob alles funktioniert. Dazu ruft man die Seite http://{homepage}/clickheat/check.php auf. Dort gibt man nun das Passwort ein und wird zu Seite index.php weitergeleitet. Nun ja, eingentlich nicht die Seite, die wir wollten, also rufen wir nochmals die Seite check.php auf. Allenfalls muss man nun noch den Ordner /clickheat/logs/ erstellen und mit Schreibrechten für den Webserver versehen.
Wenn dann alles OK ist, kann man zum nächsten Schritt übergehen.

Schritt 5 - JavaScript Code einbauen
Damit die Clicks aber auch geloggt werden, muss man einen kleinen JavaScript Code in die Seite einbauen, die man überwachen will.
Den folgenden Code fügt man kurz vor dem </body> Tag ein.
<script type="text/javascript" src="/clickheat/clickheat.js"></script>
<script type="text/javascript">initClickHeat('page');</script>
<noscript><a href="http://www.labsmedia.com/clickheat/" title="ClickHeat : track clicks">clickheat</a></noscript>
Die letzte Zeile kann man auch getrost weglassen, wenn man will.
Sollt man den Ordner clickheat aber nicht direkt im / Verzeichnis haben, muss man den Pfad zur Datei clickheat.js abändern und die zweite Zeile würde so aussehen:
initClickHeat('page','/ordner/clickheat/click.php');
Noch zum Parameter page beim aufruf der Funktion iniClickHeat(). Dieser Parameter wird verwendet zur Anzeige der Heatmaps. Damit ist es möglich mehrere Seiten zu gruppieren. Wenn ich nun eine Heatmap für alle Artikel will, muss ich nur bei allen Artikeln den Parameter artikel reinschreiben und ich sehe alle klicks auf einmal.

Schritt 6 - Das Ergebniss
ClickHeat ist nun eingerichtet und der Code ist eingebunden. Bereit für einen Test?
Einfach einige male auf die Seite mit dem ClickHeat Code klicken und dann die Seite http://{homepage}/clickheat/ aufrufen. Und schon werden die Clicks angezeigt.

Fazit
Man merkt, dass ClickHeat noch nicht so ausgereift ist, einige Klicks werden bei mir gar nicht gezählt und einige an einem falschen Ort. Aber bei den meisten Klicks funktioniert es.
Wenn es stetig weiterentwickelt wird, könnte ClickHeat zu einer echten Alternative zu Diensten wir CrazyEgg werden. Momentan ist es aber noch zu unausgereift.

Testen?
Ich habe es bei mir mal zum testen eingerichtet. Die Resultate kann man hier ansehen. Passwort: demo.
Auch auf der offiziellen Homepage gibts es zwei Demos.

Lightbox

Heute bin ich über ein nettes JS Tool gestolpert. Nicht wirklich nötig, aber eine nette Spielerei.
Das ganze nennt sich Lightbox und damit kann man Bilder schönner anzeigen lassen. Ein kleines Beispiel auf meiner Seite. einfach auf ein Bild klicken. Damit kann man mehrere Bilder einfach ansehen, ohne immer wieder zurück auf die Ausgangsseite zu müssen.

Eingebunden ist es relativ einfach.
Man muss die folgenden JavaScript Files einbinden:
<script type="text/javascript" src="js/prototype.js"></script>
<script type="text/javascript" src="js/scriptaculous.js?load=effects"></script>
<script type="text/javascript" src="js/lightbox.js"></script>


Das CSS File:
<link rel="stylesheet" href="css/lightbox.css" type="text/css" media="screen" />


Ein Bild wird nun so dargestellt:
<a href="images/image-1.jpg" rel="lightbox" title="my caption">image #1</a>


Zudem kann man noch Gruppen machen:
<a href="images/image-1.jpg" rel="lightbox[roadtrip]">image #1</a>
<a href="images/image-2.jpg" rel="lightbox[roadtrip]">image #2</a>
<a href="images/image-3.jpg" rel="lightbox[roadtrip]">image #3</a>


Das ganze kann man auch auf der offiziellen Homepage nachlesen: Lightbox - How to use