Skip to content

Releases: marcocasario/codemotion2014

MVC + RequireJS

08 Apr 14:30
Compare
Choose a tag to compare

Nuova release che prevede l'inclusione di RequireJS ed un approccio MVC sulla realizzazione delle pagine del sito web.

Il file js/main.js contiene tutte le informazioni su come inizializzare l'applicazione.

Webstorage & XHR2

02 Apr 09:46
Compare
Choose a tag to compare

Webstorage API - Communication API - Networking API

In questa esercitazione vedremo come funzionano e come applicare le Webstorage API, combinandole con le nuove XHR2 e le Networking API.

Utilizzeremo l'oggetto localstorage per storicizzare dati all'interno del browser.
Vedremo come funziona il caricamento di un'immagine trascinandola all'interno della pagina web dal proprio desktop.
Alla fine utilizzeremo le librerie per controllare lo stato della connessione per capire come prevenire eventuali perdite di dati.

Step 1. Predisposizione

Per avere una situazione stabile e funzionante puoi aggiornare il tuo sorgente direttamente da questo comando:

# !bash
# git checkout webstorage-dev

Git tiene traccia di tutte le modifiche fatte in locale, quindi per cambiare ramo dobbiamo prima annullare tutte le modifiche fatte sui file che abbiamo modificato con il comando:

# !bash
# git checkout *

Se vuoi mantenere le modifiche fatte, fai commit delle tue modifiche oppure clona il progetto in una nuova cartella!
se invece hai creato nuovi file, devi prima cancellarli.

Se non vuoi utilizzare git puoi scaricare l'archivio zip da qui: https://github.com/marcocasario/codemotion2014/tree/webstorage-dev


Webstorage API

Step 1. Utilizziamo le HTML5 Webstorage API

La nostra pagina dei contatti deve contenere nella parte centrale il form per l'inserimento dei dati anagrafici.
Aggiungiamo il form utilizzando i nuovi input type di HTML5:

Elenco dei campi:

  • input type text class="input" id="firstname" name="firstname" il deve essere obbligatorio, possiamo eventualmente anche aggiungere l'autofocus
  • input type email class="input" id="email" name="email" il campo deve essere obbligatorio
  • input type data class="input" id="born" name="born" il campo deve essere obbligatorio
  • input type text class="input" id="topic" name="topic" il campo deve essere obbligatorio, in questo caso implementare anche un oggetto di tipo datalist
  • textarea class="textarea" id="note" name="note" il campo deve essere obbligatorio

per maggiori informazioni sui nuovi input type di HTML5 puoi consultare questo link http://www.w3.org/html/wg/drafts/html/master/forms.html

<form id="form" class="form_box">
    <fieldset class="fieldset">
        <ol>
            <li class="left">
                <label class="label" for="firstname">Name *</label><br>
                <!-- input => firstname -->
            </li>
            <li class="right">
                <label class="label" for="email">Email *</label><br>
                <!-- input => email -->
            </li>
        </ol>
    </fieldset>
    <fieldset class="fieldset">
        <ol>
            <li class="left">
                <label class="label" for="born">Date of birth *</label><br>
                <!-- input => born -->
            </li>
            <li class="right">
                <label class="label" for="topic">Topic *</label><br>
                <!-- datalist => topic -->
            </li>
        </ol>
    </fieldset>
    <fieldset class="fieldset">
        <ol>
            <li class="left">
                <label class="label" for="note">Note *</label><br>
                <!-- textarea => note -->
            </li>
        </ol>
    </fieldset>

    <fieldset class="fieldset">
        <button class="submit" type=submit>Send</button>
    </fieldset>
</form>

Aggiorniamo il browser, il risultato dovrebbe essere simile a questo:
form_html

Step 2. Implementiamo quindi la nuova funzione saveUser:

/* Gestisce il salvataggio al click dell'utente sul tasto send del form */
function saveUser (e){
    e.preventDefault();
    //se i dati vengono popolati con successo, inviamo la richiesta al servizio
    if ( userModel.setData($(this).serializeArray())){
        saveLocalstorageData();
    }
}

La funzione saveUser, viene chiamata al click sul tasto send (utilizzando jQuery).
La funzione saveUser() quando invocata richiama le seguenti funzioni:

userModel.setData();
saveLocalStorageData();

e.preventDefault() serve per bloccare il comportamento di default del browser al submit del form.
In alcuni casi (es: IE < 9) potrebbe essere necessario anche un return false;

Step 3. Iplementiamo l'oggetto userModel()

Aggiungiamo la seconda nostra funzione al file contact.js

/* Oggetto UserModel() */
function UserModel() {
    //controlla se la variabile data è valorizzata altrimenti la inizializza come oggetto vuoto
    if ( !isNotNull( data )){
      var data = {};
    }
    //metodo setData()
    this.setData = function ( newData ){   
        if (newData && newData.length > 0){
            //se newData e' di tipo array (serializzato dal form)
            //valorizziamo data con tutti gli elementi del form che sono stati inviati
            for (var i = 0; i < newData.length; i++){
                data[newData[i].name] = newData[i].value;
            }
        }else if ( isNotNull( newData ) ){
            //se newData non e' un array valorizziamo data con newData
            data = newData;
        }else {
            //altrimenti mostriamo un errore in console
            console.log('Errore....');
            return false;
        }
        return true;
    };

    //Restituisce l'oggetto data
    this.getData = function (){
        return data;
    };
    return this;
}

Questa funzione utilizza un metodo non nativo di Javascript isNotNull, questo metodo è definito all'interno del file js/main.js.

L'oggetto UserModel espone due metodi:

  • setSata
  • getData

Il primo valorizza l'oggetto data, il secondo lo restituisce.

Step 4. Aggiungiamo la funzione saveLocalstorageData()

Aggiungiamo la terza funzione al file contact.js, questa funzione scrive i dati all'interno del browser.

//salva i dati nel LocalStorage
function saveLocalstorageData( ){
    console.log('Salvataggio dei dati utente', userModel);
    //utilizza l'oggetto localStorage per salvare i dati all'interno del browser
    localStorage.setItem('userData', JSON.stringify(userModel.getData()))
    return true;
}

L'oggetto localStorage espone due metodi usati da questo esercizio:

  • setItem
  • getItem

In questa funzione, utilizzeremo localStorage.setItem(), è possibile sperimentare cambiando l'oggetto localstorage con sessionStorage.

Per maggiori informazioni sulle API: http://www.w3.org/TR/webstorage/

A questo punto non ci resta che inizializzare il nostro oggetto UserModel ed aggiungere un evento al submit del form.

//inizializziamo il modello
var userModel = new UserModel;
//aggiungiamo l'evento al submit
$('#form').submit(saveUser);

in chrome apriamo i Developer Tools, facciamo click sulla scheda Resources. il risultato dovrebbe essere molto simile a questo:
risultatowebstorage

Step 5. Recupero dei dati

Una volta salvati i dati, quando rientriamo all'interno del form ancora non vengono recuperati.

Per recuperare i dati è molto semplice:

Creiamo una nuova funzione, che sarà richiamata ogni volta al caricamento della pagina:

function getUserInformation (){
    //richiediamo i dati all'oggetto e popoliamo il model
    var response = localStorage.getItem('userData');
    userModel.setData( JSON.parse(response) );
    setFormData( userModel );
}

Aggiungiamo la funzione che si occupa quindi di popolare il form direttamente dai localStorage.

function setFormData (){
    //recuperiamo le informazioni dal datamodel
    var data = userModel.getData();
    //se l'oggetto è valorizzato aggiungiamo i valori agli input del nostro form
    if (isNotNull( data )) {
        $('#firstname').val( data.firstname );
        $('#email').val( data.email );
        $('#born').val( data.born );
        $('#topic').val( data.topic );
        $('#note').val( data.note );
    }
}

Il metodo getUser() deve essere richiamato subito dopo la creazione del model

//inizializziamo il modello
var userModel = new UserModel;
//recuperiamo i dati dall'oggetto localStorage
getUserInformation();
//aggiungiamo l'evento al submit
$('#form').submit(saveUser);

Una volta salvati i dati all'interno dell'oggetto sessionStorage, al caricamento della pagina se questi dati sono presenti, il codice che abbiamo appena implementato li recupera e li inserisce per noi all'interno del form.

form_reload


Communication API

Step 1. Aggiungiamo i nuovi oggetti all'interno del form:

<fieldset class="fieldset">
    <ol>
        <li class="left" id="upload">
            <label class="label" for="fileupload">Allega la tua foto</label><br>
            <div id="holder"></div> 
            <p id="upload" class="hidden"><label>Drag & drop non supportato, ma puoi comunque inviare la tua foto:<br><input type="file" id="fileupload" name="fileupload"></label></p>
            <p id="filereader">File API & FileReader API non supportati</p>
            <p id="formdata">XHR2's FormData non è supportato</p>
            <p id="progress">XHR2's upload progress non supportato</p>
            <p>Trasferimento: <progress id="uploadprogress" min="0" max="100" value="0">0</progress></p>
            <p>Trascina e rilascia un'immagine dal tuo desktop nell'area tratteggiata.</p>
        </li>
    </ol>
</fieldset>

All'interno del codice troviamo un nuovo fieldset che serve per ospitare il drag&drop.
L'elemento più importante è holder, questa sarà l'area visibile dall'utente dove poter rilasciare l'oggetto trascinato dal proprio browser.
Gli altri elementi servono per effettuare dei test lato javascript e mostrare i rispettivi messaggi, diversi in base al browser che stiamo usando.

Ag...

Read more

Websocket API

02 Apr 09:47
Compare
Choose a tag to compare

Websocket API

In questa esercitazione vedremo come utilizzare le connessioni Websocket di HTML5 realizzando una chat.

Step 1. Predisposizione

# git checkout webstorage-dev

facciamo partire il server!

per fermare l'istanza precedente, premi 'CTRL+C'.

Step 2. Il modulo nodejs-websocket

La versione del server realizzato in node js, in questo esercizio deve essere modificata.
La prima versione rispondeva alla porta indicata oppure alla porta 8888.
In questo caso dobbiamo creare una nuova porta, che ci consenta di aprire una connessione websocket con il client che apre la pagina web.

Installiamo il nuovo modulo

Per poter funzionare, il server websocket ha bisogno di un nuovo modulo, che non è installato di default da node.js.
Direttamente da command line, installiamolo utilizzando il gestore di pacchetti npm di nodejs:

# npm install nodejs-websocket

Per verificare che tutto sia andato a buon fine, all'interno del nostro progetto è stata creata una nuova cartella node_modules. Al suo interno è stata creata un'altra cartella nodejs-websocket.

node_modules

Step 3. Il codice HTML

Creiamo una nuova area dove saranno visualizzati i messaggi, sostituiamo l'attuale

<section class="banner_section"></section>

con il seguente codice:

<section id="support_section" class="support_section text_style">
    <div class="welcome_message_area">Benvenuto, il supporto tecnico ti fornirà le informazioni necessarie per ogni tua esigenza.</div>
    <div class="title_message_area hide">Dashboard</div>
    <ul class="message_area"></ul>
</section>

All'interno del nostro

inseriremo invece le informazioni necessarie per dare la possibilità all'utente di scegliere un nickname e una volta effettuato il "login" di inviare un nuovo messaggio.

Ecco il codice per fare il login:

<article class="article clearfix nickname_area">
<form id="form_nickname" class="form_box">
    <fieldset class="fieldset">
        <ol>
            <li class="left">
                <label class="label" for="nickname">Nickname *</label><br>
                <input class="input" id="nickname" name="nickname" type="text" placeholder="Inserisci il tuo nickname" required autofocus>
            </li>
            <li><br><button class="submit" type=submit>Send</button></li>
        </ol>
    </fieldset>
</form>
</article>

Aggiungiamo subito dopo anche il codice per scrivere un nuovo messaggio:

<article class="article clearfix send_message_area hide">
    <form id="form_message" class="form_box">

        <fieldset class="fieldset">
            <ol>
                <li class="left">
                    <label class="label" for="message">Inserisci il messaggio</label><br>
                    <input class="input" id="message" name="message" type="text" placeholder="nuovo messaggio" required autofocus>
                </li>
                <li><br><button class="submit" type=submit>Send</button></li>
            </ol>
        </fieldset>
    </form>
</article>

I moduli appena inseriti sono dei semplici input type:text con relativo submit per inviare i dati al server.

Effettuati questi passaggi il risultato ottenuto sarà molto simile a questo:

websocket_1

Step 4. Modifichiamo il css

aggiungiamo una nuova regola per il contenitore ed il box che ospiterà i messaggi che arrivano dal server.

.support_section { width: 880px; height: 200px; padding: 0 40px; background: #fff; }
.message_area{ height: 150px }

Aggiungiamo gli stili che devono essere associati ai form nickname e new message:

.support_section .form_box { padding: 0 10px; }
.support_section .form_box .input { width: 268px; }
.support_section .form_box .submit { width: 298px; float: none; }

websocket_2

infine aggiungiamo tre semplici classi per cambiare il colore dei messaggi che appariranno in base al tipo di informazione visualizzata.

.user_message{ list-style: none; margin-bottom: 10px; border-bottom: 1px solid #e8e8e8;}
.in{color: green;}
.out{color: red;}
.msg{ color: #888888; }

Step 4. Implementiamo il nostro codice javascript

Apriamo il file js/helpdesk.js

Cominciamo con il definire l'oggetto che si occuperà di gestire la nostra micro applicazione help-desk:

//inizializziamo app
var app = {
    connection: {}, 
    nickname: '',
    status: 'closed'
};

In questa occasione, utilizziamo Modernizr per controllare se è disponibile la connessione websocket.
Creiamo quindi una nuova parte di codice che sarà istanziata non appena il documento è pronto utilizzando jQuery:

$(document).ready( function (){

    if (!Modernizr.websockets) {
      alert("No WebSocket here");
    }

});

Aggiungiamo quindi dopo il controllo il codice per intercettare l'evento al submit del form relativo al nickname:

//form event submit
$('#form_nickname').submit(function (event) {
  //evitiamo il submit del form
  event.preventDefault();

  if ( setNickname() ){
    hide( $('.nickname_area') );
    show( $('.send_message_area') );
    setWSConnection();
  }

  //evitiamo il submit del form
  return false;
});

Fatto questo, possiamo aggiungere anche l'evento al submit del form per l'invio del messaggio:

$('#form_message').submit(function (event) {
   //evitiamo il submit del form
   event.preventDefault();
   sendWsMessage();
   //evitiamo il submit del form
   return false;
});

Se ci concentriamo sul codice scritto per l'invio del form relativo al nickname, possiamo notare come prima della funzione setWSConnection() venga richiamata la setNickname(), vediamo di seguito cosa fa:

//valorizza l'oggetto app.nickname
function setNickname(){
  var newNickname = $('#nickname').val();
  if ( isNotNull( newNickname ) && newNickname.length > 3){
    app.nickname = newNickname;
    return true;
  }
  return false;
}

Valorizza il nostro oggetto app.nickname, con il nickname scelto dall'utente.

A questo punto possiamo occuparci della setWSConnection():

// funzione che si occupa dell'invio dei messaggi al server websocket.
function setWSConnection(){
  if (isNotNull( app.nickname )){

    clearDomMessages();

    app.connection = new WebSocket("ws://"+window.location.hostname+":8890")
    app.connection.onopen = function () {
        console.log("Connection opened");
        app.connection.send(app.nickname);
        app.connection.status = 'open';
    }
    app.connection.onclose = function () {
        var newMessage = {"status":"out", "msg": "connection closed", "time": new Date()};
        setDomMessage(newMessage);
        app.connection.status = 'close';
    }
    app.connection.onerror = function () {

        var newMessage = {"status":"out", "msg": "Connection error", "time": new Date()};
        setDomMessage(newMessage);
        app.connection.status = 'close';

    }
    app.connection.onmessage = function (event) {
        setDomMessage(event.data);
    }
  }   
}

A questo punto completiamo il nostro script con le funzioni richiamate dalla

//pulisce l'area messaggi alla prima connessione dell'utente.
function clearDomMessages(){

  $('.welcome_message_area').hide();
  $('.title_message_area').show();
  $('.message_area').empty();

}
//scrive i messaggi che arrivano dal server mentre la connessione websocket resta in ascolto
function setDomMessage( message ){

    var newMessage = jQuery.parseJSON( message ),
    element = document.createElement('li'),
    domElement = $('.message_area'),
    time = '';

    function getTime(){
      var newTime = new Date(newMessage.time);
      return newTime.getUTCHours()+":"+newTime.getUTCMinutes();
    }

    time = getTime();

    element.className = 'user_message'+' ' + newMessage.status;

    element.appendChild (document.createTextNode("["+time+"] " + newMessage.message) );

    domElement.append( element );
    domElement.animate({'scrollTop': domElement[0].scrollHeight});

}
//chiude la connessione al server webSocket
function closeWSConnection(){
  if (app.connection.status === 'open'){
    app.connection.close();
    app.connection.status = 'closed';
  }
}
// funzione per inviare i messaggi al server WS
function sendWsMessage(){

    var message = $('#message').val();
    if ( isNotNull( message )){
        console.log('Invio del messaggio al server: ' + message);
        app.connection.send(message);
        $('#message').val('');
    }

}

Login degli utenti

websocket_login

Nuovo messaggio

new_message

Logout degli utenti

websocket_logout

RWD - Responsive Web Design

28 Mar 11:24
Compare
Choose a tag to compare

Installare ed usare il mediaBookmarklet

Il mediaQuery Bookmarklet è uno strumento utile in fase di progettazione e di test delle mediaqueries.

Step 1. Installare mediaQuery bookmarklet

Il tool funziona su:

  • Chrome 9+
  • Safari 5.1.5
  • iOS 5.1.1

Aggiungere un nuovo bookmark con il seguente contenuto:

javascript:%20(function%20()%20{var%20jsCode%20=%20document.createElement(%27script%27);jsCode.setAttribute(%27src%27,%20%27http://sparkbox.github.com/mediaQueryBookmarklet/bookmarklet-js/mediaQueryBookmarklet.js%27);document.body.appendChild(jsCode);}());

add bookmark

Oppure, a questo indirizzo trovi la pagina ufficiale per installare il tool.

Una volta aggiunto sulla barra, per utilizzarlo sarà sufficiente cliccare sul link. Così facendo il tool verrà immediatamente eseguito.

Step 2. Usare il bookmarklet

Una volta lanciato il bookmarklet mostrerà una nuova "finestra" sul browser con le informazioni riguardo la dimensione in pixel della finestra del browser, la posizione del mouse in coordinate x e y, e il valore del min-width espresso in em.

Bookmarklet in action

Cambiando la dimensione della finestra i valori nel box cambieranno di conseguenza. Questo tool ci permetterà, in fase di progettazione del sito, di capire a che risoluzioni applicare le mediaquery, ed in fase di test di vedere con precisione quando le mediaqueries verranno applicate

Step 3. Ulteriori tool per il responsive

Segue una lista di tool utili per lo sviluppo con le mediaquery:

RWD Bookmarklet

Viewport Resizer

Crome Window Resizer

Resizer


Analisi della pagina alle basse risoluzioni

L'approccio mobile first (o mobile up) è quello che parte dalla progettazione della pagina alle basse risoluzioni per vedere come si comporta il contenuto.

Step 1. Aprire la pagina

Aprire nel browser la pagina index.html

Aprire il codice sorgente e studiare velocemente la struttura semantica della pagina.

Analizzare come la pagina si comporta all'interno del browser.

Step 3. mediaQuery bookmarklet in azione

Lanciare il bookmarklet. Comparirà un box in alto a sinistra con le informazioni riguardo la dimensione in pixel della finestra del browser, la posizione del mouse in coordinate x e y, e il valore del min-width espresso in em.

Step 4. Analisi del comportamento alle basse risoluzioni

La pagina che stiamo visualizzando non ha nessuna specifica impostata relativa alla media query.

Portiamo alla risoluzione più bassa (almeno 400px) restringendo la finestra del browser e leggendo i valori nel box del mediaQuery tool.

Definiamo quindi i seguenti punti

  • cosa deve succedere al sito quando visualizzo la pagina con risoluzioni basse.
  • qual'è il suo comportamento.
  • come si deve disporre il contenuto.

Step 5. Implementiamo il comportamento desiderato del contenuto alle basse risoluzioni

Una volta definito in che modo pa pagina dovrà visualizzarsi all'interno del browser, si comincia con la progettazione della prima media query, quella che definirà come il contnenuto dovrà disporsi nella viewport del browser.

Applichiamo le media query per smartphone

Stiamo usando l'approccio Mobile First (o Mobile Up) e partiamo quindi dalla risoluzione più bassa.La prima media query che vogliamo intercettare è quella che scatta dalla risoluzione più bassa alla risoluzione massima di 479px.

Step 1. Cominciamo inserendo alla fine del file style.css il blocco che mi permette di definire gli statement CSS per la media query:

/***** Media Queries *****/
/* Small screen */
@media only screen and (max-width: 479px) { 

}

Al suo interno cominciamo ad implementare le istruzioni per definire il comportamento dei componenti principali:

  • container
  • header
  • main_section
  • aside
  • footer

Step 2. Specifichiamo al suo interno le seguenti proprietà

Una volta aggiunta la media query che scatterà non appena la risoluzione andrà sotto i 479px, possiamo comunicare al browser cosa dovrà accadere.

Il layout a questa risoluzione deve svilupparsi verticalmente, con tutti gli elementi renderizzati uno sotto l'altro. Cominciamo nascondendo gli elementi come menù e banner che non devono essere visualizzati da un device come lo smartphone applicando il "display:none;"

#header #nav ul { display: none; }
.banner_section { display: none; }

Modifichiamo quindi anche la dimensione del contenitore della nostra pagina.

#container { width: 320px; box-shadow: none; }

Salva ed aggiorna la pagina per visualizzare i cambiamenti

Il risultato ottenuto dovrebbe essere molto simile a questo:
parte1

Step 3. Definiamo per gli elementi la nuova dimensione e gli allineamenti da rispettare:

Diamo le nuove dimensioni al container principale all'header ed al footer:

  #header { width: 300px; height: 80px; padding: 0 10px; }
  #header .logo { 
    background: url('../img/logo_small.png') center center no-repeat; 
    width: 130px; 
    height: 42px; 
    text-indent: -9999px; 
    float: left; 
    margin: 0 auto; 
    float: none; 
    padding-top: 40px; 
  }
  #header #nav .menu { 
    display: block; 
    visibility: visible; 
    width: 34px; 
    height: 24px; 
    background: url('../img/menu.png') center center no-repeat; 
    position: absolute; 
    top: 30px; 
    right: 10px; 
    text-indent: -9999px; 
  }

Analizziamo nel dettaglio cosa è cambiato:

  • #header .logo: cambia la dimensione, il formato del logo, i margini e l'allineamento;
  • #header #nav .menu: viene mostrato con i margini e l'allineamento a destra;

Salva ed aggiorna la pagina per visualizzare i cambiamenti
Il risultato ottenuto dovrebbe essere il seguente:
parte2

Step 4. Definiamo ora il comportamento che la parte centrale e della parte destra (aside) del sito web.

.main_section {
  width: 320px;
  float: none;
  padding: 20px 0; 
}
.main_section .article {
  border-bottom: 1px solid #ccc;
  margin-bottom: 40px;
  padding: 0 10px 40px;
}
.main_section .article .figure { display: none; }
.main_section .article h1 { width: 300px; float: none; }
.main_section .article p { width: 300px; float: none; }

Analizziamo nel dettaglio cosa è cambiato con queste modifiche:

  • .main_section: nuove dimensioni, modifica dei margini, ed è stato rimosso l'allineamento.
  • .main_section .article: aggiunto il bordo inferiore, sistemati i margini dell'oggetto
  • .main_section .article .figure: tutte le immagini non vengono renderizzate
  • .main_section .article h1/p: nuova dimensione ed allineamento

Salva ed aggiorna la pagina per visualizzare i cambiamenti

Il risultato dovrebbe essere molto simile a questo:
parte3

Step 4. Aside

Fino ad ora abbiamo lavorato sulla parte superiore e centrale della nostra pagina, il prossimo passo è quello di definire il comportamento della barra destra della pagina.

Il contenuto di essa deve scorrere dopo la parte centrale, quindi definiamo allineamenti e margini, anche in questo caso le immagini non devono essere renderizzate:

#aside { 
  width: 300px; 
  float: none; 
  padding: 20px 10px; 
  border-left: none; 
  border-top: 1px solid #ccc; 
}
#aside .callout_text { 
  float: none; 
  width: 300px; 
  margin-top: 30px; 
}
#aside .callout_text li { margin: 30px 10px; }
#aside .callout_images { display: none; }

Salva ed aggiorna la pagina per visualizzare i cambiamenti
step4

Step 5.

Come ultimo step non ci resta che modificare anche il footer, in questo casolo solo per le dimensioni ed i margini:

#footer { 
  width: 300px; 
  padding: 30px 10px; 
  text-align: center; 
}
#footer .copy { float: none; margin-bottom: 20px; }
#footer .privacy { float: none; }

Salva ed aggiorna la pagina per visualizzare i cambiamenti, in questo modo abbiamo terminato lo sviluppo della versione mobile.

Il risultato del lavoro fatto:
step5

Analisi della pagina per le risoluzioni Tablet e Small Tablet

Come fatto per la sezione smartphone, analizziamo e progettiamo il comportamento della nostra pagina con una risoluzione più grande, decidiamo in che modo il contenuto deve disporsi all'interno della pagina.

Small Tablet

Step.1 Apriamo la pagina

Portiamola alla risoluzione tablet (almeno 600px) restringendo la finestra del browser e leggendo i valori nel box del mediaQuery tool.

Definiamo quindi i seguenti punti:

  • cosa deve succedere al sito quando visualizzo la pagina con una risoluzione simile.
  • qual'è il suo comportamento.
  • come si deve disporre il contenuto.

Step.2 Applichiamo le media query per tablet

Sempre con un approccio Mobile First, la nostra seconda media query che vogliamo intercettare è quella che scatta ad una risoluzione tra 480px e 767px.

/* Small Tablet */
@media only screen and (min-width: 480px) and (max-width: 767px) {

}

Step.3 Applichiamo le modifiche progettate

Come abbiamo già fatto per la parte smartphone, al suo interno implementeremo le istruzioni per definire il comportamento dei componenti pr...

Read more

Geolocation API + Google Maps

28 Mar 16:43
Compare
Choose a tag to compare

Obiettivo del lab: lavorare con le informazioni sulla geolocalizzazione.

Step 1. Predisposizione

In questo lab utilizzeremo le Geolocation API, alcuni browser possono bloccare l'accesso a queste informazioni se effettuiamo l'accesso diretto da file system, quindi avremo bisogno di un server http.

Per avere una situazione stabile e funzionante puoi aggiornare il tuo sorgente direttamente da questo comando:

# !bash
# git checkout geolocation-dev

Git tiene traccia di tutte le modifiche fatte in locale, quindi per cambiare ramo dobbiamo prima annullare tutte le modifiche fatte sui file che abbiamo modificato. con il comando:

# !bash
# git checkout *

schermata 2014-04-07 alle 16 22 12

Se vuoi mantenere le modifiche fatte, clona il progetto in una nuova cartella!
se invece hai creato nuovi file, devi prima cancellarli.

Se non vuoi utilizzare git puoi scaricare l'archivio zip da qui: https://github.com/marcocasario/codemotion2014/tree/responsive-dev

Step 2. Facciamo partire il server!

Con il seguente comando, creeremo un nuovo server http, realizzato direttamente con node.js.

# node server.js

schermata 2014-04-07 alle 16 23 14

Step 3. Lavoriamo con le HTML5 Geolocation API

Apriamo il file js/company.js, ed aggiungiamo una nuova funzione per la nostra pagina web.

/* @company.js */
/* Comincia la nostra applicazione */
function loadDemo() {

}

Al suo interno aggiungiamo il controllo per verificare che il browser supporti le Geolocation API:

/* @company.js */
if(navigator.geolocation) {
}

Inseriamo all'interno del "if" il codice per caricare le informazioni sulla geolocalizzazione dell'utente che sta visitando la pagina utilizzando la funzione:

/* @company.js */
navigator.geolocation.getCurrentPosition(
   function(position) {
      //inserire il codice per aggiornare gli elementi della pagina
   },
   function(error){
      alert('error reported' + error);
   }, {
      enableHighAccuracy: true,
      timeout : 30000
   }
);

Step 4. Modifichiamo il DOM

A questo punto possiamo cambiare il dom del nostro file company.html per ospitare le informazioni che ci arrivano dall'oggetto geolocation.

All'interno della

aggiungiamo dei div specificando una classe/id per ognuno di questi attributi:

  • accuracy
  • altitude
  • altitudeAccuracy
  • heading
  • latitude
  • longitude
  • speed
<!-- @company.html -->
<article class="article clearfix">
<div class="left">Accuracy: </div><div class="accuracy right">0</div><br>
<div class="left">Altitude: </div><div class="altitude right">0</div><br>
<div class="left">Altitude Accuracy: </div><div class="altitudeAccuracy right">0</div><br>
<div class="left">Heading: </div><div class="heading right">0</div><br>
<div class="left">Latitude: </div><div class="latitude right">0</div><br>
<div class="left">Longitude: </div><div class="longitude right">0</div><br>
<div class="left">Speed: </div><div class="speed right">0</div>
</article>

A questo punto all'interno della funzione javascript possiamo utilizzare jquery per popolare la nostra pagina web con le informazioni che ci arrivano dall'oggetto position.

/* @company.js */
$('.accuracy').html( position.coords.accuracy );
$('.altitude').html( position.coords.altitude );
$('.altitudeAccuracy').html( position.coords.altitudeAccuracy );
$('.heading').html( position.coords.heading );
$('.latitude').html( position.coords.latitude );
$('.longitude').html( position.coords.longitude );

Quando sei pronto per fare il primo test, ricorda di aggiungere in fondo al tuo company.js il comando per inizializzare tutta la funzione appena creata.

/* @company.js */
/* Inizializzazione del codice */
loadDemo();

Salva ed aggiorna la pagina http://localhost:8888 il risultato dovrebbe essere il seguente:
browser_question

Cliccando su consenti, daremo tutte le informazioni sulla nostra posizione alla pagina.
Il risultato sarà il seguente:
infodiv

Integriamo le Google API

Step 1. Includiamo le librerie

Includiamo la libreria nel file company.html

<!-- Google Maps: change key to be your site's ID. -->
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyC3nvub6YdbJZLIKdNjcVDfh2vPbI60vus&sensor=false"></script>

Per funzionare, le api di google hanno bisogno di una APIKey, in questo caso è stata generata una generica che trovi già all'interno del codice.

Step 2. Predisposizione dell'area per far ospitare la mappa

Dobbiamo predisporre la nostra pagina HTML ad ospitare la mappa da visualizzare all'interno della pagina.
Sostituiamo la

con il nuovo codice:

<section id="map-canvas" class="map_section"></section>

Aggiungiamo una nuova regola all'interno del nostro css:

.map_section { width: 880px; background: #fff url('../img/loader.gif') center center no-repeat; border-bottom: 1px solid #ccc; padding: 0 40px; height: 440px;}

Step 3. Utilizzo delle librerie

Aggiungiamo una nuova funzione "loadMap" all'interno del nostro file company.js, questa funzione avrà lo scopo di richiedere le informazioni direttamente al servizio google maps e di restituirci la cartina con la nostra posizione direttamente all'interno del div "banner_section".

/* @company.js */
function loadMap(lon,lat){
  //definiamo le variabili utilizzate dalla funzione
  var myLatlng = new google.maps.LatLng(lat,lon),
  bound = new google.maps.LatLngBounds(),
  mapOptions = {},
  map = {};

  //creiamo il nuovo oggeto, che google utilizza per centrare la mappa.
  bound.extend( myLatlng ),

  //definiamo le opzioni per la creazione della mappa
  mapOptions = {
      center: bound.getCenter(),
      zoom: 12,
  };

  //Istanziamo il nuovo oggetto google.maps.Map();
  map = new google.maps.Map(document.getElementById("map-canvas"),
    mapOptions);

}

Richiamiamo la nostra funzione con le relative proprietà.

$('.longitude').html( position.coords.longitude );
//richiamiamo la funzione che richiede ed include la mappa passando la posizione attuale.
loadMap(position.coords.longitude, position.coords.latitude);

Aggiorniamo la nostra pagina web e visualizziamo il risultato ottenuto.
schermata 2014-04-07 alle 17 04 32

A questo punto non ci resta che aggiungere il marker che indica all'interno della mappa dove ci troviamo!
Aggiungendo queste poche righe dopo la ri-definizione dell'oggetto map comparirà il marker nativo di google.

/* @compan.js => loadMap() */
map = new google.maps.Map(document.getElementById("map-canvas"),
    mapOptions);

new google.maps.Marker({
      position: myLatlng,
      map: map,
      title:"Sono qui!",
      animation: 'bounce'
    });

Salva ed aggiorna la pagina http://localhost:8888

Il risultato dovrebbe essere molto simile a questo:
mapsonpage

Step 4. Aggiungiamo il percorso per raggiungere la sede

Aggiungiamo delle nuove variabili all'interno della funzione loadMap.
Impostiamo nei primi due latitudine e longitudine del punto di arrivo.
La terza è il nostro oggetto google con il punto sulla mappa.
directionsDisplay e directionsService richiamano i servizi google per inizializzare gli oggetti necessari per richiedere la direzione e per effettuare il render sulla mappa.

var locationLatitude = 41.901556, locationLongitude = 12.502005, //Stazione di Roma Termini
  locationLatlng = new google.maps.LatLng(locationLatitude,locationLongitude),
  directionsDisplay = new google.maps.DirectionsRenderer(),
  directionsService = new google.maps.DirectionsService();

Successivamente scriviamo una nuova funzione all'interno della loadMap() che chiama le api di google e chiede il percorso da fare partendo dai due punti.

inserire la funzione dopo la dichiarazione delle variabili

function calcolaPercorso() {
    var request = {
      origin:myLatlng,
      destination:locationLatlng,
      travelMode: google.maps.TravelMode.DRIVING
    };
    directionsService.route(request, function(result, status) {
      if (status == google.maps.DirectionsStatus.OK) {
        directionsDisplay.setDirections(result);
      }
    });
  }

Come ultimo passaggio, dopo la definizione del nostro primo marker, possiamo richiamare la funzione appena definita ed effettuare il render sulla mappa

//add direction information
  calcolaPercorso();

  //set map to directionsDisplay object
  directionsDisplay.setMap(map);

Salva ed aggiorna la pagina http://localhost:8888

Il risultato dovrebbe essere molto simile a questo:
mapwithstreet

Bootstrapping with Yeoman and HTML5Boilerplate

02 Apr 14:36
Compare
Choose a tag to compare

Componenti necessari

Di seguito sono elencati tutti i software necessari per procedere con i LAB

Installare Node JS

scaricare ed installare l'ultima versione di nodejs dal sito http://nodejs.org/ il sito web intuisce il sistema operativo utilizzato.
Tutti i possibili download li trovate a questo indirizzo: http://nodejs.org/download/

Gli utilizzatori di linux o virtual machine con linux (es: ubuntu, debian) possono seguire questa utile guida: https://github.com/joyent/node/wiki/Installing-Node.js-via-package-manager

nodesite

Seguire quindi tutti i passaggi per completare l'installazione.

Installare Yeoman

Installato nodejs avremo a disposizione la gestione dei pacchetti direttamente da nodejs con il comando

For npm versions < 1.2.10.
Il parametro -g installa il pacchetto a livello globale

# npm install -g yo

Bower & Grunt

# npm install -g grunt-cli bower

Installare il generatore di template HTML5 Boilerplate

# npm install -g generator-h5bp

Inizializzare il progetto

Ora siamo tutti gli strumenti necessari per inizializzare il progetto con il comando:

Creiamo una nuova cartella "codemotion"

# mkdir codemotion

Spostiamoci al suo interno e lanciamo il comando:

# yo h5bp

h5bp

Il comando appena eseguito crea un progetto vuoto con tutte le risorse necessarie.

Analizziamo il contenuto del progetto con tutte le librerie scaricate.

contenuto_cartella

Come si può notare aprendo i file css/html scaricati, il contenuto ha tutto il necessario per iniziare un nuovo progetto da zero senza perdere tempo con le classiche impostazioni.


Inizializzare il progetto Codemotion2014

Per tutti i lab eseguiti durante il corso, è possibile utilizzare alcuni comandi di git per clonare e spostarsi all'interno dei vari step che il progetto prevede.

La struttura del progetto che realizzeremo è disponibile al seguente indirizzo: https://github.com/marcocasario/codemotion2014/tree/responsive-dev

e cliccare quindi su Download ZIP
downloadzip

Chi preferisce utilizzare git può clonare il progetto direttamente da questo indirizzo: https://github.com/marcocasario/codemotion2014/tree/responsive-dev

oppure utilizzando il comando da shell:

# git clone https://github.com/marcocasario/codemotion2014.git

gitclone

spostiamoci dentro la cartella 'codemotion2014' creata automaticamente dal comando 'git clone'.

A questo punto possiamo spostarci all'interno del ramo di sviluppo:

# git checkout responsive-dev

Apriamo la pagina index.html sul nostro browser, il risultato ottenuto deve essere questo:
index