TDDD83 Kandidatprojekt datateknik
Laboration 2
# Front end (HTML, CSS & JavaScript)
Graden av framgång för en hemsida ligger självklart i dess förmåga
att leverera förväntat resultat, sidan ska inte ladda för länge eller
krascha mitt i ett kommando från användaren. Men vem skulle lita på
en hemsida vars design ser ut att vara från 80-talet? Tillika är
designen en viktig aspekt i webbutveckling och i denna laboration ska
vi ägna oss åt design och användargränssnitt.
I denna laboration kommer vi skapa en så kallad _Single Page Application_
där all data hämtas asynkront från ert API __efter__ att sidan laddats in. Detta innebör alltså att er applikation aldrig ska laddas om (så länge inte användaren klickar på uppdatera eller liknande).
Men innan vi börjar behöver vi först förstå grunderna i hur en
hemsida är uppbyggd. En webbklient består av tre delar:
__HTML__ - [Läs mer](https://www.w3schools.com/html/)
Denna teknik tillhandahåller grundstrukturen för hemsidor, vilken sedan
är utökad och modifierad av andra tekniker såsom CSS och Javascript.
__CSS__ - [Läs mer](https://www.w3schools.com/css/)
För att skapa önskat utseende, presentation och formatering på de objekt
som finns på en hemsida används CSS.
__Javascript__ - [Läs mer](https://www.w3schools.com/js/)
När funktionallitet och kontroll av beteenden ska definieras används
Javascript.
Det finns även bibliotek som innehåller många färdiga HTML/CSS-komponenter
som exempelvis [Bootstrap]( https://getbootstrap.com/docs/4.4/layout/overview/)
vilken vi kommer använda i denna laboration.
## Förberedande frågor
Svara på följande frågor och skriv ner era svar innan demonstration
Vilken eller vilka teknik(er) (HTML/CSS/Javascript) används för respektive av följande?
1. Sätta en bakgrundsfärg på ett element
2. Skapa ett länk-element
3. Inkrementera en siffra på sidan när användraren klickar på en knapp.
4. Skapa en ruta som är 200x85 pixlar och har en röd list
## Del 1: Sidstruktur
Börja med att följa [instruktionerna om "Påbörjande av ny labb"](inlamning-och-git#p%E5b%F6rjande-av-ny-labb).
För att börja bygga klientapplikationen ska ni nu skapa några tomma filer i
mappen client:
1. Skapa följande filer i mappen /client:
* client.html
* client.css
* client.js
Ovanstående filer klassificeras i webbsammanhang som _statiska_, d.v.s.
webbservern ska inte göra något med dessa filer förutom att se till att
de finns tillgängliga för användaren. För att konfigurera Flask att
servera dessa statiska filer behöver ni göra följande:
__A.__ Lägg till argumenten `static_folder='../client', static_url_path='/'`
till Flask-konstruktorn. Detta innebär att Flask kommer att servera statiska filer från mappen
../client på URLen "/" (d.v.s. exempelvis http://localhost:5000/).
__B.__ Skapa en route för "/" som serverar filen _client.html_ enligt följande:

## Del 2: Beroenden
Eftersom ni ska använda Bootstrap behöver webbläsaren få tillgång till
källkoden för Bootstrap samt dess beroenden. Detta görs genom att lägga
till en länk-rad i vår client.html-fil.
1. Skapa innehållet i _client.html_ och inkludera beroenden enligt
[denna sida](https://getbootstrap.com/docs/4.4/getting-started/introduction/).
__OBS:__ Efter att ni kommit igång med Bootstrap enligt sidan ovan måste ni justera
länken som inkluderar jQuery, för att inkludera funktionalitet som vi kommer behöva framöver. Detta gör ni genom att ersätta importen med det ni finner när ni går in på https://code.jquery.com och klickar på länken "minified" under den senaste versionen.
Notera att webbläsaren läser HTML-koden
uppifrån och ner, så ordningen koden ligger i spelar stor roll. Om ni
placerat alla länkar i samma ordning som i Bootstrap-länken ovan, ska allt fungera korrekt.
## Del 3: Layout
Nu är det dags att börja använda Bootstrap och skapa en tjusig layout för vår hemsida.
Bootstrap gör det smidigare att utveckla webbsidor för flera olika
skärmstorlekar samtidigt. Testa alltid olika storlekar på webbläsarfönstret
för att se att layouten fungerar på alla varianter (exempelvis telefon-,
surfplatte- och datorstorlek).
1. Lägg, i er HTML-kod, till en [Navbar](https://getbootstrap.com/docs/4.4/components/navbar/)
med en logotyp (bild eller text) och minst menyalternativen "Hem" och "Kontakt".
__Notera:__ Funktionalitet för navigering behöver inte implementeras ännu.
2. Lägg till ett div-element med klassen "container" enligt
[denna sida](https://getbootstrap.com/docs/4.4/layout/overview/). Denna
kommer senare att innehålla allt synligt innehåll förutom er navbar.
Resultatet kan illustreras så här:

där "container" är det element som innehåller sidspecifikt innehåll.
3. Lägg till en välkomnande titel (h-element) och ett valfritt stycke
trevlig text i ovanstående div-tagg. När ni är klara ska en rubrik
synas på sidan med en mindre brödtext under rubriken.
## Del 4: CSS
I Bootstrap finns redan mycket stilar definierade och tillgängliga att
använda. Många gånger vill utvecklare såklart själva styra hur komponenter
och layout ser ut på en mer detaljerad nivå. Till detta använder vi CSS.
Med hjälp av CSS är det möjligt att "välja" HTML-element och applicera
olika stilattribut på dem. Det enklaste sättet att "välja" ett eller
flera element är via dess elementtyp, id eller klass. Följande figur
visar ett exempelelements typ, id samt klass.

Notera att id ska vara unikt (max ett element per HTML-dokument)
medan flera element kan ha samma typ och/eller klass(er).
Följande figur visar tre exempel på hur ni med hjälp av CSS väljer
olika element. Dessa och ett gäng andra sätt att välja element
kallas för [Selectors](https://www.w3schools.com/css/css_selectors.asp).

1. Lägg in följande länktagg för att webbläsaren ska ladda
in er css-fil. Förslagsvis direkt under all annan css-import i head-elementet.

2. Under er nyligen skapade brödtext och rubrik ska ni nu lägga till
en snyggt formaterad lista över öppettider. öppettiderna får ni
bestämma själva men listan ska vara väl formaterad med hjälp av
CSS och vara placerad naturligt på sidan, det vill säga med
rimliga avstånd från hemsidans kanter.
__Tips:__ Hur ser en lista med öppettider ut på andra hemsidor?
## Del 5: Vyer
Er front end-applikation bör i det här laget ha en meny (navbar), en
välkomstsida samt någon CSS applicerad.
Vi kommer snart att gå igenom hur Javascript kan användas för att visa
olika vyer för användaren, men för att det ska gå att genomföra behöver
ni först placera innehållet för välkomstsidan i någon typ av behållare
samt dölja det för användaren. Det finns såklart många sätt att göra
detta, men ett enkelt sätt är att lägga en script-tagg runt innehållet som
bildar en vy. Exempelvis på detta sätt:

Vi kan kalla ett sådant block för en vy.
1. Flytta innehållet för välkomstsidan till en egen behållare (utanför
den div som har klassen "container", som ska lämnas tom) och se till
att den inte visas. Ni bör nu se en tom sida, bortsett från er navbar. För att visa
välkomstinnehållet behöver ni använda lite Javascript som introduceras i del 6.
## Del 6: Javascript (med jQuery)
Javascript används som bekant för att manipulera element och innehåll.
I denna laborationsserie använder vi även Javascript-biblioteket
[jQuery](https://jquery.com) för att underlätta många vanligt
förekommande implementationer, så vi inte "uppfinner hjulet" så många
gånger.
När ni skriver Javascript kan webbläsarens utvecklingarverktyg vara till stor hjälp, exempelvis för debugging och inspektion av er kod. Funktionen `console.log()` skriver exempelvis ut data till utvecklarverktygets konsol. Läs mer om utvecklarverktygen i Firefox [här](https://developer.mozilla.org/sv-SE/docs/Tools).
1. Inkludera er Javascript-fil (client.js) i HTML-dokumentet. Se till
att den inkluderas under inkluderingen av jQuery eftersom er kod
kommer vara beroende av att jQuery finns tillgängligt.
2. Det är inte säkert att allt innehåll i HTML-dokumentet har laddats
klart när webbläsaren når er fil. Därför är en bra början att utgå
från följande (`doStuff` är endast ett exempel för att illustrera syntaxen för en funktion och bör ej användas som namn):

3. Lägg till raden `alert("Sidan laddades");` inuti funktionen som skickas till `$(document).ready()` (d.v.s. ersätt `doStuff();` i exemplet ovan). Detta gör att ni enklare upptäcker ifall ni av misstag gör så att sidan laddas om.
4. För att återigen visa er välkomstvy ska ni med hjälp av Javascript
sätta innehållet i er container till innehållet i ert script-element
som ni skapade i Del 5.
__Tips:__ För att läsa eller sätta innehållet i ett element kan
jQuery-metoden [.html()](https://api.jquery.com/html/) användas på
följande sätt:

Ovanstående kan med fördel placeras i funktionen som skickas till `$(document).ready()`.
5. Skapa nu ytterligare en vy för er kontaktsida. Den ska innehålla:
* Kontaktuppgifter till er själva, en påhittad person eller ett
påhittat företag (namn, e-post, telefonnummer, adress) presenterade
på ett trevligt sätt.
* Ett rimligt formaterat kontaktformulär innehållande minst fälten
namn, e-post och meddelande. Det ska även finnas en knapp för att
skicka formuläret, men ni behöver inte implementera någon ytterligare
funktionalitet ännu. Använd
[Bootstrap-dokumentation](https://getbootstrap.com/docs/4.4/components/forms/)
som hjälp när ni bygger formuläret.
__Tips:__ För att se hur er vy ser ut medan ni bygger den, ändra så
att kontaktvyn visas vid sidladdning istället för välkomstvyn. Vi
ska lägga till funktionalitet för navigation alldeles strax.
6. Nu är det dags att implementera navigation! När användaren klickar
på menyalternativen, se till att respektive vy visas i containern.
__Tips:__ För att reagera på ett klick kan jQuery-metoden `click()`
användas, exempelvis på detta sätt:

`e.preventDefault();` kan användas på ovanstående vis för att
förhindra att webbläsaren hanterar event på dess standardsätt. Exempelvis
kan metoden användas för att förhindra att en länk laddar sidan som
länken pekar på när användaren klickar på den.
[Läs mer](https://javascript.info/default-browser-action). Det går även att
åstadkomma detta genom att helt enkelt returnera `false` från funktionen.
## Del 7: Hantera data
I det här stadiet borde ni ha koll på hur ni med hjälp av Javascript
reagerar på events/händelser, hämtar data från element samt manipulerar
element. Ni ska nu få använda era kunskaper för lite mer avancerad
datahantering med Javascript.
__Kontaktformulär__
Först och främst vill vi kunna göra något med kontaktformuläret:
1. När användaren klickar på "Skicka"-knappen ska ni hämta ut värdet
ur varje fält (namn, e-post, meddelande) och presentera för användaren.
Presentationen kan bestå av en simpel
[alert()](https://www.w3schools.com/jsref/met_win_alert.asp) eller liknande,
det viktiga är att all data visas. I labb 3 kommer ni få skicka data
till er server istället för att visa den för användaren.
__Billista__
I nästa laboration ska ni få koppla ihop er front end med er back end.
I denna laboration fokuserar vi på front end-applikationen och därför
kommer ni få en så kallad server stub. Det är ett antal
Javascript-metoder som "simulerar" en back end.
1. Ladda ner [server-stub.js](downloads/server-stub) och lägg in filen
i er client-mapp.
2. Titta igenom [dokumentationen](server_stub-docs/docs/serverStub.html)
för vår server-stub.
3. Inkludera server-stub.js i ert HTML-dokument. Tänk på att den måste
inkluderas ovanför era egna Javascript-filer.
4. Skapa en till ytterligare vy och tillhörande menyalternativ
"Bilar".
5. När den nya vyn visas, presentera med hjälp av HTML, CSS och
Javascript en lista över alla bilar från serverStub. Ni kan designa
den hur ni vill men följande information ska visas för varje bil:
* Märke
* Modell
* Eventuell kunds namn
* En knapp/länk/ikon för att redigera och en för att ta bort bilen
__Tips:__ Läs om jQuerys tillgängliga metoder för att lägga till
element [här](https://www.w3schools.com/jquery/jquery_dom_add.asp).
__Tips:__ Titta på Bootstraps dokumentation för kort (Card) och
tabeller om ni vill ta hjälp av Bootstrap för design.
6. Gör det möjligt för användaren att uppdatera hela listan genom
att klicka på förslagsvis en knapp. Ni ska då hämta bilarna från
serverStub och se till att den informationen visas.
7. Implementera borttagning av bilar. Tänk på att bilen ska tas
bort både från sidan och "servern" (se
[serverStub.deleteCar()](server_stub-docs/docs/serverStub.html#deleteCar)).
D.v.s. att bilen ska försvinna från listan och ifall användaren uppdaterar billistan ska den borttagna
bilen inte komma tillbaka.
__Tips:__ Fär att få med data från elementet som är klickat på kan ni
lägga till ett data-attribut på elementet (knappen/länken/ikonen) på följande sätt:

I exemplet ovan används ett a-element, men det går självklart att
applicera samma princip på andra typer. `$(this)` är i detta fall
a-elementet som triggar eventet.
__Tips:__ Eftersom ni antagligen skapar knappen för borttagning
av bilar efter att er övriga Javascript har körts behöver ni lyssna på mer generella events (se [jQuery-metoden on()](https://api.jquery.com/on/)), alternativt
se till att ni börjar lyssna efter exempelvis klick-event efter
att elementet har skapats.
8. Skapa ett redigeringsformulär för bilar som visas när användaren
klickar på redigeringsalternativet för en specifik bil. Detta formulär
ska visas i en [Modal](https://getbootstrap.com/docs/4.4/components/modal/)
och innehålla fält för varje attribut för en bil.
När användaren skickar formuläret ska ändringarna synas i bil-listan automatiskt.
Fälten i formuläret ska automatiskt förifyllas med den befintliga
datan för bilen i fråga. Läs mer om hur ni kan sätta innehåll i
modals dynamiskt i
[Bootstraps dokumentation](https://getbootstrap.com/docs/4.4/components/modal/#varying-modal-content).
9. Gör det även möjligt att lägga till bilar. Förslagsvis genom
att lägga till en knapp som kan öppna en modal liknande den för redigering.
När en bil läggs till ska den bli synlig i listan automatiskt.
## Redovisning:
Följ [instruktionerna för "Redovisning"](inlamning-och-git#redovisning).
Sidansvarig: Martin Sjölund
Senast uppdaterad: 2021-02-08