Video 18: objecten (eindelijk…)

Deze video bestaat uit twee delen:

deel 1:

deel 2: 


Inleiding opdrachten van Video 18

Moderne websites gebruiken veel AJAX om de site snel en responsief te maken. In de meest geavanceerde toepassing van dat idee wordt er niet eens meer HTML van de webserver naar de browser gestuurd: de server stuurt alleen data op, in de vorm van Javascript-arrays en Javascript-objecten (met natuurlijk arrays-binnen-objecten-binnen-objecten-binnen-arrays etc.). Dat soort data in Javascript-code wordt JSON genoemd. Voordat de server de data in JSON opstuurt, heeft de browser al een flink Javascript programma ontvangen. Dat programma zet –in de browser–  dan de data om in HTML.

In deze serie oefeningen gaan we zo’n programma schrijven dat JSON omzet in een pagina van een blog-site. Eerst één (later meerdere) blogpost(s), met titel, auteur, tekst en afbeelding enzo. Weer later voegen we daar commentaren aan toe. Omdat het nu even niet handig is om de data echt van een server te halen, faken we de server door de data gewoon in het Javascript programma op te nemen. Werkelijke AJAX kan je, als je wilt in een later project doen, als je ook een server-programmeertaal hebt geleerd als Python, Ruby, PHP of C#.

Hier zie je het begin van het programma, inclusief de JSON-data. Die data ga je zelf nog uitbreiden, maar gebruik deze code als startpunt voor de opdrachten:

<html>
<head>
<style>
  /* zet hier de css om je blogpagina mooi te maken" */
</style>
</head>

<body>
  <!-- hier kun je nog een headline of banner of zoiets laten komen -->
<div id="mainContent">
  <!-- laat hier de html voor de posting komen -->
</div>

<script>
var myBlogPosting = {
  title:    "Google launches underwater Street View",
  bodyText: "<p>Today Google Maps unveils a new Street View feature: " +
            "underwater panoramic views of six special sea spots. " +
            "The idea is to create a virtual map of the oceans, " +
            "documenting the state of fragile ecosystems as they " +
            "change over time, and sharing a vivid experience of " +
            "part of our world that few humans get to see up close " +
            "and in person, in real life.</p>" +
            "<p>The ocean collection on Google Street View is now " +
            "available at maps.google.com/ocean, and includes coral " +
            "reefs and the creatures who live in them, in Australia, " +
            "the Philippines and Hawaii.</p>",
  link:     "http://boingboing.net/2012/09/25/google-launches-underwater-str.html"
}
</script>
</body>
</html>

Vraag 18.1: blogposting ‘renderen’

Schrijf een script die van de gegeven blogPosting een mooie HTML pagina maakt. De gegenereerde HTML kan in de ‘mainContent‘-DIV komen.

  • Zet de code om de blogposting te ‘renderen naar de pagina’ (=omzetten in iets zichtbaars, HTML dus) in een functie, die het posting-object als parameter binnenkrijgt. (We zullen deze functie straks willen gebruiken voor andere blogpostings).
  • Besteed wat aandacht, maar ook niet teveel, aan de vormgeving. Het is belonend om mooie output uit je programma te krijgen, maar 4 uur designen is niet een heel effectieve manier om in deze minor scripten te leren.

[ Mail je complete programma… ]


Vraag 18.2: blogposting uitbreiden

Voeg velden toe voor de auteursnaam, een url van een afbeelding, en voor een ranking.

  • De auteur van dit bericht heette “Xeni Jardin”
  • De ranking is een getal tussen 1 en 5. Verzin zelf maar een goede waarde ervoor.
  • Zoek een goede afbeelding, en zorg ervoor dat je pagina de afbeelding toont (niet de text van de URL).

Zorg er voor dat ook deze gegevens zichtbaar worden in de browser.

[ Mail je complete programma… ]


Vraag 18.3: meerdere blogpostings

We willen dat de pagina meerdere blogpostings toont. Maak er een stuk of 8 (of 7) bij, en zorg ervoor dat ze samen worden opgeslagen in een array.

Maak nu eerst even een scriptje dat de titels van alle postings in de array naar de console schrijft.
(Renderen van de hele lijst is de volgende opdracht).

[ Mail je complete programma… ]


Vraag 18.4: alle blogpostings ‘renderen’

Verander nu je script zo dat het alle postings in de array naar de pagina als HTML schrijft.
Gebruik daarbij de functie die je eerder maakte om één posting als HTML te ‘renderen’. Het is daarbij prima als die functie nog wat aanpassingen nodig heeft, maar de functie blijft werken voor één enkele posting.
De code om alle postings uit de array te behandelen zit elders, en roept deze functie aan.

[ Mail je complete programma… ]


Vraag 18.5: blogposting renderen met een methode

Maak van de functie die een posting omzet in HTML een methode. Met andere woorden:
  • De objecten hebben nu zelf een variabele die naar de functie/methode verwijst.
  • De functie/methode wordt aangeroepen via het object (b.v.mijnObject.mijnMethode).
  • De code voor de functie/methode zelf benadert de andere velden in het object via 'this'.
Zorg er (natuurlijk) voor dat het programma als geheel nog werkt. [ Mail je complete programma... ]

Vraag 18.6: commentaar

Objecten kunnen ook arrays als waardes van een veld bevatten. Bijvoorbeeld:
mijnFilms = [ { titel: "Some Like It Hot",
                jaar:  1959,
                acteurs: [ "Marilyn Monroe", "Tony Curtis", "Jack Lemmon" ]
              },
              { titel: "Casablanca", jaar: 1942,
                acteurs: ["Humphrey Bogart", "Ingrid Bergman" ]
              }
            ]
En, (niet getoond in dit voorbeeld), die arrays-binnen-objecten kunnen natuurlijk zelf weer objecten bevatten (met wellicht een paar arrays erin, enzovoort). Dat gaan we nu toevoegen aan onze blog-pagina:
  • Een Comment bestaat uit: een stuk text, de naam van de commentator, en een ranking.
  • Zorg er voor dat alle postings een paar Comments hebben, op ééntje na.
  • Comments zijn ook objecten, en hebben in ieder geval één methode: de methode die HTML-tekst oplevert op basis van de data in het Comment.
Herschrijf je script dat voor alle postings ook de comments getoond worden (in een wat kleiner lettertype wellicht). [ Mail je complete programma... ]

Opdracht 18.7: Andere postings, andere methoden

Niet alle objecten hoeven exact dezelfde code te hebben voor een methode. Experimenteer in Firebug eens met de volgende code:

function toonKarakter() {
    var bericht = "Ik ben " + this.naam;
    bericht += ", een " + this.soort + " uit Duckstad.";
    console.log( bericht );
}
function toonMuis() {
    var bericht = "Ik ben " + this.naam;
    bericht += ", een " + this.soort + " uit DISNEYLAND PARIJS!";
    console.log( bericht );
}

var disneyTypetjes = [  // begin array
    { naam: "Mickey Mouse",
      soort: "bizar muisje",
      stelJeNetjesVoor: toonMuis
    },
    { naam: "Donald Duck",
      soort: "eend",
      stelJeNetjesVoor: toonKarakter // andere functie
    },
    { naam: "Kwik",
      soort: "neefje",
      stelJeNetjesVoor: toonKarakter
    },
    { naam: "Kwek",
      soort: "neefje",
      stelJeNetjesVoor: toonKarakter
    },
    { naam: "Kwak",
      soort: "neefje",
      stelJeNetjesVoor: toonKarakter
    },
    { naam: "Dagobert Duck",
      soort: "eend",
      geld:  100000000,
      stelJeNetjesVoor: function() { // functie definitie binnen object
         alert("Ik ben "+this.naam+", en ik ben zo rijk, " +
               "dat ik mezelf met 'alert' voorstel!");
         console.log("Ik heb " + this.geld + " duckdollars!");
       } // einde functie
    } // einde object Dagobert
 ]; // einde array

for( var idx=0; idx < disneyTypetjes.length; idx++ ) {
  console.log( "Disney typetje " + idx + " zegt:")
  disneyTypetjes[idx].stelJeNetjesVoor();
}
console.log("Klaar! Dat waren ze allemaal...");

Zie je dat vershillende objecten nu heel verschillend kunnen reageren op dezelfde methode-aanroep? Dit gaan we gebruiken door twee nieuwe types posting toe te voegen:
  • De SponsoredPosting lijkt heel erg op een gewone posting maar heeft de volgende eigenschappen:
    • boven de posting zelf wordt (in een vrij klein, onopvallend font) de tekst "this is a message from one of our sponsors".
    • SponsoredPostings hebben een extra veld: de URL van de sponsor.
    • Een klik op de titel of op het plaatje van de SponsoredPost, navigeert naar de site van de sponsor.
    • De vormgeving van de SponsoredPosting wijkt een beetje af, zodat-ie fijn opvalt.
  • De VideoPosting toont een embedded YouTube-filmpje (boven of onder de gewone tekst van de Posting).
    • De URL die normaal gesproken het plaatje bevat, bevat nu de YouTube-url van de video. Zoiets als "http://www.youtube.com/embed/Z86V_ICUCD4". Let op: Gewone YouTube URLs bevatten het woord 'watch', maar nu moet je het woord 'embed' daarvoor in de plaats hebben staan!
    • Die URL gebruik je dan in de volgende html-code om de video ook echt in je blogpagina te tonen:
      <iframe width="420" height="315" src="http://www.youtube.com/embed/Z86V_ICUCD4" frameborder="0" allowfullscreen></iframe>
      http://www.youtube.com/watch?v=Z86V_ICUCD4&w=420&h=315 (vervang de URL in dit voorbeeld dus door de URL van de VideoPosting)
Voeg twee SponsoredPostings en twee VideoPostings toe aan je verzameling postings. Geef deze nieuwe postings aparte methoden om HTML te renderen. Deze nieuwe methoden voeren de bovengestelde eisen uit. [ Mail je complete programma... ]

Vraag 18.8: bonus: commentaren op commentaren

VOOR DE BONUS: In threaded commentaar-systemen, kunnen comments zelf weer een lijstje comments hebben (maar het hoeft niet altijd, de lijst sub-comments kan soms leeg zijn). Kun je het zo maken dat je blog-pagina sub-commentaren ook kan tonen (het liefst ingesprongen)? De uitdaging zit 'm in de wens dat je programma werkt, ongeacht hoe diep de commentaren in elkaar verwerkt zitten. Je moet dus niet alleen commentaren-op-commentaren aankunnen, maar ook commentaren-op-commentaren-op-commentaren (3 niveau's) en commentaren-op-commentaren-op-commentaren-op-commentaren-op-commentaren-op-commentaren (6 niveau's en zelfs meer). Hiervoor is recursie een handige programmeerstrategie. Lees er over in hoofdstuk drie van het Javascript book. Als je er voor kiest om deze opgave niet te maken, denk er in ieder geval even over na. We gaan 'm vast in de klas behandelen. [ Mail je complete programma... ]