Mine notater Gløer Olav Langslet Sandvika VGS Et praktisk eksempel med objekter Vi kjenner alle til korktavlen med gule lapper. Vi henger opp en lapp for at vi selv eller andre skal huske eller bli minnet på et eller annet. Læreplansmål Eleven skal kunne gjøre rede for hensikten med objektorientert utvikling og begrepene klasse, objekt og arv. I denne leksjonen skal vi forsøke å gjenskape korktavlen med HTML, CSS og JavaScript. Vi tenker også at det kan være lurt å lage hver lapp som et objekt. Da må vi først lage en modell for hvordan en lapp må se ut, eller hva den må inneholde. I dette tilfellet er det ganske enkelt teksten på lappen som skal lagres. Men vi har mange lapper, så vi bør vel også ha et array som vi kan lagre alle lappene i. Skal det være noen vits, bør vi også lagre innholdet i lappene. Dette gjør vi ved å opprette et array med tekstene som vi lagrer med localstorage.
sdsd En modell for lappene Vi lager en klasse, eller en modell for hvordan lappene skal se ut. I objektorientert programmering snakker vi om klasser og objekter. Klasser er på en måte modellen for objektene. Vi sier at når vi skal lage en lapp, skal den være sånn og sånn. En god start? Det eneste vi trenger å lagre om en lapp, er teksten på lappen, eller notatet. Vi kan kalle klassen Notat, og teksten notattekst. Klasser og objekter Sånn. Dette er klassen vår. Nå kan vi enkelt opprette et notat ved å skrive følgende: Det er vel egentlig ikke noen ekte klasser i JavaScript som det er i Java, C++ og andre rene objektorienterte språk. I stedet for klasser bruker vi funksjoner, og det fungerer omtrent på samme måte. 2
Sandvika VGS Vi tester. Det er alltid lurt å teste det vi lager tidlig. Hvis vi har skrevet feil, vil vi avdekke det med en gang. Hvis ikke, blir vi glade og fortsetter arbeidet. Det var koden til nå. Vi får opp to meldinger med tekstene i notatene våre. Neste skritt er å gi lappen en grafisk representasjon. Det beste er om vi kan la hver lapp lage seg selv, rett etter at den er opprettet. Til det trenger vi litt JavaScript, men vi bruker også litt CSS til utformingen av selve lappen. 3
sdsd Hvordan ser HTML-koden for en lapp ut? HTML-koden er ganske enkel. Planen er å gjenskape eksakt disse linjene med HTML for hver lapp vi lager. Vi setter class= notat på alle notaene, så vi kan styre dem med CSS. Det skal selvfølgelig også være mulig å endre på teksten i lappene, så vi må si at de skal være contenteditable, det betyr at vi kan skrive i lappene. Vi knytter en funksjon som kan lage div-taggen til notatene Når vi skriver this.lagnotat() i selve modellen, betyr det at hver gang vi lager et nytt notat med new Notat( blablabla ), så vil vi umiddelbart sette i gang funksjonen. Først oppretter vi et div-element, sier at det skal ha classname= notat, sier at det skal være editerbart med contenteditable. Til slutt legger vi teksten inn i diven. this.notattekst betyr denne lappens notattekst. For notat1 vil det være Dra på butikken. Nå mangler vi bare å legge diven til på siden vår et sted. Vi ser kanskje for oss at det skal være noe mer på siden enn bare notatene, så vi legger alle notatene inn i en ny div, som vi kaller main. Denne skriver vi like gjerne i HTML. 4
Sandvika VGS Vi lager en div som vi kan legge notatene inn i Vi legger inn en di med id= main. Hver lapp skal nå legges inn i main etter hvert som de blir laget. I linje 15 lager vi en JavaScript-referanse til main-diven. I linje 27 legger vi vårt nye notat inn i main. Når vi nå lager 2 nye notater, vil de automatisk dukke opp på siden. 5
sdsd Vi pynter opp med litt CSS Dett kan løses på mange måter. Men vi ønsker at lappene skal legge seg etter hverandre med litt avstand. Benytt din kunstneriske frihet. 6
Sandvika VGS En taktikk for å lagre lappene Det første vi må gjøre, er å sørge for at objektenes notattekst endrer seg når vi endrer teksten i notatet. Dette kan vi gjøre på onkeyup. Da er vi sikre på å få med oss hver minste endring. Dette burde vel gå bra. Når vi taster, skal vi oppdater objektet. Men det går ikke så bra. this vil referere til selve diven vi har laget når vi gjør det på denne måten, og ikke til selve notat-objektet. Vi kan illustrere det ved å skrive this.notattekst til konsollen, og se hva det blir: Vi får undefined, det betyr at diven ikke har noe som heter notattekst. Og det stemmer jo, for det er selve objektet som har denne knyttet til seg. Vi kan løse dette ved å døpe om eller lage en referanse til objektet utenfor funksjonen: 7
sdsd Hva skjer nå? I linje 50 sier vi at self = this. Det er en måte å gi objektet et annet navn, eller rettere sagt lage en referanse til objektet. Det trenger vi når vi skal ha tak i objektet innefra funksjonen som er knyttet til diven som vi lager. I funksjonen vil nemlig this bety diven som vi skriver i: Konsollen logger først div-elementet, og så objektet vårt: Og da er vi egentlig i mål, for nå kan vi skrive at objektet skal få verdien av innmaten (innerhtml) til diven: Men hvordan vet vi at det virker? Vi skal senere lagre alle tekstene til notatene med localstorage, og da trenger vi en funksjon som trekker ut alle tekstene fra notatene og legger det over i localstorage. Denne funksjonen tenkte vi å kalle oppdaternotattekster, og vi kan like gjerne lage den med en gang, og se om endringene våre faktisk virker. Men når skal vi gjøre dette? Det kan tappe krefter fra programmet vårt om vi gjør det hver gang vi skriver et tegn. Det vil være mer ressurssparende om vi for eksempel gjør dette hver gang vi klikker utenfor notatet, dvs. notat-diven mister fokus. I JavaScript kan vi bruke onblureventet for å få til dette. Den vil slå til hver gang vi er ferdige med å skrive. Dette eksempelet kan du se her: http://langslet.com/vgs/kode/leksjon_5/firkant.html 8
Sandvika VGS Vi starter en funksjon med onblur Tester først når onblur slår til: Prøv å skrive noe i et av notatene. Når du klikker utenfor, starter oppdateringsfunksjonen. Det er nå på tide å opprette et array for notatene våre. Vi skal etter hvert lage en knapp for å opprette nye notater, men i første omgang lager vi altså et array som vi kan legge notatene inn i. Helt i starten av koden initialiserer vi arrayet: Så kan vi legge notaene våre inn etter at de er opprettet: Det vi skal oppdatere, er et annet array som ligger i localstorage, det har vi ikke laget ennå, men allerede nå kan vi sjekke om objektene oppdaterer seg, ved å gå gjennom arrayet, og sjekke hva som ligger lagret i objektets notattekst. 9
sdsd Vi går gjennom notatene Går gjennom hvert notat i listen: Vi går gjennom listen, og skriver ut objektets eneste verdi til konsollen: Når vi skriver, og så klikker utenfor, ser vi endringen. Men hvis vi oppdaterer, er vi like langt. Vi må innføre en måte å lagre til localstorage. Det enkleste er å lage et array som kun består av tekstene til lappene. Når vi oppdaterer siden, kan vi sjekke om det er lagret noe i localstorage. Hvis det er det, lager vi de gule lappene basert på dette. 10
Sandvika VGS Et array for tekstene Parallelt med at vi oppretter arayet med notatobjektene, lager vi også et array til notattekstene: Legg merke til at vi ikke oppretter en tom liste. Vi sier bare at vi skal ha en variabel som heter notattekster. Grunnen til det, er at hvis det fins noen notater i localstorage, skal vi bruke disse. Hvis de ikke fins, skal vi opprette et tomt array: Oppdaterer localstorage Hver gang vi har gjort en endring i et notat, går vi gjennom alle notatobjektene, og oppdaterer arrayet med tekstene i localstorage: I linje 73 starter vi med å nulle ut arrayet. Vi skal jo fylle det opp basert på det som ligger i notatobjektene. Dette gjør vi ved å fylle inn notattekst fra hvert objekt. Til slutt legger vi hele arrayet inn i localstorage. Vi må huske på at vi nå jobber med et array, og da må vi bruke JSON.stringify og JSON.parse. stringify pakker arrayet inn, og parse pakker det ut igjen. 11
sdsd Men det virker ikek riktig ennå Koden vår som oppretter notatene, vil nå overstyre alt. Hver gang siden lastes lager vi to nye notater. Vi må i stedet bygge notatene dynamisk basert på det som er lagret i localstorage. I starten av programmet sjekker vi om det ligger noe lagret i localstorage. Hvis det gjør det, legger vi dette inn i arrayet med tekstene, notattekster. Hvis det ikke er noe lagret, oppretter vi et tomt array. Da vil det heller ikke skje noe her. Men hvis det er noe lagret fra før, vil vi nå lage nye Notat-objekter. Hvert av disse legger vi også inn i arrayet med objektene. Nå kan vi i hvert fall oppdatere de to notatene vi har laget. Men vi ønsker vel også å kunne opprette nye notater. La os lage en knapp som kan sørge for dette: Vi legger knappen i et nav-element, siden vi også skal lage en knapp som skal slette alle notater, og kanskje et søkefelt, for raskt å kunne finne lapper med et visst innhold. Når vi klikker på knappen, ønsker vi å opprette et tomt notat. 12
Sandvika VGS Nytt notat Vi kobler knappen til en funksjon som oppretter et nytt, tomt notat: Og funksjonen: I linje 93 lager vi et nytt tomt notat. I linje 94 legger vi det inn i arrayet med notatobjekter. Fjern alle notater Vi kan fjerne alle notater ganske enkelt: 13
sdsd Pynter opp litt! Vi bruker litt CSS for å pynte opp. Her har vi brukt 2 bilder som vi fant på http://famfamfam.com/lab/icons/silk/ 14
Sandvika VGS Setter inn ikoner i knappene Legger inn et par ikoner fra FAMFAMFAM: Pass på at du legger bildene i samme mappe. 15