07 - Frontend
Frontend
Intro
Una pagina HTML è rappresentabile come un albero (DOM, Document Object Model).
Ogni node ha dei parent e dei children, questa rappresentazione rende semplice navigare la pagina in modo gerarchico, selezionare per leggerne le proprietà o modificarlo.
Dall'inspector è chiara la rappresentazione gerarchica, i nodi sono collassabili in modo da nascondere i figli e il codice è indentato, la radice dell'albero è il nodo più a sinistra, e ogni indentazione è un livello successivo.
Si può intuire la struttura anche guardando semplicemente il codice HTML di una pagina, in particolare se scritto bene, sempre facendo riferimento all'indentazione
Selezione di un elemento
Esistono diversi metodi per selezionare un nodo in JavaScirpt:
document.getElementById('id-nodo'); // seleziona un nodo in base all'id
document.querySelector('.selettore-css'); // seleziona il primo nodo che
// combacia con il criterio
// ne esistono anche altri specifici per cercare una classe, un tipo di tag, un tag, ecc
document.querySelector segue le stesse regole della selezione css, si può selezionare per id, classe, nodetype, attributo, ecc. Si possono anche usare i selettori gerarchici, ad esempio .list .list-item seleziona l'elemento con classe list-item figlio di list.
Esiste anche il metodo
document.querySelectorAll('.selettore-css')
che torna una lista con tutti gli elementi che soddisfano il selettore
Tutti questi metodi tornano un oggetto di tipo Element o una lista di oggetti dello stesso tipo. Questi oggetti hanno a loro volta gli stessi metodi visti sopra, ma effettuano la ricerca esclusivamente tra i discendenti del nodo di partenza.
const listEl = document.querySelector('.list');
const listItems = listEl.querySelectorAll('.list-item');
Modifica della pagina
Esistono diversi metodi per modificare il contenuto della pagina.
const newNode = document.createElement('div'); // crea un nuovo nodo ma non lo
// aggiunge al DOM
element.appendChild(newNode); // aggiunge il nuovo nodo creato come figlio di
// element
const content = '<div>ciao</div>';
element.innerHTML = content; // sostituisce l'intero contenuto di element
Eventi
Ci sono diversi eventi che possono essere lanciati da una pagina: click di un bottone, submit di un form, change di un input, ecc.
Per rimanere in ascolto di tali eventi si usa la sintassi:
element.addEventListener('event-name', handlerFunction)
Ad esempio per gestire il change di un input:
element.addEventListener('change', event => {
// codice da eseguire quando viene lanciato l'evento
})
All'handler viene sempre mandato un parametro che contiene i dettagli dell'evento, cambia a seconda dell'evento.
Esercizio 03-01
Creare una pagina web che mostri gli elementi del carrello sviluppato in precedenza e il sommario con i totali.
Obiettivi:
- viene mostrata una lista con un elemento per ogni articolo del carrello
- mostrare nome, quantità, prezzo totale ivato e sconto
- le quantità sono input editabili, quando viene modificata una quantità si devono aggiornare i valori dell'elemento della lista e il riquadro con i totali.
Codice di partenza:
<!DOCTYPE html>
<html>
<head>
<title>Playground</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
<link href="./style.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>
<script type="module" src="./index.js"></script>
</head>
<body class="p-5">
<div class="container">
<div id="items-list-container">
<h3>I tuoi articoli</h3>
<ul class="list-group" id="items-list">
<li class="list-group-item item">
<div class="d-flex flex-row d-flex justify-content-between align-items-center">
<div class="item-name">
motherboard
</div>
<div class="d-flex flex-row align-items-center justify-content-end flex-wrap">
<span class="ms-2 d-flex flex-row align-items-center">
<label class="me-1" for="quantity">qty:</label>
<input class="form-control item-quantity" value="1" type="number" style="width: 70px">
</span>
<span class="ms-2">
<span class="item-price">1500€</span>
<span class="item-discount">(-300€)</span>
</span>
</div>
</div>
</li>
</ul>
</div>
<div class="mt-5">
<h3>Totale ordine</h3>
<div class="order-summary">
<div>
<div class="d-flex justify-content-between">
<span>Net Total:</span>
<span>1200€</span>
</div>
<div class="d-flex justify-content-between">
<span>VAT:</span>
<span>200€</span>
</div>
<div class="d-flex justify-content-between">
<span>Transport:</span>
<span >15€</span>
</div>
<hr>
<div class="d-flex justify-content-between">
<span>Total:</span>
<span>1700€</span>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
Prendere il resto del codice dall'esercizio precedente.
export function getVAT(country) {
return country === 'IT' ? 0.22 : 0;
}
export function getDiscountAmount(price, discount) {
const percentageDiscount = discount / 100;
return price * percentageDiscount;
}
export function getDiscountedPrice(price, discount) {
return price - getDiscountAmount(price, discount);
}
export function getVatAmount(price, vat) {
return price * vat;
}
export function getPrice(price, vat) {
return price + getVatAmount(price, vat);
}
export function getTransportFee(weight) {
let transportFee = 0;
if (weight > 2000) {
transportFee = 7;
}
if (weight > 5000) {
transportFee = 15;
}
if (weight > 10000) {
transportFee = 25;
}
return transportFee;
}
export function parseItem(item, vat) {
let discountAmount = getDiscountAmount(item.netPrice, item.discount) * item.quantity;
let discountedPrice = getDiscountedPrice(item.netPrice, item.discount) * item.quantity;
let vatAmount = getVatAmount(discountedPrice, vat);
let price = getPrice(discountedPrice, vat);
let weight = item.weight * item.quantity;
return {
name: item.name,
quantity: item.quantity,
weight: weight,
discountAmount,
discountedPrice,
vatAmount,
price
};
}
export const cart = [
{
name: 'ssd',
netPrice: 95,
weight: 100,
discount: 5,
quantity: 2
},
{
name: 'motherboard',
netPrice: 270,
weight: 900,
discount: 0,
quantity: 1
},
{
name: 'ram',
netPrice: 120,
weight: 60,
discount: 10,
quantity: 2
},
{
name: 'processor',
netPrice: 400,
weight: 130,
discount: 0,
quantity: 1
},
{
name: 'power supply',
netPrice: 130,
weight: 1400,
discount: 15,
quantity: 1
},
{
name: 'cpu cooler',
netPrice: 170,
weight: 1000,
discount: 23,
quantity:1
},
{
name: 'gpu',
netPrice: 1600,
weight: 2500,
discount: 0,
quantity: 1
},
{
name: 'case',
netPrice: 130,
weight: 3500,
discount: 30,
quantity: 1
}
];

