Salta el contingut

Desenvolupament web dinàmic frontend amb javascript
Conceptes

Sessió 7: Projecte

Dissenyem dinamisme frontend

Aprendrem a dissenyar interficies d'usuari dinàmiques a frontend, així com usar diferents serveis públics o privats mitjançant scripts.

Projecte frontend dinàmic

L'objectiu serà definir els requeriments que l'aplicació web que es disseny i haurà de complir.

Normalment aquests requeriments aniran orientats cap a dues bandes:

  • Requisits funcionals:

    Seran aquelles funcionalitats que volem que l’aplicació web resolgui o doni servei i que podrem implementar dinàmicament amb tecnologia d’scripting de frontend. Indicar QUÈ volem que faci el web.

    • Per exemple: Localitzar dinàmicament un conjunt de botigues d’una cadena de roba.
    • Per exemple: Paginar un conjunt de plats de menjar d’un restaurant.
  • Requisits no funcionals:

    Entenem que serà tots aquells punts de l'aplicació que no esdevenen funcionalitats, però que l'aplicació ha d'assolir en aspectes com rendiment, seguretat, visualització, …

    • Per exemple: Disseny intuïtiu, accessible i adaptat a diferents usuaris
    • Per exemple: Fer la interficie responsiva

Per tant notem que ara els objectius guanyen en un punt de dinamisme que permetrà afegir funcionalitats en el punt de la UX o UI.

UI i UX

Diferències entre UI i UX i la seva importància en el projecte web.

Ara que estem avançant amb interficies dinàmiques amb JavaScript, és un bon moment per introduir els conceptes de UI (User Interface) i UX (User Experience), que són fonamentals per dissenyar webs atractives i fàcils d’usar.

  1. Què és UI (User Interface)? La Interfície d’Usuari (UI) fa referència a l’aspecte visual i els elements gràfics amb els quals l’usuari interactua. Això inclou:

    • Disseny visual (colors, tipografies, icones, botons, marges)
    • Coherència visual (ús correcte de l’espai, alineació, contrast)
    • Interaccions (animacions, efectes, botons que responen a clics)
    • Responsivitat (adaptació a mòbils, tauletes i ordinadors)
  2. Què és UX (User Experience)? L’Experiència d’Usuari (UX) es basa en com l’usuari se sent mentre utilitza la web. Una bona UX fa que la web sigui fàcil d’usar, intuïtiva i satisfactòria. Això inclou:

    • Facilitat de navegació (menús clars, botons on l’usuari espera trobar-los)
    • Accessibilitat (ús adequat de colors i contrastos, navegació amb teclat)
    • Temps de càrrega (una web lenta fa que els usuaris marxin)
    • Claredat de contingut (textos comprensibles, informació ben organitzada)
Pregunta

Activar el botó de Submit d'un formulari quan tots els camps estan plens, és UI o UX?

  • UI
  • UX
  • Les dues

Activar el botó de Submit només quan tots els camps estan plens és una combinació de UI (User Interface) i UX (User Experience), però s'enfoca més en UX.

Per què és UX?

  • Millora l'experiència de l'usuari perquè evita errors en l'enviament del formulari.
  • Dóna un feedback visual clar sobre quan l'usuari ha completat correctament el formulari.
  • Evita frustracions com enviar un formulari buit o incomplet i haver de corregir errors després.
  • Per què també és UI?

  • Implica un canvi visual en la interfície (per exemple, el botó passa de desactivat a activat).
  • Pot incloure animacions, colors o estils que ajudin a indicar l'estat del botó.
  • Conclusió: És principalment una decisió de UX perquè millora la interacció de l'usuari amb el formulari, però també afecta la UI perquè visualment es percep el canvi en el botó.

    Ara pensa què farà falta desenvolupar per implementar Activar el botó de Submit d'un formulari quan tots els camps estan plens.

    💡: Cada vegada que perdi el focus un input ... llavors el que faré serà cridar a una funció que ... tots els valors i ... modifiqui ...

    💡: Escriuré el codi en una primera iteració i ho provaré en local... fins que em funcioni tot correctament.

    💡: Tot seguit ho pujaré a l'entorn de desplegament i ho tornaré a provar en aquest entorn.

    Com aplicar UI/UX a projectes?

    • Analitzar quins poden ser els elements afectats per aquest dinamisme.
    • Fer wireframes abans de programar per planificar el disseny i estructura de la web.
    • Definir una paleta de colors i tipografies coherents per millorar la UI.
    • Testar la web amb altres persones per detectar problemes d’UX.
    • Implementar feedback visual amb JavaScript (per exemple, canviar el color d’un botó quan l’usuari el passa per sobre).

    Nota

    La part de testejar la usabilitat de la interfície per una altra persona té un benefici molt clar en la validació sobretot de la UX. Normalment el dissenyador i maquetador al tenir la comprensió del que ha fet, obvia les pautes d’usabilitat de les interfícies que poden tenir altres usuaris. Per tant, el fet de fer proves amb altres usuaris que no tenen la informació del disseny donarà la validesa de si la interfície és robusta o no.

    Per exemple: La manera de com donem feedback a una acció d’alta, pot generar una confusió a l’usuari sobre la certesa o no de que s’ha inserit i desat la informació correctament.

    No news good news

    La frase "No news, good news" en UX (User Experience) fa referència al principi que si un usuari no rep cap tipus de feedback negatiu o confús mentre utilitza una interfície, vol dir que tot està funcionant correctament. Això vol dir que:

    • L'experiència és fluida i sense friccions → L'usuari no es troba amb errors, interrupcions o situacions inesperades.
    • Els usuaris no han de preguntar-se si una acció s'ha completat correctament → Si un procés funciona bé i està clarament dissenyat, no cal que l'usuari es preocupi per si ha funcionat o no.
    • Els millors dissenys sovint són “invisibles” → Quan un disseny està ben fet, l'usuari ni tan sols el nota perquè tot funciona com espera.

    Perill d’aplicar-ho malament Si es porta a l'extrem, aquest principi pot ser perillós perquè:
    Els usuaris necessiten confirmació visual o sonora en accions importants, per exemple, en fer una compra o enviar un formulari.
    El silenci pot generar ansietat, si l'usuari no sap si una acció s'ha realitzat amb èxit, pot intentar repetir-la o pensar que hi ha hagut un error.

    Solució UX:
    Utilitzar microinteraccions (com missatges de confirmació o animacions) per informar sense ser molest.
    Mostrar estats del sistema clarament (carregant, èxit, errada).
    Donar feedback visual subtil per indicar que l'aplicació està responent.

    En resum, "No news, good news" és útil en UX per evitar sobrecarregar d’informació innecessària, però sempre s'ha de garantir que l'usuari tingui el feedback necessari en moments clau.

    Una vegada hem definit els canvis que haurem de dissenyar i aplicar a les interficies web, la tecnologia que caldrà aplicar serà:

    • HTML: Llenguatge de marques que seguirem usant per a generar l’estructura de la interfície. A partir d’ara les etiquetes generaran un element HTML que podrem usar per a dinamitzar

      Com ho fem? indicant l'atribut id=”identificador”

      Aquest identificador serà usat per accedir a dinamitzar l’element.

      Per exemple: Al fer click a un botó d’enviament d’un formulari

    • CSS: Ara gestionarem diferents estils CSS per als diferents element html de la interficie UI. Podrem aplicar dinamisme d’estil UX canviant les propietats dels estils aplicats dinàmicament

      Com ho fem? gestionant les propietats d’estil CSS dels elements

      També podriem canviar directament la classe d’estil completa que se li aplica

      Per exemple: canvia de mode de visualització dia/nit

    • Javascript: És el llenguatge de programació de frontend que usarem per a realitzar tot aquest dinamisme. Gestionarem els elements HTML mitjançant el DOM i controlarem les accions mitjançant els esdeveniments.

      Com ho fem? incloent un <script> a dins del codi de la pàgina HTML

      També permet fer-ho directament a un esdeveniment d’un element HTML

      Per exemple: Programar que cada 10 segons actualitzi una imatge de la interficie

    Bones pràctiques de programació amb javascript

    • Seguir una convenció de noms de Variables i funcions amb noms descriptius i usant camelCase.
    const userName = "Anna"; // Correcte (clar i llegible)
    function getUserData(id) { ... } // Correcte
    
    • Utilitzar const i let en lloc de var
    const maxUsers = 100; // No canviarà
    let currentUsers = 10; // Pot variar
    
    • Evitar repetir codi
    // Incorrecte (Codi repetit)
    function greetUser1() {
        console.log("Hola, benvingut!");
    }
    function greetUser2() {
        console.log("Hola, benvingut!");
    }
    
    // Correcte (Codi reutilitzable)
    function greetUser() {
        console.log("Hola, benvingut!");
    }
    
    • Manipulació eficient del DOM. Accedint només una vegada i llavors gestionant.
    const title = document.getElementById("title");
    title.innerText = "Hola";
    title.style.cssText = "color: blue; font-size: 20px;";
    
    • Afegir i treure classes dinàmicament
    document.getElementById("button").addEventListener("click", function() {
        this.classList.toggle("active");
    });
    
    • Usar el mode estricte
    "use strict";
    let nom = "Anna";
    console.log(nom);
    

    Bé, una vegada tenim clar les tecnologies que podrem usar, veiem-ne de nou els diferents punts alhora de desenvolupar un projecte web frontend:

    Dissenyem

    1. Disseny

      • Objectiu:

        Descripció del que ha de ser el web dinàmic que desenvoluparem. Usarem un llenguatge natural. Identificant quin és el públic objectiu i qui utilitzarà el projecte web. Estudiarem quines són les necessitats i expectatives (UX) dels usuaris. Si és necessari es planificaran diferents reunions de 'briefing' amb les persones per determinar el disseny, la funcionalitat i el seu contingut. Ara caldrà tenir en compte tots els elements de dinamisme que podrem aplicar.

      • Requisits

        • Requisits funcionals: Descripció de totes les funcions que ha de tenir el web. D’alguna manera indiquem QUÈ ha de fer el sistema.
        • Requisits no funcionals: Descripció de COM es vol que sigui el sistema
      • Estructura web

        Documentar l’estructura de carpetes que tindrà la web.

        De manera mínima tindrem

        Estructura carpetes

      • Disseny interficies UI / UX

        • Crearem els Wireframe de la web, en format dibuix manual
        • Definirem la paleta de colors
        • Definirem la tipografia del text
        • Generarem les imatges i el logo
        • Indicarem a la UI quin serà el dinamisme que hi haurà
      • Disseny lògic dels scripts

        Definirem l’arxiu d’scripts que tindrem a la carpeta /scripts

        Farem una breu descripció de la lògica que haurà de fer cada una dels esdeveniments, funcions, … que hi desenvoluparem.

    2. Desenvolupament

      Tot seguit passarem al desenvolupament pròpiament del web.

      Al ser una web dinàmica, haurem de fer desenvolupament de codi per aplicar el dinamisme dissenyat.

      Primer realitzarem la part de maquetació de la interfície amb HTML+CSS, tenint en compte que treballarem els elements HTML generats amb el DOM.

      Tot seguit, desenvoluparem els scripts amb JS per aplicar el dinamisme.

      Aplicarem les bones pràctiques comentades més amunt ->

      Usarem el IDE VSC, amb diversos complements que ens puguin ajudar a l’escriptura del codi (Copilot?)

    3. Seguiment

      Caldrà anar pujant regularment al git el codi generat. D'aquesta manera es pot visualitzar el progrès regularment i si s'escau es pot tornar a una versió del codi concreta.

      Si les pujades corresponen a funcionalitats acabades, podrem publicar una versió o altra fàcilment.

      També disposarem d’una còpia de seguretat del codi en l’estat que ens interesssi.

    4. Proves & Documentació

      Realitzarem un conjunt de proves amb diferents navegadors i dispositius, provant així la responsivitat i adaptabilitat de les interfícies generades.

      Caldrà realitzar proves funcionals del que s'ha desenvolupat.

      També podem testejar el codi web generat a W3C Validation →

      Ara també podrem fer proves de traçabilitat del codi javascript que anem desenvolupant ->

    Documentació.

    Tenim dos punts on generem documentació:

    1. A partir del disseny inicial

      Podem generar un document PDF amb els 4 punts de disseny:

      • objectius
      • requisits
      • estructura web
      • disseny de les interfícies
      • disseny lògic dels scripts.
    2. A dins del codi desenvolupat.

      En aquest punt tindrem la lògica del codi comentada:

      • Capçalera de la pàgina:

        Hi posem la informació general de l'script

        /**
         * @module: Projecte2.js
         * @author: Maria Bosch
         */
        
        function guardarLlista() {
            localStorage.setItem('llistaCompra', JSON.stringify(llistaCompra)); 
        }
        
      • Capçalera de la funció

        Hi posem la descripció de la funció i els paràmetres

        /**
         * Funció per mostrar missatges amb tipus i temporitzador a la dreta superior
         * @param {string} message - missatge que vull mostrar
         * @param {string} [tipus='info'] - tipus del missatge, canviarà color
         * @param {number} [temps=3000] - temps que triga en ocultar-se. Per defecte 3s 
         */
        function showMessage(message, tipus = 'info', temps = 3000) {
            ...
        }
        
      • Explicació interna del propi codi de javascript

        Hi posem la lògica del codi, línia o bloc de codi.

        function goToFirstPage() {
            const stepsToFirstPage = -(history.length - 1); // Calcular quantes pàgines enrere cal anar
            history.go(stepsToFirstPage); // Navegar a la primera pàgina
        }
        

    Scripts externs. Webs híbrids

    Tal com haviem vist amb l'exemple de Google Maps , podem inserir recursos externs a la nostra interfície web, d'aquesta manera augmentem la UX amb codi no generat per nosaltres.

    Web híbrid

    Podem diferenciar d'un web natiu a aquell que tot el contingut és propi a un web híbrid, quan la font del contingut prové de diverses fonts d'origen diferents a la de la crida HTTP GET URL

    Ajax

    Aquesta tasca la podriem desenvolupar usant crides AJAX en segon pla cap a un backend, però això ho deixem per a continguts del proper curs!

    Per tant, la idea és incorporar la lògica d'un script extern al nostre codi

    <script src="URL script js"></script>
    

    També podem usar la importació de llibreries o mòduls usant import

    <script type="module">
        import *ID* from "URL script js";
    </script>
    

    llistat de llibreries JS

    llibreries javascript

    Google Charts (Google, w3Schools)

    Google Charts

        <html>
          <head>
           <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
           <script type="text/javascript" src="scripts/p2-s7-ex2.js"></script>
          </head>
          <body>    
            <div id="chart_div" style="width: 550px; height: 120;"></div>
          </body>
        </html>
    
        // carreguem la llibreria de Google Charts
        google.charts.load('current', {'packages':['gauge']});
        google.charts.setOnLoadCallback(drawChart);
    
        /**
         * Funció per dibuixar el gràfic de Gauge
         * @returns {void}
         */
        function drawChart() {
    
            // Dades del gràfic
            var data = google.visualization.arrayToDataTable([
                ['Label', 'Value'],
                ['Memory', 80],
                ['CPU', 55],
                ['Network', 68]
            ]);
    
            // Opcions del gràfic
            var options = {
                width: 550, height: 280,
                redFrom: 80, redTo: 100,
                yellowFrom:60, yellowTo: 80,
                greenFrom:0, greenTo:60,
                minorTicks: 2,
                Animation: {duration: 10000, easing: 'in'}
            };
    
            // Dibuixem el gràfic  
            var chart = new google.visualization.Gauge(document.getElementById('chart_div'));
            chart.draw(data, options);
    
            // Actualització de les dades dels gràfics
            setInterval(function() {
                data.setValue(0, 1, 40 + Math.round(60 * Math.random()));
                chart.draw(data, options);
            }, 13000);
            setInterval(function() {
                data.setValue(1, 1, 40 + Math.round(60 * Math.random()));
                chart.draw(data, options);
            }, 5000);
            setInterval(function() {
                data.setValue(2, 1, 60 + Math.round(20 * Math.random()));
                chart.draw(data, options);
            }, 26000);
        }
    

    Objectiu: Inserir gràfics de google a la interfície

    Nota: La majoria de gràfics no requereixen ús de API-KEY.

    Tenim un <div> per inserir el gràfic

    <div id="chart_div" style="width: 400px; height: 120px;"></div>
    

    Llavors cal incorporar l'script de Google Chart

    <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
    

    I tot seguit desenvolupem la nostra part de scripting al frontend

    En aquest cas, el posem a un fitxer extern

    <script type="text/javascript" src="scripts/p2-s7-ex2.js"></script>
    

    Primer cal carregar la llibreria que usarem i indicar la funció que cridarà al carregar-lo.

    // carreguem l'objecte de la llibreria de Google Charts
    google.charts.load('current', {'packages':['gauge']});
    google.charts.setOnLoadCallback(drawChart);
    

    Tot seguit definim la configuració de l'objecte i els valors a mostrar

    /**
     * Funció per dibuixar el gràfic de Gauge
     * @returns {void}
     */
    function drawChart() {
        // configuracions i valors
        // dibuixem
    }
    

    Com definim els valors?

    // Dades del gràfic
    var data = google.visualization.arrayToDataTable([
        ['Label', 'Value'],
        ['Memory', 80],
        ['CPU', 55],
        ['Network', 68]
    ]);
    

    Un array de 2 dimensions, on definim valors per a 3 rellotges

    Llavors indiquem unes possibles configuracions

    // Opcions del gràfic
    var options = {
        width: 550, height: 280,
        redFrom: 80, redTo: 100,
        yellowFrom:60, yellowTo: 80,
        greenFrom:0, greenTo:60,
        minorTicks: 2,
        Animation: {duration: 10000, easing: 'in'}
    };
    

    I tot seguit creem l'objecte associant-lo al div i dibuixem amb el mètode .draw(), passant-li els valors i opcions

    // Dibuixem el gràfic  
    var chart = new google.visualization.Gauge(document.getElementById('chart_div'));
    
    chart.draw(data, options);
    

    Al final incorporem unes petites animacions de valors aleatoris, usant la funció setInterval() i el mètode .draw() per a dibuixar i .setValue() per assignar.

    data.setValue(0, 1, 40 + Math.round(60 * Math.random()));
    chart.draw(data, options);
    

    Google Charts 2

        <html>
          <head>
           <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
           <script type="text/javascript" src="scripts/p2-s7-ex3.js"></script>
          </head>
          <body>
            <div>
              <label for="valor">Valor:</label>
              <input type="number" id="valor" name="valor" value="25" min="0" max="100" step="1">      
            <div id="chart_div" style="width: 400px; height: 120px;"></div>
          </body>
        </html>
    
        // carreguem la llibreria de Google Charts
        google.charts.load('current', {'packages':['gauge']});
        google.charts.setOnLoadCallback(drawChart);
    
        /**
         * Funció per dibuixar el gràfic de Gauge
         * @returns {void}
         */
        function drawChart(val = 25) {
    
            // Dades del gràfic
            var data = google.visualization.arrayToDataTable([
                ['Label', 'Value'],
                ['CPU', val],
            ]);
    
            // Opcions del gràfic
            var options = {
                width: 250, height: 160,
                redFrom: 80, redTo: 100,
                yellowFrom:60, yellowTo: 80,
                greenFrom:0, greenTo:60,
                minorTicks: 2,
                Animation: {duration: 10000, easing: 'in'}
            };
    
            // Dibuixem el gràfic  
            var chart = new google.visualization.Gauge(document.getElementById('chart_div'));
            chart.draw(data, options);
    
            // Actualització de les dades del gràfic
            document.getElementById('valor').addEventListener('change', function() {
                val = document.getElementById('valor').value;
                data.setValue(0, 1, val);
                chart.draw(data, options);
            })
    
    
        }
    

    Objectiu: Assignem valor dinàmicament al gràfic de google

    Afegim un input nou per entrar un valor entre 0 i 100

    <input type="number" id="valor" name="valor" value="25" min="0" max="100" step="1">
    

    I a l'script i afegim el control de l'esdeveniment de change

    // Actualització de les dades del gràfic
     document.getElementById('valor').addEventListener('change', function() {
        val = document.getElementById('valor').value;
        data.setValue(0, 1, val);
        chart.draw(data, options);
    })