Table of Contents
-
1. Elementen selecteren.
- 1.1 Basis selectors.
- 1.2 Hiërarchische selectors.
- 1.3 Basisfilters.
- 1.4 Inhoudsfilters.
-
1.5 Attribuut selectors.
-
1.5.1 Attribuut bestaat
[name]
. -
1.5.2 Attribuut is gelijk aan
[name="value"]
. -
1.5.3 Attribuut is niet gelijk aan
[name!="value"]
. -
1.5.4 Attribuut begint met
[name^="value"]
. -
1.5.5 Attribuut eindigt op
[name$="value"]
. -
1.5.6 Attribuut bevat
[name*="value"]
. -
1.5.7 Attribuut bevat meerdere filters
[filter1][filter2]
.
-
1.5.1 Attribuut bestaat
-
1.6 Childfilters.
- 1.6.1 Eerste child element :first-child.
- 1.6.2 Laatste child element :last-child.
- 1.6.3 Eerste sibling element binnen dezefde parent :first-of-type.
- 1.6.4 Laatste sibling element binnen dezefde parent :last-of-type.
- 1.6.5 Het n-de child elementen.
- 1.6.6 Het enige child element :only-child().
- 1.6.7 Het enige child element van dat type binnen dezefde parent :only-of-type().
- 1.7 Formulierfilters.
- 1.8 Zichtbaarheidsfilters.
- 1.9 Toepassing 1: gemeentelijst filteren (basisversie).
- 1.10 Toepassing 2: openingsuren markeren.
- 2. Inleiding tot AJAX.
1. Elementen selecteren.
Een jQuery statement bestaat steeds uit twee of meer delen. Het eerste deel is altijd een selector. De volgende delen beschrijven de acties die u op de selector uitvoert.
Een voorbeeld:
-
$('p.foo')
: selecteer alle p-tags met het class-attribuut .foo. -
.addClass('bar')
: voeg aan deze selectie de class .bar toe. -
.show('slow');
en maak de selectie zichtbaar.
Een goede selectie maken is bijgevolg cruciaal om een krachtig script uit te voeren.
JavaScript kent een zeer beperkte set aan selectors.
U kan bijvoorbeeld een bepaald id (document.getElementById(id)
) of een bepaalde tag opvragen (document.getElementByTagName(tag)
), maar wat als u de derde rij in een tabel wilt ophalen of alle links met een externe URL? Dit is onmogelijk met één commando.
Dit hoofdstuk beschrijft de belangrijkste selectiemethodes binnen jQuery. De syntax is eenvoudig. Deze volgt immers de selectiemethodes van CSS3, aangevuld met enkele jQuery-specifieke selectiemethodes.
De voorbeelden die volgen, kan u uittesten op het oefenbestand selectorTest.html.
Geef in het tekstveld een selectie in (bv: p#paragraaf1). Het script op de pagina gaat op zoek naar de selectie en voegt aan de selectie de class .highLight toe. Deze class tekent een groen kader rond de selector, maakt de achtergrond geel en kleurt de tekst rood.

Een overzicht van de verschillende selectors vindt u hier:
http://api.jquery.com/category/selectors/basic-css-selectors/
1.1 Basis selectors.
Zie: http://api.jquery.com/category/selectors/basic-css-selectors/
1.1.1 Tags, classes en id’s.
Volgende voorbeelden gebruikt u waarschijnlijk dagelijks in CSS:
1.1.2 Universele selector.
Het sterretje is, net zoals in CSS, de universele selector voor alle tags.
1.2 Hiërarchische selectors.
Zie: http://api.jquery.com/category/selectors/hierarchy-selectors/
Hiërarchische selectors kan u best vergelijken met een stamboom. Bekijk in onderstaande code hoe de tags in elkaar genest zijn.
<table
class=
"layoutTabel"
>
<thead>
<tr>
<th>
Opleiding:</th>
<th>
Datum:</th>
<th>
Lokaal:</th>
</tr>
</thead>
<tbody>
<tr>
<td>
Dreamweaver</td>
<td>
15 december</td>
<td>
PC1</td>
</tr>
</tbody>
</table>
De hiërarchische selectors zijn:
- Parent en child
-
Parent en child zijn geneste tags op het eerste niveau.
De thead-tag en de tbody-tag staan rechtstreeks onder de table-tag en gedragen zich in een parent-child relatie.
table is een parent van thead of
thead is een child van table. - Siblings
-
Siblings (broers of zussen) zijn elementen die op gelijk niveau staan.
De drie td-tags binnen een tr-tag zijn siblings van elkaar. - Ancestor (voorouder)
- Een ancestor kan de parent zijn, maar ook de parent van de parent, of nog een verdere relatie.
th heeft als parent tr.
th heeft als ancestor tr, maar ook thead, table en body. - Descendant (nakomeling)
- Een descendant kan een child zijn, maar ook een child van een child of nog een verdere relatie.
table heeft als child thead en tbody.
table heeft als descendant thead, tbody, maar ook tr, th en td.

1.2.1 Descendant selector: $(‘ancestor descendant’).
1.2.2 Child selector: $(‘parent > child’).
(*) Merk op dat in ons voorbeeld geen enkele td-tag rechtstreeks onder de table-tag staat. Er wordt dus niets geselecteerd!
1.2.3 Sibling selector (alle volgende) : $(‘prev ~ sibling’).
1.2.4 Sibling selector (dadelijk aangrenzende): $(‘prev + next’).
In het laatste voorbeeld worden paragraaf2 en paragraaf3 niet geselecteerd. Tussen paragraaf 1 en paragraaf 2 staat immers nog een lijst.
1.3 Basisfilters.
Zie : http://api.jquery.com/category/selectors/basic-filter-selectors/
De selectors die we tot hiertoe hebben besproken, selecteren telkens een volledig element.
$('tr')
selecteert bijvoorbeeld alle tr-tags in een tabel.
Stel dat we nu enkel de even of oneven rijen in een tabel wensen te selecteren, dan doen we dit aan de hand van filters. Een filter is als het ware een subselectie binnen een hoofdselectie. Alle filters worden met een dubbelpunt als prefix aangeduid. Voor de oneven rijen (rijen met index 1, 3, …) in een tabel wordt dit: $('tr:odd')
.
Bij sommige filters moet u eveneens een index meegeven. Het eerste element heeft de index 0. Om bijvoorbeeld de derde rij binnen een tabel te selecteren, geeft u als index de waarde 2 mee $('tr:eq(2)')
.
1.3.1 Subselecties binnen een reeks.
1.3.2 Inverse subselecties binnen een reeks met :not().
1.3.3 Overige subselecties.
(De drie laatste selectors kan u niet op het oefenbestand testen.)
1.4 Inhoudsfilters.
Zie : http://api.jquery.com/category/selectors/content-filter-selector/
Deze filters testen op de inhoud (tekst of html) binnen een bepaald element.
1.4.1 Het element bevat een bepaalde tekst :contains().
De tekst is hoofdlettergevoelig, maar de aanhalingstekens zijn niet verplicht.
contains("PC")
is NIET hetzelfde als contains("pc")
.
contains("PC")
is WEL hetzelfde als contains(PC)
.
1.4.2 Het element bevat een bepaald element :has().
1.4.3 Lege (:empty) of niet lege (:parent) elementen.
1.5 Attribuut selectors.
Vanuit CSS kan u elementen selecteren op basis van hun attribuut. Ook deze eigenschap werd door jQuery overgenomen. Bekijk de broncode van het oefenbestand. Neem bijvoorbeeld een afbeelding. Alle afbeeldingen hebben natuurlijk een src-attribuut en een alt-attribuut. Sommige afbeeldingen hebben ook het title-attribuut.
Zie : http://api.jquery.com/category/selectors/attribute-selectors/
1.5.1 Attribuut bestaat [name]
.
We kunnen een selectie nog verder verfijnen door de waarde of inhoud van het attribuut te controleren.
1.5.2 Attribuut is gelijk aan [name="value"]
.
1.5.3 Attribuut is niet gelijk aan [name!="value"]
.
1.5.4 Attribuut begint met [name^="value"]
.
1.5.5 Attribuut eindigt op [name$="value"]
.
1.5.6 Attribuut bevat [name*="value"]
.
1.5.7 Attribuut bevat meerdere filters [filter1][filter2]
.
1.6 Childfilters.
Een childfilter selecteert het n-de element binnen het parent element.
Zie : http://api.jquery.com/category/selectors/child-filter-selectors/
1.6.1 Eerste child element :first-child.
1.6.2 Laatste child element :last-child.
1.6.3 Eerste sibling element binnen dezefde parent :first-of-type.
1.6.4 Laatste sibling element binnen dezefde parent :last-of-type.
1.6.5 Het n-de child elementen.
De index start hier vanaf 1 en niet vanaf 0!
De letter n staat voor een geheel getal (0, 1, 2, 3, …).
1.6.6 Het enige child element :only-child().
1.6.7 Het enige child element van dat type binnen dezefde parent :only-of-type().
1.7 Formulierfilters.
Zie : http://api.jquery.com/category/selectors/form-selectors/
Filtert formulierelementen van een bepaald type of met een bepaald attribuut.
1.7.1 De type-selector (button, submit, reset, checkbox, …).
1.7.2 Overige attributen (:checked, :disabled, :enabled en :selected).
Met :checked
en :selected
selecteert u enkel het element, maar haalt u de gekozen waarde nog niet op. De methodes om deze waardes uit te lezen, komen later aan bod.
1.8 Zichtbaarheidsfilters.
Zie : http://api.jquery.com/category/selectors/visibility-filter-selectors/
1.9 Toepassing 1: gemeentelijst filteren (basisversie).

De pagina bevat een lijst van alle Vlaamse gemeenten.
Het zoekveld bovenaan de pagina filtert de lijst met gemeentenamen.
<body>
...
<input
type=
"text"
name=
"filter"
id=
"filter"
...
"
>
...
<ul>
<li><a
...
>
Aalst</a></li>
<li><a
...
>
Aalter</a></li>
<li><a
...
>
Aarschot</a></li>
<li><a
...
>
Aartselaar</a></li>
</ul>
...
</body>
1
$
(
function
()
{
2
$
(
'#filter'
).
keyup
(
function
(){
3
var
filter
=
$
(
this
).
val
();
4
$
(
'li'
).
hide
();
5
$
(
'li:contains('
+
filter
+
')'
).
show
();
6
});
7
});
Telkens u in het tekstveld een letter intypt, wordt het event keyup()
geactiveerd. De waarde uit het tekstveld komt in de variabele filter terecht.
Indien u bijvoorbeeld ka invult, wordt getest of dit woord binnen een li-tag voorkomt. De selectoren op lijn 4 en 5 bepalen of de li-tag zichtbaar of onzichtbaar wordt.
Merk op dat op lijn 5 de variabele dynamisch in de selector wordt verwerkt. Voor het zoekwoord ka wordt dit: $('li:contains(ka)').show();

1.10 Toepassing 2: openingsuren markeren.

De pagina bevat twee tabellen waarop we de openingsuren van vandaag markeren. Elke weekdag komt overeen met één rij binnen de tbody-tag. Merk op dat we de tabel ook starten met zondag. Dit is een bewuste keuze omdat we het rijnummer dan makkelijk kunnen koppelen aan de weekdag van het Date-object.
<table
class=
"layoutTabel"
>
<thead>
...</thead>
<tbody>
<tr>
<td><strong>
Zondag</strong></td>
<td>
Gesloten</td>
<td>
Gesloten</td>
<td>
Gesloten</td>
</tr>
...
</tbody>
</table>
1
$
(
function
()
{
2
var
vandaag
=
new
Date
();
3
var
dag
=
vandaag
.
getDay
();
4
$
(
'tbody tr:nth-child('
+
(
dag
+
1
)
+
')'
).
addClass
(
'nu'
);
5
});
Op lijn 3 halen we de weekdag op. (zondag = 0, maandag = 1, …). Vervolgens gaan we op lijn 4 dit getal met één verhogen om zo de juiste rij binnen tbody te markeren met de class .nu.
2. Inleiding tot AJAX.
Alle moderne websites maken tegenwoordig gebruik van AJAX. Denk maar aan Gmail, Google Drive, Facebook en Twitter.
In tegenstelling tot een klassieke webpagina worden bij AJAX-gestuurde pagina’s delen van de pagina ververst zonder de volledige webpagina opnieuw in te laden. De pagina’s worden hierdoor veel interactiever en intuïtiever. De gebruiker krijgt meer het gevoel dat hij in een desktopapplicatie werkt dan op een website. Websites die hoofdzakelijk gebruik maken van AJAX noemt men ook wel Rich Internet Applicaties of RIA’s.
AJAX is geen technologie op zich, maar een algemene term voor het ontwerpen van interactieve pagina’s waarbij gegevens uit een extern bestand worden opgehaald en vervolgens dynamisch worden getoond. Het grote voordeel van AJAX t.o.v. uitsluitend klassieke webpagina’s is dat alle gegevens dynamisch in de browser worden geladen. Alle interactiviteit (sorteren, filteren, …) gebeurt dus volledig binnen de browser zonder dat er een nieuwe connectie met de server nodig is.
De communicatie binnen een klassieke website gebeurt als volgt:
- De browser laadt een pagina.
- De gebruiker klikt op een link.
- De browser vraagt een volledig nieuwe pagina op.
- De webserver stuurt de nieuwe pagina naar de browser.
- De browser toont de nieuwe pagina.
De communicatie met een AJAX-pagina verloopt als volgt:
- De browser laadt een pagina.
- De gebruiker klikt op een link.
- De JavaScript engine verwerkt de aanvraag en stuurt de aanvraag in de achtergrond door naar een externe pagina.
- De JavaScript engine ontvangt de gegevens en past het DOM aan.
- De browser toont de nieuwe gegevens en hoeft daarvoor niet de volledige pagina te herladen.
Omdat de browser minder met de webserver communiceert en omdat de verwerking volledig lokaal gebeurt, krijgen we een zeer snelle respons en een snelle pagina update.
In dit hoofdstuk geven we een korte inleiding tot AJAX en verduidelijken we enkele begrippen. De oefeningen komen in de twee volgende hoofdstukken aan bod.
Een volledig overzicht van alle AJAX-methodes vindt u hier:
http://api.jquery.com/category/ajax/
2.1 Historiek.
De techniek om asynchroon gegevens op te halen, bestaat al meer dan 20 jaar. In 1998 ontwikkelde Microsoft een systeem om via een ActiveX control gegevens in de achtergrond op te halen. Enkele jaren later implementeerden alle andere browsers een gelijkaardig principe, maar nu gebaseerd op het gestandaardiseerde XMLHttpRequest protocol (kortweg XHR).
Google was het eerste bedrijf dat XHR op grote schaal in zijn toepassingen ging verwerken. In de beginjaren kwamen de externe gegevens uitsluitend uit een XML-document. Zo is de term AJAX ontstaan. AJAX was het acroniem voor Asynchronous JavaScript And XML.
Ondertussen is de omschrijving van AJAX al achterhaald. Via AJAX kunnen we niet enkel XML importeren, maar eveneens tekst, HTML, JSON en JavaScript.
Het is niet zo evident om op een universele manier AJAX te verwerken. De ene browser gebruikt XHR, de andere ActiveX. Gelukkig hoeven wij ons hier geen zorgen over te maken. jQuery zorgt immers voor een correcte verwerking in de verschillende browsers.
2.2 Wat is XML?
XML is het acroniem voor eXtensible Markup Language. Net zoals HTML, beschrijft XML de datastructuur van gegevens, niet de opmaak. Een XML-document is, net zoals HTML, opgebouwd met tags (nodes in het XML jargon) en attributen.
Neem als voorbeeld een adresboek in de vorm van een XML-document.
XML begint steeds met de header of proloog. De proloog bevat informatie over de document encoding en de XML versie. Dit is ondermeer belangrijk voor het programma dat de XML-code gaat verwerken (de XML-parser). Na de proloog volgt de rootnode adresboek.
Ons adresboek bevat twee personen. Elke persoon staat beschreven in een eigen adresnode met als attribuut een uniek id. Binnen de adresnode komen de childnodes: voornaam, naam en email.
<?xml version="1.0" encoding="UTF-8"?>
<adresboek>
<adres
id=
"1"
>
<voornaam>
Lorem</voornaam>
<naam>
Ipsum</naam>
<email>
lorem@example.com</email>
</adres>
<adres
id=
"2"
>
<voornaam>
Morbi</voornaam>
<naam>
Dui</naam>
<email>
morbi@example.com</email>
</adres>
<adres
id=
"3"
>
... </adres>
</adresboek>
Een goed gestructureerd XML-document is zelfbeschrijvend. Dit wil zeggen dat nodenamen iets vertellen over de inhoud van de node.
Als het document voldoet aan alle syntaxregels van XML, noemt men dit well-formed (of goed gevormd). Een well-formed document kan door de meeste parsers, zoals een webbrowser, correct verwerkt worden.
Een well-formed document kan u makkelijk in Firefox of in Chrome testen. Open het XML-document in de browsers. Als de boomstructuur verschijnt, is het document well-formed en zijn de gegevens te verwerken via jQuery.

Indien het document fouten bevat, is het niet well-formed en krijgt u dit te zien:

In een XML-document dat uitsluitend voor eigen gebruik is ontworpen, kan u de nodenamen vrij kiezen. In een universeel, gestandaardiseerd XML-document zoals RSS, ATOM en XHTML ligt de naamgeving vast.
Om de correctheid van het document te controleren, maakt men gebruik van een DTD of van een XML Schema.
Een DTD of XML schema documenteert als het ware het XML-bestand. Hierin wordt ondermeer beschreven welke nodes in het XML-document moeten/mogen voorkomen en welke inhoud de nodes bevatten (tekst, enkel getallen, …). Aan de hand van dit controlebestand kan de parser de XML-nodes zowel op syntax als op inhoud valideren.
Een well-formed XML-bestand dat ook nog voldoet aan de bijbehorende DTD of Schema, noemt men een valid XML-bestand.
2.3 Wat is JSON?
JSON is het acroniem voor JavaScript Object Notation. JSON beschrijft, net zoals XML, de datastructuur van gegevens. JSON is een onderdeel van JavaScript, en is bijgevolg relatief eenvoudig in het DOM te verwerken.
De eenvoud van JSON heeft geleid tot een grote populariteit ervan, met name als een alternatief voor XML. Binnen JSON staan gegevens gestructureerd in de vorm van een JavaScriptobject of als een JavaScript array.
Ziehier een JSON equivalent van ons XML adresboek.
{
"adresboek"
:
[
{
"id"
:
1
,
"voornaam"
:
"Lorem"
,
"naam"
:
"Ipsum"
,
"email"
:
"lorem@example.com"
},
{
"id"
:
2
,
"voornaam"
:
"Morbi"
,
"naam"
:
"Dui"
,
"email"
:
"morbi@example.com"
},
{
...
}
]
}
- Goed: “voornaam”:”Lorem”
- Fout: voornaam : “Lorem”
- Fout: ‘voornaam’ : “Lorem”
- Fout: ‘voornaam’ : ‘Lorem’
2.4 Requests filteren met GET en POST.
Het is perfect mogelijk om gegevens (HTML, JSON, XML, …) te verwerken uit een volledig statisch document. Het wordt natuurlijk nog interessanter indien we de gegevens dynamisch vanuit een database kunnen genereren. Vanuit een statische pagina is de response altijd hetzelfde. Op een dynamische pagina is de response afhankelijk van een filter of parameter. Het filteren gebeurt meestal vanuit een formulier.
Neem bijvoorbeeld de zoekfunctie van Google. De response is afhankelijk van de zoekterm die u in het formulier invult.
Zoals u weet, kan u een formulier verzenden via GET of via POST.
2.4.1 Formulier verzenden met de GET-methode.
GET plakt alle formuliervelden achter de URL. Alle zoekmachines gebruiken GET.
Zoek via Google op jquery tutorials en bekijk de URL.
De structuur van de URL met een GET-request is als volgt:
action?naam1=waarde1&naam2=waarde2&naam3=waarde3
Action is de URL van de pagina die het formulier zal verwerken. Van elk formulierveld wordt zowel de naam van het veld als de waarde in het veld aan de URL toegevoegd. Alle velden zijn gescheiden door een &-teken.
Omdat GET de waarde of de inhoud van elk object zichtbaar maakt in de URL, kan u deze methode bijvoorbeeld niet gebruiken op een loginpagina. Het paswoord mag immers niet zichtbaar zijn in de URL. De lengte van de URL is ook beperkt tot enkele honderden karakters (browserafhankelijk).
2.4.2 Formulier verzenden met de POST-methode.
De tweede methode, POST, geeft de gegevens via de header door. De gegevens zijn nu niet zichtbaar in de URL. Het aantal karakters dat kan worden doorgestuurd, is vrijwel onbeperkt.
2.4.3 GET-methode zonder formulier.
Omdat de GET-methode alle parameters achter de URL plaatst, is het perfect mogelijk om de parameters dadelijk in een link te verwerken. Dit wordt vaak gebruikt in een master/detail relatie.
De masterpagina toont een beknopt overzicht van alle items. Elk item heeft een link naar de detailpagina en stuurt in de URL een unieke identificatiecode mee.
Neem als voorbeeld de startpagina van Campinia Media.

Elke link “Lees verder” verwijst naar dezelfde detailpagina:
http://www.campiniamedia.be/fondslijst_detail.asp?
ISBN=xxxxxx
De parameter ISBN filtert de juiste gegevens uit de database en toont de gedetailleerde informatie over het gevraagde boek.
2.5 Zes soorten AJAX requests.
De methode $.ajax()
is een jQuery’s low-level AJAX implementatie. Dit is tevens de meest uitgebreide, maar ook moeilijkste methode.
Gelukkig zijn er ook nog vijf afgeleide methodes met minder toeters en bellen, maar wel veel eenvoudiger te begrijpen en te gebruiken. Onderstaande tabel geeft een overzicht van de verschillende methodes met hun mogelijkheden en beperkingen.

Zonder webserver kan u enkel koppelen met statische bestanden. Om gegevens uit een database te verwerken, zal u altijd een server-side script moeten gebruiken en bent u natuurlijk wel verplicht om een webserver te gebruiken.
Omdat niet iedereen vertrouwd is met server-side scripts (PHP, ASP.NET, …) gaan we de oefeningen dadelijk opsplitsen over twee verschillende hoofdstukken.
2.6 Same origin policy.
Uit veiligheidsredenen bevatten alle browsers enkele beperkingen. Eén van deze beperkingen is de same origin policy. Of, met andere woorden, alle gegevens die u via AJAX ophaalt, moeten afkomstig zijn van hetzelfde domein. Hetzelfde domein betekent meer specifiek: dezelfde server, zelfde protocol, zelfde domeinnaam en dezelfde poort. Het is bijvoorbeeld niet mogelijk dat een webpagina op domeinA gegevens ophaalt uit domeinB.
Er zijn echter twee uitzonderingen. Het ophalen van externe JavaScripts en gegevens in JSONP formaat (let op de P achteraan) zijn wel toegestaan.
JSONP staat voor “JSON with Padding”. Wanneer de webserver van domeinB zodanig staat geconfigureerd dat deze toelaat dat andere gebruikers zijn gegevens in JSON-formaat mogen ophalen, spreekt men van JSONP. De structuur van een JSON-bestand en van een JSONP-bestand is identiek.
Onderstaande afbeelding toont de AJAX mogelijkheden/beperkingen, rekening houdend met de same origin policy.

2.7 Cross-site scripting.
Indien u over een webserver beschikt, kan u de same origin policy makkelijk omzeilen. Op de webserver plaatst u een proxyscript. Dit proxyscript haalt de inhoud van een externe pagina (html, XML, JSON, …) op en toont dit in zijn eigen pagina.
In plaats van in een AJAX request te verwijzen naar de externe pagina, verwijst u nu naar de proxypagina. Voor de browser lijkt het alsof de gegevens afkomstig zijn van het eigen domein. Op deze manier kunnen we dus alle externe gegevens perfect via AJAX verwerken. Hierover later meer.
