Kommunikation och Användargränssnitt TNM040 AngularJS Laboration 2 Per Lind perli379@student.liu.se 2016-09-27
Introduktion Målet med denna laboration är att göra egna layouts i Bootstrap och att använda Angular för att animera användarens interaktioner med sidan. Bootstrap Vi använder Bootstrap för att det använder ett grid-system som är enkelt att lära och låter oss snabbt bygga responsiva layouts anpassade till olika skärmstorlekar. Vad ska vi göra i labben? Vi ska utgå från den single-page app vi gjorde i laboration 1 och göra ett nytt användargränssnittet till den. Det kommer alltså handla om att designa ett grafiskt användargränssnitt i Bootstrap. Vi ska också använda nganimate för att skapa animationer när vi får indata från användaren. Vad behövs? Ni behöver ha gjort laboration 1 så att ni har en kodbas att utgå ifrån. Hur går vi tillväga? Precis som föregående laborationen bör denna göras i grupper av inte mer än två personer per dator. Det blir enklaste om ni redovisar alla delar på samma gång när ni känner er klara.
Uppgift 1: Bootstrap navbar med collapse Ni ska redan ha lagt till en navbar, nu ska vi bara se till att den är responsiv och kollapsar när skärmen är smalare än 768px. För att kunna visa dess kollaps-funktionalitet så måste vi förutom bootstrap.css också inkludera bootstrap.js vilket innehåller deras collapse plugin. Det är den som lägger till och tar bort de CSS klasser som får menyn att visas och döljas av knappen. http://getbootstrap.com/javascript/#collapse Det är attributen data-toggle och data-target som låter oss lägga till eller ta bort CSS klasserna. Data-target ger vi id selector för det element vi vill använda collapse på. Det skulle alltså räcka att bara lägga till dessa två attributen. De CSS klasser som lagts till som heter collapse, navbar-collapse och collapsed är alltså inte nödvändiga men används för att sätta utsprungligt state och för att style:a menyn. <nav class="navbar navbar-default"> <div class="container-fluid"> <!-- menyn ska ta upp 100% width --> <!-- navbar header --> <div class="navbar-header"> <a class="navbar-brand" href="#!/">angular-lab</a> <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#menu" aria-expanded="false"> <span class="sr-only">toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> </div> <!-- Navbarens innehåll --> <div class="collapse navbar-collapse" id="menu"> <ul class="nav navbar-nav"> <li><a href="#!/weather"">väder</a></li> <li><a href="#!/forecast">prognos</a></li> </ul> </div><!-- /.navbar-collapse --> </div><!-- /.container-fluid --> </nav> Uppgift 2: Välj layout.container eller.container-float Första saken ni borde välja är om ni ska använda en 100% width layout eller om ni vill ha fix bredd på era views. Det här är en smaksak så det är upp till er. Använd en av klasserna container och container-float på erat ng-view direktiv i index.html. Uppgift 3: Välj utseende på weather.html Vi ska börja med att göra en layout för mobiler, detta gör vi i Bootstrap med hjälp av utility klasser med namnet *-xs som låter oss bestämma vilka HTML element som ska visas eller
döljas för skärmar som är mindre än 768 pixlar i bredd. http://getbootstrap.com/css/#responsive-utilities Exempel: <div class="hidden-xs col-sm-9"> <forecast-details forecast="currentforecast"></forecast-details> </div> Om vi vill dölja ett element kan vi använda hidden-xs, så att det inte syns på mobiler. Om vi istället skulle visa endast på mobil skulle vi använda visible-xs-block eller visible-xs-inline. Börja med göra en layout som ser bra ut för breakpoint xs, gå sedan över till breakpoints sm, md och till sist lg. Det finns inga rätt eller fel här så det är egentligen upp till er att tänka ut hur ni vill strukturera saker på sidan och sedan positionera dom på så vis med col-*-* klasser. http://getbootstrap.com/css/#grid-media-queries För att få lite inspiration kan ni se dessa exempel: http://www.w3schools.com/bootstrap/bootstrap_templates.asp http://getbootstrap.com/getting-started/#examples http://getbootstrap.com/examples/grid/ Uppgift 4: Välj utseende på forecast.html Lägg några minuter på att fundera ut på vilket sätt ni vill presentera väderdatan. Kanske vill ni ersätta HTML-mallen för direktivet ni skrev med andra boostrap komponenter istället för panel, kanske med well, label, jumbotron, carousel eller kanske bara en tabell? Gör dom ändringar ni vill, gå sedan över till att strukturera upp layouten för de olika breakpoints så som ni gjorde i den första vyn. Tänk på att börja med att få layouten att se bra ut för skärmar mindre än 768px i bredd och sedan jobba uppåt i storlekarna. När ni fått layouten att anpassa sig väl till samtliga skärmstorlekar och är nöjda med resultatet kan ni gå vidare. Uppgift 5: Typsnitt Bootstrap-teman sätter en standard font-family på sidans body element. Vill man ersätta detta typsnittet har man ett val, det första alternetivet är att skapa ett custom bootstraptema och ändra vilken font-family som används. http://getbootstrap.com/customize/
Det andra alternativet är att helt enkelt sätta ett style-attribut på body och skriva över den font-family som Bootstrap använder. Det första alternetivet är i de flesta sammanhang bättre, fast för enkelhetens skull rekommenderas att ni i det här fallet skriver över värdet. När vi ska välja vilken annan font som ska användas så har vi ytterligare ett val att göra. Antingen använder vi de system-fonter som finns i alla webbläsare eller så länkar vi in en webfont. Här finns en lista på system-fonter: http://www.w3schools.com/cssref/css_websafe_fonts.asp Om ni vill använda webfonter istället så har google ett snabbt och smidigt system: https://fonts.google.com/ Nackdelen med att använda webfonter är att dessa måste hämtas ner och vissa webbläsare använder sin fallback font under tiden, så på dessa system kan användaren uppleva ett hack när den byter mellan fonterna efter sidan laddats klart. Detta är inte ett jätte problem men något som man kan vara medveten om. Er uppgift är att bytta ut "Helvetica Neue" som är standrad font-family och istället använda någon annan eller några andra typsnitt. Uppgift 6: Ikoner Bootstrap kommer med ett paket font-ikoner som kallas glyphicons. Dessa går bra att använda out-of-the-box. http://getbootstrap.com/components/#glyphicons-glyphs Två andra populära uppsättningar font-ikoner finns här: http://fontawesome.io/ https://google.github.io/material-design-icons/#icon-font-for-the-web (För att länka in font awesome ikoner kan ni använda cdn: https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.6.3/css/font-awesome.min.css) Välj någon av de tre ikon paketen. Vi ska nu lägga in några ikoner på sidan, förslagsvis kan vi lägga in ikoner i navbaren. Font-awesome ikonerna fa-sun-o och fa-binoculars.
Uppgift 7: Bootstrap-tema Det finns flera sätt att ändra bootstrap temat, eftersom vi inte kan använda några csspreprocessors i datorsalarna så kan vi inte hämta ner Bootstraps LESS fil, göra ändringar och generera ut en egen CSS. Så det enklaste blir då att använda getbootstraps egna verktyg (http://getbootstrap.com/customize/) eller leta upp ett bootstrap-tema CSS tema online att utgå ifrån. Det finns många alternativ, https://bootswatch.com/ har bra teman som är testade och fungerar. Det är bara att byta ut bootstrap.css och de är alla hostade på cdn så det är väldigt smidigt att inkludera https://www.bootstrapcdn.com/bootswatch/. Andra sidor som https://startbootstrap.com/ har även dom custom CSS filer fast de finns oftast inte tillgängliga från cdn, utan man får då hämta ner filerna och hosta dem själv på sin egna webserver. Välj ut något tema vara sig det är ett anpassat vanilla bootstrap tema eller bootswatch. Navigera runt på sidan och försäkra er om att det ser ut som ni vill. Om det är några visuella fel så kan ni fixa dessa med att skriva rätta de värden som är fel i ett CSS fil som ni läser in i index.html efter er bootstrap.css. new-age.css https://startbootstrap.com/template-overviews/new-age/
Uppgift 8: Animera ng-view I föregående laboration så la vi till ytterligare en sida så vi har två vyer vi kan gå emellan. Nu är tanken att vi lägger till en transition, en animation som körs när man byter mellan vyerna. Förslagsvis en fade-in eller slide-in. För att kunna göra några animationer över huvud taget så måste vi först se till att vi har angular-animate.js i index.html och så måste vi komma ihåg att lägga till nganimate som beroende i myapp-modulen. Jag kommer visa ett exempel på hur man kan göra en fade-in med en CSS3 animation som använder keyframes. Det första som vi behöver göra är som alltid lägga till en klass på det element vi vill animera. I detta fallet så är det elementet som har ng-view direktivet. <div ng-view class="view-frame container"></div> Vi kan kalla klassen view-frame så vi vet vilket element vi animerar. Ni kan se en tabell över vilka animationer som olika direktiv har här: https://docs.angularjs.org/guide/animations#which-directives-support-animationsngview har enter och leave event hooks, detta innebär att de kommer lägga till klasserna ng-enter och ng-leave när dessa event triggas. Så vi skapar en ny css fil för att göra animationer, vi kan kalla den app.animations.css och samla alla CSS animationer där för enkelhets skull. Så innan vi börjar skriva någon CSS så får vi komma ihåg att lägga till det nya stylesheet:et i index.html. Här följer ett förslag på fade-in animation:.view-frame { background: transparent; position: absolute; left: 0; right: 0; top: 72px; /* offset navbar height + margin */ /**** ng-view animation *****/.view-frame.ng-enter { animation: 0.5s fade-in; animation-timing-function: ease-in;.view-frame.ng-leave { animation: 0.4s fade-out; animation-timing-function: ease-out; @keyframes fade-in { from { opacity: 0; to { opacity: 1;
@keyframes fade-out { from { opacity: 1; to { opacity: 0; /*****************************/ Gör något liknande eller någon helt annan animation, för exempel på hur man skriver CSS3 animationer titta på w3schools: http://www.w3schools.com/cssref/css3_pr_animation.asp http://www.w3schools.com/cssref/css3_pr_transition.asp Vill ni ha några andra ease-funktioner utöver de vanliga kan ni hitta några förslag här: http://easings.net/ Om ni är osäkra på hur cross-browser stödet för några CSS3 eller HTML5 features ser ut (t.ex. CSS3 transform) så rekommenderas sidan http://caniuse.com/. Det är en extremt användarbar resurs när man funderar på om man borde använda en webbteknik. För att göra nästa uppgift så bör ni ha kopplat ihop select-elementet i forecast.html så att datan som visas uppdateras. Har ni gjort detta kan ni fortsätta till uppgift 8. Ifall ni inte har kopplat ihop select-elementet i forecast.html så att er controller ändrar värdet på $scope.weatherdata, så behövs det göras nu. Deklarera en funktion i er controllers $scope och anropa den med ng-change direktivet på selectelementet. ng-change direktivet kommer anropa funktionen den tilldelats när värdet i ng-model ändras. Detta innebär att ng-change kräver att vi också använder ngmodel på samma element. Ni kan se hur det gjordes i weather.html och weather.js. Uppgift 9: Animera direktiven i forecast.html Direktivet forecast-detail som ni skrev i förra labben ska vi nu animera. I forecast.html så bör ni ha något som ser ut ungefär så här: <div class="col-sm-12" ng-if="weatherdata.forecast[0]"> <forecast-details forecast="weatherdata.forecast[0]"></forecast-details> </div> Vi har ett ng-if direktiv för att visa första datamedlemmen dvs. måndagens väder. ng-if har två events, enter och leave. När ng-if= true så triggas enter-eventet och klassen ng-enter läggs till på det. Och motsatt så när ng-if= false så triggas leave och ng-leave klassen läggs till. Vi gör precis samma sak som när vi animerade ng-view, lägg först till en klass på elementet med ng-if. Ge den klassen ett bra namn så ni vet vad den gör, t.ex. first-forecast.
När ni är klara med att animera ng-if så kan vi gå vidare och animera ng-repeat. Det är precis likadant som föregående uppgifter fast denna har tre event; enter, leave och move. Move-eventet triggas om någon post i listan skulle tas bort, ett exempel är om man skulle filtrera ut datan med ett sökfält. I vårt fall kommer inte move eventet att triggas om ni inte lägger till nytt beteende I ForecastController. Som tidigare lägg till en ny CSS klass på ng-repeat direktivet. <div class="col-sm-12 col-md-6 col-lg-4 forecast-item" ng-repeat="forecast in weatherdata.forecasts" ng-if="$index > 0"> <forecast-details forecast="forecast"></forecast-details> </div> Vi kan kalla den nya klassen forecast-item. Nu är det upp till er att välja någon typ av animation. Istället för att använda css3 animation testa att göra något med transition. Ett till exempel:.forecast-item.ng-enter,.forecast-item.ng-leave,.forecast-item.ng-move { transition: 0.6s cubic-bezier(0.175, 0.885, 0.32, 1.275) all; /*Start with no height and no opacity*/.forecast-item.ng-enter,.forecast-item.ng-move { opacity:0; top: 120px; left: 0; right: 0; /*Fade-in and increase height*/.forecast-item.ng-enter.ng-enter-active,.forecast-item.ng-move.ng-move-active { opacity:1; top: 0; left: 0; right: 0; Uppgift 10: Active klass på navbar Detta är en frivillig uppgift. När man har valt en route så vore det trevligt om man markerade posten i navbarens lista med klassen active. Det smidigaste sättet att lägga till klassen är med ng-class direktivet vilket låter dig sätta upp ett vilkor för när en klass ska fästas på elementet. Vi ska skriva en funktion som matchar url routen med ett värde som vi skickar in. Detta gör vi i en controller som vi kopplar till navbaren med ng-controller.
<ul class="nav navbar-nav" ng-controller="menuctrl"> Skapa klassen menu.controller.js angular.module('myapp.menu', []); angular.module('myapp.menu').controller('menuctrl', ["$scope", "$location", function($scope, $location) { $scope.isactive = function(path){ return $location.path() == path; ]); Använd nu den nya isactive metoden i listan med routes. <li ng-class="{'active': isactive('/forecast')"><a href="...">prognos</a></li>