Kop 1

tagline

Link naar de presentatie

JSON is een manier om objecten in een string op te slaan en wordt veel gebruikt om data uit te wisselen.
In deze reeks

Leerdoelen

  • opfrissen van vaardigheden met array's in JavaScript;
  • opfrissen van asynchrone processen in JavaScript;
  • opfrissen van werken met objecten in JavaScript.
  • werken met template-literals

Bron

Een aan te vullen JSON-bestand: https://gist.github.com/Theo-denBlanken/ed9551298618eb05ad01b838b3bf32b5

Opdracht

  1. Gebruik het voorbeeld bestand: https://gist.github.com/Theo-denBlanken/ed9551298618eb05ad01b838b3bf32b5
  2. Vul dit aan met minstens een eigen boek naar keuze
  3. In plaats van alle bovenstaande punten mag je ook een lijst met objecten en eigenschappen maken die je helamaal zelf bedenkt: denk aan CD's, films, favourite YouTube filmpjes

Data uit JSON stap: 1 JSON data aanvullen (00:08:36)

We halen het JSON bestand met gegevens van boeken op bij https://gist.github.com/Theo-denBlanken/ed9551298618eb05ad01b838b3bf32b5 JSON is een notatie waarbij objecten worden teruggebracht tot een string.
Daar zijn wel 'objecten' aan te wijzen, in ons geval boeken.
Elk boek heeft een titel, maar voor sommigen begint het eerste woord niet kernachtige genoeg om op te sorteren. Daarom wordt dat deel ervoor in een eigenschap 'voortitel' ondergebracht.
Daarnaast zijn er eigenschappen als de afbeelding van het omslag, de prijs, taal , ean en aantal bladzijden.
Elk boek heeft en auteur met voornaam en achternaam en soms ook een tussenvoegsel.
Deze komen weer los als eigenschappen van auteur gestructureerd.
Omdat er ook boeken zijn met meerdere auteurs, worden alle auteurs weer in array geplaatst bij de eigenschap auteurs.

Data uit JSON stap: 2 JSON binnenhalen (00:12:12)

In een JavaScript, dat aan een webpagina is gekoppeld, willen we het JSON-document naar binnen halen en tot een object omzetten. We hebben daarbij een asynchroon proces.
Het script loopt in hoog tempo alle opdrachten in het script af, maar het binnenhalen van de data kost tijd. Pas na dat binnenhalen kan het worden verwerkt.
Na binnenkomst is er als het ware een melding, die het script vertelt dat er nu vanaf dat punt verder gewerkt kan worden.
We maken daarvoor een XMLHttpRequest-object aan.
Het onreadystatechange event controleert of de readyState van het object 4 is en de state van dit object 200 is. Dan kan de opdracht gegeven worden de responseText uit te voeren.
Om de request uit te voeren roepen we de .open()-method aan van dit object. Deze methode heeft 3 argumenten: "GET", de url van het JSON-bestand en een boolean, die aangeeft of het een asynchroon verzoek is. Dat is bij ons dus true.
Met de .send()-method wordt de request verstuurd en gaat het proces van contact zoeken en data-uitwisseling beginnen.

Om het a-synchrone karakter te laten zien, wordt er voor even een console-opdrachtje gegeven als laatste opdracht in het script. Deze blijkt dan toch als eerste uitgevoerd te worden.
Ook kun je console-opdrachten geven voor het geval de readyState nog niet 4 is en de status nog niet 200 is.
Als je er een positief resultaat is, kun je de data met JSON.parse() omzetten naar een echt JavaScript object.
In de console kun je ten slotte zien dat het een object is geworden.

Data uit JSON stap: 3 boektitels uitvoeren (00:11:05)

We maken in JS een boeken-object aan.
Die krijgt een method uitvoeren, die ervoor zorgt dat de gegevens van het object worden weergegeven in de pagina.
Het boekenobject krijgt ook een data-eigenschap, die het resultaat van de import van de JSON bevat.
Met this.data kan elke method of property in het boekenobject naar deze data-eigenschap verwijzen.
De uitvoeren-method moet elke boek van de data-property langsgaan voor de uitvoer. Dat doet hij met een for-lus ons geval een forEach().
Maak daarin een variabele html (of een andere naam natuurlijk) wordt in de lus de titel gehaald en aan met template literals (backticks) maak je een stukje html waarin je een eigenschap van het boek-object tussenvoegt.
Op het eind van de lus heb je dus een grote html-string, die je met .innerHTML uitvoert in de webpagina.
De zo verkregen titels zijn in sommige gevallen niet compleet: de 'voortitels' ontbreken nog.

Data uit JSON stap: 4 boektitels aanvullen en op GitHub posten (00:08:36)

Om de de titel compleet te maken gaan we in de forEach eerst een variabele titel maken.
Met en conditional ga je na of er een voortitel is, en je voegt die dan met een spatie toe aan deze variabele.
In dezelfde lus voeg je de altijd aanwezige boek-titel daar ook aan toe en zo heb je de complete titels.
Deze voeg je dan toe in uitvoer plaats van de eerder gebruikte titel-porperty van het object. Tussenresultaat commit je vast op GitHub.

Data uit JSON stap: 5 covers toevoegen (00:12:09)

Vergelijkbaar met de titels worden nu de afbeeldingen van de covers toegevoegd.
Met gebruik van template-literals schrijf je in de lus voor elk boek het img-element en je voegt de waarden voor de alt in met de titel.
Het src-attribuut krijgt de property cover vanuit de data-property van het boeken-object.
Vervolgens wordt er html- gegenereerd om elk boek een eigen section te geven met de class boek.
Als je de BEM conventie wil gebruiken, geef je het afbeeldingselement de class boek__cover of iets dergelijks.
De CSS wordt aangemaakt en de afmetingen van de covers beperkt. Een maximale breedte van 200px zal een beter resultaat geven dan in de video.
Om de informatie naast de cover te plaatsen geven we de covers een float: left; en om te voorkomen dat de navolgende boeken ernaast komen de sections een clear: left;

Data uit JSON stap: 6 andere meta-data toevoegen (00:10:00)

Door in de lus meer template-literals toe te voegen, kun je vanuit het data-object nog meer informatie toevoegen aan het boek.
Voorlopig werken we aan de weergave voor desktop. Omdat we span-elementen genereren komen de elementen vanzelf op dezelfde regel.
Met CSS kun je met de ::after pseudo-selector ook een scheidingsteken tussen deze elementen plaatsen.

Data uit JSON stap: 7 prijs toevoegen en kop stijlen (00:05:36)

De prijs kan in een aparte div worden toegevoegd, weer met template literals en gebruik van de data in het object.
De kop krijgt ook de passende classnaam naar BEM conventie en kan op 1 lijn worden gebracht met de bovenzijde van de cover.
Er blijven nog wel wensen over betreffende de formattering van de uitgave-datum, de prijs en nog het toevoegen van de auteur(s).

Data uit JSON stap: 8 auteurs toevoegen (00:12:33)

In het data-object is bij elk boek een array van auteurs toegevoegd. Om deze uit te voeren, moet binnen de lus opnieuw een lus worden doorlopen, die alle auteurs uitvoert.
Elke auteur in die array is een object, met eigenschappen als voornaam en achternaam.
Opnieuw kan met template-literals die in de goede volgorde en met een spatie worden uitgevoerd.
Er zijn echter ook auteurs, die een tussenvoegsel hebben.
Met de ternary operator (een verkorte if-conditional) wordt opgevraagd of dat tussenvoegsel er is en in dat geval wordt deze met een spatie in een variabele gestopt. anders blijft de variabele leeg:
let tv = schrijver.tussenvoegsel ? schrijver.tussenvoegsel+" " : "";
Deze variabele wordt in de uitvoer van de auteur meegenomen.

Daarnaast moet in de opsomming van de auteurs een tussenruimte worden gemaakt in ons geval voorlopig even een spatie. Tot slot is het alweer hoog tijd een commit te maken in onze versiebeheer op GitHub.

Data uit JSON stap: 9 het scheidingsteken tussen meerdere auteurs (00:05:07)

Als er een aantal auteurs uit de array wordt uitgevoerd bij een boek, dan zou het scheidingsteken het beste een komma kunnen zijn.
Doen we dat dan wordt er ook achter de laatste (of enige) auteur een komma geplaatst.
In de forEach() kunnen we ook 2 parameters meegeven, waarbij de tweede een index is.
Je kunt dan in de statements een conditional plaatsen die kijkt of de index groter of gelijk is aan het aantal auteurs -1 (de index begint te tellen bij 0).
In dat geval is het scheidingsteken een lege string.
Vergelijkbaar een conditional bij de voorlaatste auteur waarbij het scheidingsteken " en " gewenst is. Plaats deze voor de vorige conditional.

Data uit JSON stap: 10 weergave van prijzen (00:02:45)

De prijs, die uit de data komt is een getal. Die wordt als prijs niet correct weergegeven.
We wensen een uitvoer in 2 decimalen en de komma voor die decimalen.
Om het getal naar de juiste string om te zetten zit in JavaScript de method .toLocaleString().
We voeren daar in dat het Nederlands is zowel qua taal als land en wat het geld-symbool is en hoe dat wordt geplaatst.
Op https://www.freeformatter.com/netherlands-standards-code-snippets.html#currencyformats vinden we daarvoor de de method
.toLocaleString('nl-NL', {currency: 'EUR', style: 'currency'});
Merk op dat deze 2 argumenten heeft: de string met taal-land en het object met munt en styling van de munt.
Het euroteken wordt hier automatisch ook aan toegevoegd, zodat onze gemaakte euro nu teveel is.

Data uit JSON stap: 11 datum formatteren (00:11:21)

De uitvoer geeft de datum maar de gebruiker wenst liever de naam van de maand uitgevoerd te krijgen voor het jaar van uitgave.
We maken een method binnen het boeken-object en zetten de maand en het jaar in variabelen.
Deze maand en jaar geven we dan in omgekeerde volgorde terug.
Je ziet hier weer dat we een method in een object kunnen aanroepen met het this-keyword.
Ook maken we een method, die van een maand het nummer naar een naam omzet via een switch.

Data uit JSON stap: 12-pre: resultaat van filteren (00:00:51)

Een impressie van de mogelijkheid als je de data uit het object kunt filteren.
Dit wordt in de komende 3 filmpjes voorgedaan.

Data uit JSON stap: 12 filteren (00:10:58)

Arrays en objecten kennen een filter-methode. Documentatie op https://www.codegrepper.com/code-examples/javascript/how+to+filter+object+in+javascript. In het algemeen is de vorm:
nweArr = arr.filter((obj) => { return obj.eigenschap == 'waarde'} ) Dit wordt in onze boeken toegepast op de taaleigenschap.
Het filteren vind plaats voordat er wordt uitgevoerd.
Het wordt een method binnen ons object en de ingevoerde array is het resultaat van de omgezetten JSON. We kiezen telkens 1 taal waarop we het filter laten werken.
De nieuwe array is een property binnen ons object.

Om dit straks flexibeler te maken maken we ook en property in ons object waar de taal in staat waarop we filteren.

Data uit JSON stap: 13 meer talen filteren (00:09:15)

Door de vergelijkende functie in het filter voor meerdere talen geschikt te maken kunnen we voor meer dan 1 taal filteren.
Het taalfilter wordt dan geen string maar een array.
In de vergelijking doorlopen we dan het array en vergelijken bij het boek of hij aan 1 van de talen uit de array voldoet.
In dat geval moet het filter een true geven. We doen dat met een conditional in een forEach-loop.

Data uit JSON stap: 14 gebruiker laten filteren (00:17:11)

Het script kan filteren op meerdere talen. We brengen nu de checkboxes aan waarmee de gebruiker kan aangeven welke talen hij wenst.
daarvoor maken we een div aan en de labels en checkboxen daarbinnen worden volgens BEM conventie van classs-namen voorzien.
Daarmee zijn ze ook door het script in een node-list te stoppen.

Met een forEach() geven wel elk element een event-listener die reageert op de verandering van één van de checkboxen. Dan wordt er een functie aangeroepen die de taaleigenschappen-property moet aanpassen in ons boekenobject.
Deze functie maakt eerst een leeg array en gaat alle checkboxes na in de DOM.
als deze gecheckt staat wordt de value toegevoegd aan de array.
Na het doorlopen wordt array van de taaleigenschap overschreven door de gemaakte array.
Hierna roepen we de filter- en uitvoer-methods nog een keer aan om de nieuwe filtering toe te passen.
De filter-functie gebruikt de JSON-geparste object uit de responseText van het XMLHTTPRequest.

Data uit JSON stap: 15 sorteren (00:10:49)

Arrays van objecten kun je in JavaScript heel goed sorteren met de .sort() method.
Probeer dit eerst uit met een eenvoudig object in de console. Kopieer vanaf: http://bla.hosts1.ma-cloud.nl/blog/een-array-van-objecten-sorteren-op-een-object-eigenschap/
Vervolgens gaan we dat toepassen op de titel-eigenschap van onze boeken.
Dit blijkt voor een groot deel te lukken en het is duidelijk waarom we de titel hebben gesplitst in een titel- en een voortitel eigenschap. Dat geeft hier het gewenste resultaat.
Omdat de .sort()-method de teksten in ASCII (zie: http://www.asciitabel.be/) blijkt dat alle titels zonder hoofdletter onderaan komen.
Om dit op te lossen moet in de vergelijking van het sorteren de titel naar hoofdletters worden omgezet in de sort-functie. Dat kan met .toUpperCase().

Data uit JSON stap: 16 op andere eigenschappen sorteren (00:10:41)

Om op andere eigenschappen te kunnen sorteren, maken we in ons object een eigenschap aan, die de sorteereigenschap in zich heeft.
In de sorteerfunctie zetten we de opdrachten in een conditional, die bij elke sorteer-eigenschap een andere .sort() functie aanroept.
Bij de auteurs moeten we ons realiseren dat de eigenschap de achternaam is van de eerste auteur.

Data uit JSON stap: 17 de gebruiker laten sorteren (00:13:47)

Om de gebruiker te laten sorteren voegen we een select-element toe aan het document.
De option-elementen daarin hebben waarden, die corresponderen met de eigenschappen van ons object. Het select-element krijgt weer een class-naam volgens BEM conventie.

Door deze class-naam is het document.querySelector() als variabele in het JavaScript op te nemen. Daar krijgt het een eventListener, die op een change-gebeurtenis een functie aanroept.
Deze functie kijkt naar de value van het select-element en stopt die in de eigenschap in ons boekenobject.
Daarna laten we opnieuw uitvoeren, want die voert ook de sorteerfunctie (met nu die nieuwe eigenschap) uit.

Data uit JSON stap: 18 sorteervolgorde omdraaien (00:11:12)

In een eerdere fase hebben we gezien dat de sorteervolgorde van oplopen naar aflopend kan worden omgezet, door in de ternary-operator de 1 en 1- te wisselen.
Daarom maken we nog een eigenschap in ons boekenobject die de waarde 1 of -1 kan hebben en vervangen de hard-gecodeerde 1 en -1 in de sorteeropdrachten door de eigenschap.
We testen dit door nu op 1 plaats namelijk de eigenschap in ons boekenobject een andere waarde te geven en inderdaad blijkt daardoor de sorteervolgorde omgekeerd te zijn.

Dit omkeren willen we de gebruiker laten doen.
Daarvoor maken we 2 gekoppelde radiobuttons met de value 1 en -1.
We maken vervolgens in ons script een functie, die door een change-event de waarde van de sorteervolgorde aanpast van 1 naar -1 of omgekeerd.

Data uit JSON stap: 19 twee koloms layout (00:05:46)

Voor bredere schermen is een 2 koloms layout beter als je de boeken presenteert.
Dat kan dan goed met CSS Grid.
Om de boeken daar afzonderlijk goed uit te laten komen is een afwisseling van achtergrondkleur een versterkende factor.
Je kunt hier met :nth-child()-selector voor zorgen.
Voor het geval dat nog niet is gebeurd, kun je ook hier weer een commit van het voorlopige werk op GitHub plaatsen.



Link naar de presentatie

Data uit JSON stap: 20 Winkelwagen en bestelknoppen maken (00:26:23)

Er is in deze reeks gekozen voor een layout met floats.
Dit geeft soms ongewenste effecten, die moeten worden bijgewerkt.
Je kunt dat ook wel tweaks met floats noemen.
Je ziet hier in het begin al dat een div niet de volledige breedte komt omdat deze door een floatend element wordt gedwongen ernaast te blijven. Met een clear:right voor dit element kan dit worden voorkomen: dan zal dan zoveel naar beneden gaan, dat het helemaal onder het floatende element is.
Omdat er misschien ook aan de linkerzijde een floatende element kan zijn, geven we hem maar direct clear: both.

Een ander ongewenst effect is dat enkele afbeeldingen zo weinig hoogte hebben dat de tekst eromheen gaat stromen en er ook onder komt.
Dat is te verhelpen door alle tekstelementen in een div te plaatsen en deze zoveel marge te geven dat er voldoende afstand van de rand blijft. Daardoor loopt de langere tekst gewoon door.
Om van deze site een shop te maken, maken we een winkelwagen met een klein elementje dat aangeeft hoeveel artikelen in de wagen geplaatst zijn.
Om deze exact op een gewenste plek te krijgen, geef je hem position: absolute.
Zorg er dan wel voor dat de parent van dit element ook een position heeft gekregen. Anders richt het element zich op de body van het venster.
In de uitvoer van de boeken wordt ook een bestelknop opgenomen en gestyld.
Bij het toevoegen en stijlen van deze elementen houden we weer rekening met de BEM naamconventie.

Data uit JSON stap: 21 Bestelknoppen laten werken (00:17:54)

Het is de bedoeling dat een klik op de bestelknop tot gevolg krijgt dat het bijpassende boek-object in een winkelwagen-object geplaatst wordt.
We maken daarom een nieuw object, welke later ook methods gaat krijgen, maar nu alvast een lege array als eigenschap (property).
Wordt er op een bestelknop geklikt, dan moet het boek-object dat bij de bestelknop hoort, in de array van de winkelwagen worden gestopt.
De bestelknoppen zijn door het JS geplaatst, maar moeten nog een even-listener krijgen.
Daarvoor maken we na het toevoegen van de html een document-query die alle bestelknoppen in zich heeft.

Met een .forEach() lopen we door die knoppen en geven ieder een .addeventListener().
De klik wordt de variabele e genoemd, zodat we met e.preventDefault() kunnen voorkomen dat de knoppen (die in feite linkjes zijn) het als een link gaan afhandelen.
Er wordt eerst bepaald wat de ean is van het boek waarvan er op de knop is geklikt.
Dat kan met e.target.getAttribute('data-role'). We hebben immers daarvoor elke knop een data-role attribuut gegeven met daarin de waarde van de ean van dat boek.
Als we weten welke ean het boek heeft (wordt in een variabele boekID gestopt) dan filteren we dat boek uit onze boeken-object.data.
Dat gaat met: this.data.filter( b => b.ean == boekID);
Dit is een array van 1 element en die pushen we naar de array in ons winkelwagen-object.
Vervolgens geven we het aantal boeken in de winkelwagen eenvoudig weer met de lengte van de array in het winkelwagenobject.

Data uit JSON stap: 22: Local storage (00:11:28)

Als de pagina opnieuw wordt bezocht, of wordt ververst dan is de bestelling uit het winkelwagenobject weer leeg. De browsers hebben sinds HTML5 de mogelijkheid gegevens op de slaan in local storage. De gegevens zijn naam-waarde-paren die uit 2 strings bestaan.
localStorage.setItem('opleiding', 'mediadeveloper aan Mediacollege Amsterdam'); of met de punt notatie:
localStorage.opleiding = "mediadeveloper aan Mediacollege Amsterdam"; Dan kun je in de inspector van je browser de local storage al vinden bij Applications en daarin Local storage. Ook na verversen zien je dar nog staan.
Je kunt die data ophalen en in een variabele plaatsen met
let gegevens = localStorage.getItem('opleiding'); of met de puntnotatie
let gegevens = localStorage.opleiding;

In onze winkelwagen zorgen we er bij het uitvoeren voor dat de gegevens van de bestelling in de local storage komt. We moeten daarbij wel bedenken dat onze bestelling een array van objecten is. Daar maken we een JSON-string van met .JSON.stringify(this.bestelling);

Met JSON.parse(localStorage.naam_van_eigenschap) plaatsen we de inhoud weer in de bestelling van de winkelwagen.
Met localStorage.clear() kunnen we voor testdoeleinden de localStorage helemaal leegmaken.

Data uit JSON stap: 23: bestelformulier maken (00:14:35)

Met local storage kun je ervoor kiezen om een aparte pagina te maken voor de weergave van je bestelling.
Hier wordt ervoor gekozen een inschuivend element te maken waarop de bestelling kan worden gepresenteerd.

In de HTML wordt bovenin een div met class gemaakt.
Deze krijgt een position: absolute; waardoor hij boven de volgende inhoud komt, maar onder de winkelwagen.
De left positie kan voor de presentatie 0 zijn als je het veld wil zien, en 100vw als hij uit beeld geschoven moet zijn.
Voor het schakelen wordt een checkbox gemaakt, en de winkelwagen wordt als label gekozen.
De checkbox hoeven we niet te zien, maar hij moet wel een sibling zijn van en vóór de bestel-div.
Met checkbox:checked ~ bestel-div, kun je de gewenste linkerpositie geven aan de bestel-div als de check-box gecheckt is. Dat gaat hier met de transform-eigenschap.
Met een transition op die eigenschap ontstaat de animitie van de inschuivende bestel-div.

Data uit JSON stap: 24: Overflow verhelpen en methods voor de winkelwagen (00:11:20)

Het naar rechts-schuivende formulier, maakt de body extra breed. Daarom wordt de overfloxX beperkt.
De bediening is via een klik op de winkelwagen, die daarom voor de gebruiker beter een cursor:pointer kan hebben.
Daarnaast wordt de code in het winkelwagen-object ondergebracht in methods.

Data uit JSON stap: 25: Uitvoer bestelling winkelwagen (00:22:57)

Net als op de gewone pagina, kunnen we vanuit de bestelling-eigenschap van de winkelwagen de inhoud uitvoeren in onze bestel-div.
Daar gebruiken we weer de string-literals en de forEach().

Data uit JSON stap: 26: verberg dubbele items (00:12:00)

Het is slordig dat boeken, die vaker zijn aangeklikt ook vaker voorkomen in de bestelling.
Het is beter ze 1 keer te laten zien en later te vertellen hoeveel keer ze besteld zijn.
Bij het testen van de pagina's maken we ook wel de local storage leeg via de console:
localStorage.clear().
Dan blijkt dat het ophalen van de data uit de local storage een fout genereert, omdat die er helemaal niet is. Daarom verbeterenen we dat door deze opdracht in en conditional te stoppen.

Daarvoor gaan we bij de uitvoer van elk boek het boek-object nog een eigenschap (property) geven aantal besteld.
Deze is 0 en bij een klik wordt van dat boek het aantal Daarnaast gaan we in de method warbij het boek wordt toegevoegd, een variabele maken die kijkt of het boek al bestaat in de bestellijst. Daarvoor maken we een variabele waarin de filterresultaat komt waarbij we de boeken filteren op het voorkomen van de id. Is deze leeg (lengte gevonden array heeft length 0) dan wordt het boek toegevoegd, anders wordt het aantal opgehoogd.
Na het uitvoeren en het bijwerken in de local storage, verschijnen er nu geen dubbele exemplaren meer.

Data uit JSON stap: 27: aantallen verwerken (00:09:13)

Door de vorige video worden de aantallen niet meer verwerkt, het totale aantal boeken blijft beperkt tot het aantal verschillende boeken en wordt de prijs niet meer berekend.
In deze video komen de bestelde aantallen in beeld en wordt de prijs bij meerdere exemplaren doorgerekend en wordt het totaal van de boeken bij de winkelwagen anders berekend.

Data uit JSON stap: boeken verwijderen (00:13:25)

Op het eind van elke rij wordt een icon van de vuilnisbak toegevoegd.
Daarin zit ook een attribuut data-role met de ean van het boek als waarde.
Na de toevoeging van de boeken wordt er een method toegevoegd om al deze icons van een event-listener te voorzien.
Deze gaat dan bij een klik filteren op alle boeken die NIET de ean hebben van het geklikte boek. Daarmee is dat boek uit de bestellijst verwijderd.

Data uit JSON stap: stap 29: knoppen bestelling maken (00:11:09)

Het blijkt dat als je met de bestellijst open, de pagina ververst de focus op de weggeschoven bestellijst blijft, en juist de producten links verdwijnen.
Dit blijkt te verhelpen door de checkbox voor de bestellijst anders te verbergen.
Als display: none; vervangen wordt door opacity: 0; dan blijkt het probleem verholpen.
In de uitvoer van de bestellijst voegen we met Font Awesome twee pijlen toe.
We kunnen dan straks met het script de gebruiker de aantallen in de bestellijst laten aanpassen.

Het verwerken van het script is vergelijkbaar met de trash, en daarom geven ze deze knoppen ook een attribuut data-role mee, zodat het script strak weet bij welk boek de aantallen moeten worden aangepast. De waarde is weer het ean-nummer van de boeken, omdat die uniek voor elk boek is.
We geven ook css-classes mee volgens de BEM-conventie zodat we de elementen wat padding en een hover-effect kunnen geven.

Data uit JSON stap: stap 30: knoppen bestelling activeren (00:16:59)

We gaan voor de knoppen op dezelfde wijze te werk als bij de trash.
Er wordt voor het winkelwageobject een method aangemaakt die de koppen activeert en die wordt vanuit de uitvoeren-method aangeroepen. Dit moet na het toevoegen van de elementen gebeuren.
In de nieuwe method maken we een variabele die alle hoger-knoppen bevat. Deze array wordt met een forEach() doorgelopen.
Elke knop krijgt een click-event. Daarvan wordt via het data-role attribuut met .getAttribute('data-role') de ID opgevraagd.
Er wordt een nieuwe array gemaakt, die de bestellijst filtert op het boek met de betreffende ID.
van dit boek in het bestelobject wordt de eigenschap (property) die het aantal geeft opgehoogd. Bedenk dat dit filteren een array oplevert en dat we met [0] het eerste element te pakken hebben, waarvan we het aantal aanpassen.
Om dit blijvend te maken wordt de local storage bijgewerkt en om het zichtbaar te maken de bestellijst opnieuw uitgevoerd.
Voor de verlaagknop gaat het vergelijkbaar. Alleen moet in het geval het aantal 0 wordt het boek uit de bestellijst worden verwijderd. Daar komt dan een conditional voor.


Bonusopdracht

Er zijn de volgende uitdagingen waaruit je kunt kiezen:

  • De layout binnen de sections is in de video met floats gerealiseerd. Doe dat met CSS Grid of CSS flexbox.
  • Het XMLHttpRequest kan ook worden uitgevoerd met de Fetch-API.
    Zoek dit uit en vervang de XMLHttpRequest door de Fetch-API.
  • Geef de boeken een extra eigenschap, bijvoorbeeld genre of uitvoering (gebonden/e-book/paperback). Geef de gebruiker de mogelijkheid daarop te filteren.

Heb je een of beide bonusopdfachten gedaan, vermeld dit dan wel in de README.md.

Inleveren

  • Na afloop plaats je deze training online in je bewijzenmap;
  • Valideer jouw pagina's op Markup Validation Service van W3C.
  • De validatie icoontjes staan al in de footer. Code vind je bij https://github.com/Theo-denBlanken/validatie-W3C;
  • Tijdens jouw uitwerking plaats je regelmatig commits in een aparte repository op GitHub
  • Maak in jouw GitHub-repo een README.md met daarin temnminste een link naar jouw online uitwerking.
  • Plaats de GitHub-link in ELO Magister.