Artikel top billede

(Foto: Computerworld)

Web 2.0 programmering - del 4

I de sidste tre afsnit i serien om prototype
har du fået et indblik i, hvordan du kan bruge JavaScript i dine
web-applikationer på nye måder. I dette sidste afsnit kommer du til at se flere
eksempler på biblioteker, der bygger ovenpå prototype og
scriptaculous.

Af Kenneth Geisshirt, Alt om Data

Denne artikel er oprindeligt bragt på Alt om Data. Computerworld overtog i november 2022 Alt om Data. Du kan læse mere om overtagelsen her.

Det er meget almindeligt at give et eller flere emneord til et objekt, for eksempel et billede. I Web 2.0 er tag clouds blevet almindelige, hvor hvert emneord kaldes et tag og, hvor det er muligt at søge på emneordene ved at klikke på dem i en oversigt. Naturligvis bruger min foto-applikation også tags, og det skal være muligt for brugeren at søge ved at klikke.

Det er ikke så svært at opbygge tag clouds, når du har prototype til din rådighed. Du har allerede set, hvordan det er muligt at reagere på museklik, og det er også, hvad der kræves denne gang.

I infoboks ”viewTags” finder du en JavaScript-funktion, som gennem et AJAX-kald henter alle tags i databasen og bygger en liste op af dem. Det er især linjen med Event.observe, der er interessant. Som du har set i tidligere afsnit, sættes et kald til en funktion op gennem et closure. Når en bruger klikker på et tag, bliver funktionen toggleTag kaldt. Du finder denne funktion i infoboks ”toggleTag”.

Funktionen toggleTag gør to ting: For det første tjekker den, om et tag allerede er valgt og slukker/tænder for en rød baggrund, hvis det henholdsvist er valgt/ikke valgt. Det er det, der er givet funktionen sit navn. Den letteste måde at gøre det på er at bruge CSS. Som du ser tilføjes CSS-klassen selected, hvis et tag vælges. Hvis tag fravælges fjernes CSS-klassen. Det er en meget lille CSS-klasse – den består kun af en rød baggrundsfarve (background-color: #FF0000).

Det andet funktionen gør er at kalde funktionen searchImages. Denne funktion er meget central i søgning i billeddatabasen. Du finder funktionen i infoboksen ”searchImages”.

I begyndelsen af funktionen searchImages findes alle de tags, som brugeren har klikket på. Et array af de valgte tags trækkes med den magiske $$-funktion. Således vil $$('.selected') give dig et array af alle elementer med CSS-klassen selected – netop som du ønsker her.

Vælg en dato

De billeder, som uploades af ejeren af foto-applikationen, påstemples en dato. Datoen er et felt i databasen sammen med filnavnet. Naturligvis skal det være muligt for de besøgende at søge efter billeder ved hjælp af datoer.

Den lette måde – for programmøren - at få en bruger til at angive et dato-interval er at bede om start- og slutdato og lade brugeren klikke på en knap. Men det er ikke særlig elegant, og med prototype er det muligt at gøre det flottere. Der findes nemlig biblioteket dateslider. Det giver en slags skydelære, hvor brugeren med musen kan flytte start- og slutdatoen.

Biblioteket dateslider kræver, at en række elementer er på plads for at virke. Det er ikke kompliceret, men djævlen gemmer sig i detaljen. For det første skal du bruge to JavaScript-filer (dataslider.js og date–en-US.js) - begge er inkluderet i den zip-fil, som du downloader. I zip-filen finder du også prototype og scriptaculous, men dem har du allerede installeret. Bibliotektet bruger en del funktioner i prototype og især scriptaculous, så du skal aktivere både drag-and-drop (dragdrop.js) og effekter (effects.js).

I html-koden skal der tilføjes en række elementer hvor dateslider kan virke indenfor. I infoboks ”Dateslider – html” finder du den del af foto-applikationens html, som sætter dateslider op. DIV-elementet med ID sliderbar er der hvor selve skydelæreren placeres. De to input-felter bruges til at gemme de valgte start- og slutdatoer. Dem vil JavaScript-funktionen searchImages bruge til at bygge søgekriterierne op med. Med dateslider følger der en større opsætning af CSS med. Mange af funktionerne i dateslider virker gennem CSS, og du kommer ikke udenom at ændre lidt i CSS-filen for at tilpasse den til din applikation. Til min applikation har jeg kun rettet en lille ting, nemlig størrelsen på DIV-elementet med ID slider-container. I CSS-filen som følger med, er bredden sat til 600 pixels, og det er i mit tilfælde al for meget (250 pixels er mere passende).

Med html og CSS på plads mangler du bare at aktivere dateslider. Det gøres ved at kalde dateslider-klassens constructor. I infoboks ”Aktivering af dateslider” finder du de få linjer JavaScript-kode, som skal bruges. Klassens constructor har seks argumenter. Det første er ID på det DIV-element, hvor skydelæreren skal placeres, mens de næste to argumenter er start- og slutdatoer for det interval, som skal vises til en begyndelse. Fjerde og femte argument er start- og slutåret, som dateslider skal vise. Det er muligt for brugeren at ”bladre” længere tilbage eller frem ved at holde venstre museknap nede mens du flytter musen. Det sidste argument er valgfri og bruges til at sætte en række egenskaber.

De to egenskaber onStart og onEnd er callback-funktioner som kaldes, når brugeren har valgt henholdsvis start- og slutdato. I min foto-applikation kaldes funktionen searchImages, som så bruger datoerne som en del af søgningen efter billeder. Personligt foretrækker jeg ISOs datoformat (for eksempel 2009-03-12 for 12. marts 2009), og det kan styres ved hjælp af dateFormat.

Den anden linje i infoboks ”Aktivering af dateslider” lader dateslider bruge de to input-felter som du finder infoboks ”Dateslider – html” til at skrive start- og slutdatoer, når brugeren har valgt dem. Disse to felter bruges af funktionen searchImages til at bygge søgningen op.

Vis billede

Når brugeren har bygget søgningen op og fundet de billeder, som interesserer ham, skal de vises. Der findes flere fine biblioteker, som kan vise billeder mere elegant ved blot ved hjælp af et IMG-tag. Til min foto-applikation har jeg valgt at bruge lightbox2. Biblioteket åbner et nyt ”vindue”, hvor billedet bliver vist. Vindue skal ikke forstås bogstaveligt, idet det ikke er et nyt vindue set fra styresystemet, men nærmere en overlejring af billedet i browserens vindue.

Dette bibliotek bruger prototype og scriptaculous' effects og builder. Endvidere følger der en CSS-fil med, som skal installeres og eventuelt tilpasses til din applikation.

Brugen af lightbox2 er ganske let. I infoboks ”searchImages” kan du se hvordan. AJAX-kaldet håndteres af den anonyme funktion i onSuccess, og hvert billede sættes ind på web-siden. Der er et A-tag med en IMG-tag indeni. A-tag bruges af lightbox2 og attributten rel fortæller at lightbox2 skal vise billedet, når der klikket på den lille udgave af det.

Afslutning

Biblioteker som prototype udnytter på elegant vis, at JavaScript adskiller sig fra andre objekt-orienterede programmeringssprog som C++ og Java. JavaScript har ikke klasser, men er baseret på prototype-objekter. Det giver mulighed for at udvide et objekt med nye metoder og egenskaber mens programmer kører.

Det giver en masse fleksibilitet for programmøren. Endvidere har JavaScript lånt en del fra funktionelle programmeringssprog (for eksempel Haskell og Lisp) med anonyme funktioner og closures.

Dette er sidste afsnit i serien om JavaScript-biblioteket prototype og et udsnit af de bibliotekter, som bygger på prototype. Med prototype er det muligt at gøre udviklingen af web-applikationer meget lettere. Det er ikke, fordi selve JavaScript-sproget eller web-browserne er blevet ændret – det hele ligger i software-biblioteker som alle web-udviklere har adgang til. Prototype har ”kolleger” i form af for eksempel jQuery og YUI. Udviklerne af disse software-biblioteker gør alt, hvad de kan, for at bibliotekerne virker med alle browsere inklusiv diverse version af Internet Explorer, Firefox, Safari og mobiltelefoner. Det tager en stor den af kompleksiteten ud af web-udvikling.

function viewTags() {
new Ajax.Request('/zphoto/tags.php', {
method: 'get',
onSuccess: function(msg) {
var tags = msg.responseText.evalJSON();
var i = 1;
tags.each(function(tag) {
var t = new Element('div', {id: 'tag-'+i});
$('tags').appendChild(t);
t.update(tag.text);
Event.observe(t, 'click', toogleTag.bindAsEventListener(this, 'tag-'+i));
i++;
});
}
});
}

toogleTag

function toogleTag() {
var args = $A(arguments);
var tag = args[1];
var css = $w($(tag).className);
if (css[0] == 'selected') {
$(tag).removeClassName('selected');
} else {
$(tag).addClassName('selected');
}
searchImages();
}

Dateslider – HTML

<fieldset class='boxed'>
<legend>Date range</legend>
<div id="slider-container">
<div id="sliderbar"></div>
</div><br />
<form>
<label for="datestart">Start:</label> <input type="text" id="datestart">
<label for="dateend">End:</label> <input type="text" id="dateend">
</form>
</fieldset>

Aktivering af dateslider

var ds = new DateSlider('sliderbar', '2009-01-01', '2009-03-01', 2008, 2009,
{onEnd: function() { searchImages(); },
onStart: function() { searchImages(); },
dateFormat: 'yyyy-MM-dd'
});
ds.attachFields($('datestart'), $('dateend'));

Infoboks – searchImages
function searchImages() {
var selected = $$('.selected');
var tags = new Array();
selected.each(function(t) {
tags.push(t.innerHTML);
});
var dates = new Array();
dates.push($F('datestart'));
dates.push($F('dateend'));
new Ajax.Request('/zphoto/search.php', {
method: 'get',
parameters: {
tags: tags.toJSON(),
caption: $F('caption'),
date: dates.toJSON()
},
onSuccess: function(msg) {
$('images').innerHTML = '';
var images = msg.responseText.evalJSON();
var i = 1;
images.each(function(image) {
var img = new Element('img', {id: 'image-'+i, src: '/zphoto/img/'+image.filename, width: '100px'});
var a = new Element('a', {href: '/zphoto/img/'+image.filename, rel: 'lightbox'});
a.appendChild(img);
var li = new Element('li');
li.appendChild(a);
$('images').appendChild(li);
i++;
});
}
});
}

[themepacific_accordion]
[themepacific_accordion_section title="Fakta"]

Få mere at vide

[/themepacific_accordion_section]
[themepacific_accordion_section title="Fakta"]

Firebug og FireScope

[/themepacific_accordion_section]
[/themepacific_accordion]