Passa al contenuto principale

Telephone Number Validator

Anteprima Telephone Number Validator Mobile UI Figma vs Visual Studio Code Anteprima Telephone Number Validator Desktop UI Figma vs Visual Studio Code

Il Progetto

Validatore di numeri telefonici statunitensi sviluppato con Regular Expressions, design responsive mobile-first e architettura orientata alla performance. Un'applicazione che dimostra la potenza delle regex nella validazione di pattern complessi.

Codice Sorgente

<!-- DESIGN 
------
* This file contains the HTML structure of the Phone Checker application.

* The structure follows this flow:
* - Head with meta tags, CSS link, and preconnection to Google Fonts.
* - Body with main containing the primary container.
* - Container with device-frame (device bezel) that appears only on the
* desktop version.
* - Device-screen (internal screen) that contains the entire application's UI.
* - Form with input, buttons, and results area
-->

<!DOCTYPE html>
<html lang="en">
<head>
<title>Phone Checker</title>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap" rel="stylesheet">
</head>

<body>

<!--
* freeCodeCamp instructions:
* - You should have an input element with an id of "user-input". ✔️
* - You should have a button element with an id of "check-btn". ✔️
* - You should have a button element with an id of "clear-btn". ✔️
* - You should have a div, span or p element with an id of "results-div" ✔️
-->

<!--
* I discovered that the modern approach uses classes for CSS and IDs for
* elements primarily used in JavaScript. Performance is the same, and
* counterintuitively, classes even seem faster as this article explains:
* (https://csswizardry.com/2011/09/writing-efficient-css-selectors/)
-->

<main>

<div class="container">
<div class="device-frame">
<div class="device-screen">
<p class="tribute"><a href="https://www.freecodecamp.org/" target="_blank" rel="noopener noreferrer" aria-label="Visit freeCodeCamp website (opens in new tab)">For freeCodeCamp</a></p>
<h1>Phone Checker</h1>
<form id="phone-form">
<label for="user-input">Enter a Phone Number</label>
<input type="tel" id="user-input" placeholder="1 555-555-5555" />
<div class="button-group">
<button type="submit" id="check-btn">Check</button> <!-- I must remember to add e.preventDefault() in JS -->
<button type="button" id="clear-btn">Clear</button>
</div>
<div id="results-div"></div>
</form>
</div>
</div>
</div>

</main>

<script src="script.js"></script>
</body>

</html>

Il Progetto Più Bello Fatto Fin'ora

È stato il progetto più bello fatto fin'ora. La regex è stata la parte più difficile in assoluto.
Non ho provato altri approcci: avrei potuto gestire la convalida del numero di telefono in modi alternativi, come una cascata di if statement. Il codice sarebbe stato più facile da scrivere e persino da leggere, ma sarebbe stato tremendamente lungo. Optare per la regex è stato anche un modo per rafforzarne la mia comprensione. Ho infatti scritto la spiegazione dettagliata della regex all'interno dello script.js, sia per far comprendere a chiunque a cosa serve ogni pezzetto, sia per consolidare quanto ho appreso.

Il Design: HTC One M8 e Windows Phone Aesthetic

Per quanto riguarda il design, ho deciso di inserire un HTC One M8 for Windows (la versione per Verizon) in un semplice sfondo blu stile Windows Phone. È venuto meglio di come me lo ero immaginato. Ho provato con la versione gold e black, ma questa silver è quella che si sposa meglio con lo sfondo.

Mobile-First (Davvero): Una Scelta Consapevole

La versione mobile è la versione di default. Come ho scritto nei commenti dello styles.css, ho scelto di creare una media query per desktop e non più, contrariamente al passato, la versione mobile in media query.

Le ragioni sono due:

  1. Diffusione: Il mobile ha ormai da anni superato il traffico del desktop.
  2. Performance: Impostandola come default, il caricamento del device frame (l'HTC) avviene solo se visualizzato da desktop. Inoltre chi naviga da desktop ha generalmente internet più veloce, quindi è stato ancora più sensato.

La Riflessione: Mobile-First non è un Dogma

Non se ne parla mai, ma credo che al di là del gold standard "mobile-first", bisognerebbe valutare in base al dispositivo che verrà utilizzato prevalentemente per navigare la nostra applicazione.
Se si crea un'applicazione destinata principalmente al desktop, forse ha più senso adottare il vecchio metodo di dedicare una media query al mobile.
In questo progetto ho comunque scelto l'approccio mobile-first anche per abituarmi a questo modo di pensare, una skill che voglio consolidare.
Potrei sbagliarmi, ma mi sorgono sempre red flag quando sento "è così e basta". Ci sono sempre mille sfumature e "dipende" che spesso non vengono menzionati.

La Filosofia dei Commenti

Come già fatto nello scorso certification project, ho dedicato particolare attenzione ai commenti nel codice. Ho scritto tutto lì: la logica, le scelte architetturali, i pattern utilizzati. Ripeterlo qui sarebbe ridondante e, soprattutto, difficile da comprendere senza avere il codice sottomano.
In questo progetto ho deciso di ridurre i commenti inutili, quelli che antirez chiama "Trivial Comments", al fine di rendere il codice più pulito. Ho concentrato la maggior parte dei commenti all'inizio di ogni documento, creando una sorta di mappa che guida la lettura del codice senza appesantirlo.
Ci tengo solo a dire che a ogni progetto che passa la mia self confidence aumenta e, allo stesso passo, il mio divertimento.

Cosa Ho Imparato

Regular Expressions:

  • Pattern complessi per validazione numeri telefonici US: /^(1\s?)?(\(\d{3}\)|\d{3})[\s\-]?\d{3}[\s\-]?\d{4}$/
  • Gestione di prefissi opzionali (country code 1)
  • Alternanza tra formati con parentesi (\d{3}) e senza \d{3}
  • Character classes [\s\-] per separatori multipli
  • Anchor ^ e $ per validazione stretta senza caratteri extra

Strategia Mobile-First Consapevole:

  • Default CSS senza media query per mobile
  • Media query @media (min-width: 560px) and (min-height: 730px) solo per desktop e tablet
  • Caricamento condizionale del device-frame (bezel) solo su desktop e tablet
  • Ottimizzazione per connessioni mobili più lente

CSS Variables Avanzate:

  • Override di variabili CSS nelle media query per design responsivo
  • Sistema di design scalabile con variabili semantiche
  • Gestione di due temi completi (mobile/desktop) con stesso set di variabili

DOM Manipulation Sicura:

  • .textContent per sanitizzazione XSS prima di ogni modifica
  • .innerHTML solo dopo validazione del contenuto
  • Pattern sicuro: sanitize → modify → insert

Viewport Dinamico:

  • min-height: 100dvh per gestire la barra URL mobile dinamica
  • Fallback 100vh per browser non supportati

Performance e UX:

  • Limite maxResult = 50 per prevenire problemi di performance DOM
  • .insertBefore() per stack LIFO dei risultati
  • Animazione @keyframes slideInFade con cubic-bezier per feedback fluido
  • Effetto click con transform: perspective() per feedback tattile

Form Handling:

  • e.preventDefault() per controllo completo del comportamento del form
  • Validazione lunghezza input con maxInputLength
  • Alert per feedback immediato su errori di input

Architettura Codice:

  • Separazione logica tra validazione, visualizzazione e interazione
  • Commenti strutturati con sezione DESIGN per overview architetturale
  • Naming semantico per funzioni riutilizzabili

Riflessione

È stato fondamentale, nella creazione dell'HTML, testare iterativamente sul mio edge case preferito: l'iPhone 12 mini e, sorprendentemente, anche su un HTC One M8 (versione Android).
Ho infatti scoperto di recente il comando "ipconfig getifaddr en0" (in macOS) nel terminale, che mi ha aperto un mondo. Mi sono aggiunto sul desktop in un file txt la procedura che ho riassunto:

  • Esegui ipconfig getifaddr en0 nel terminale
  • Ti darà un numero (n) ovvero il tuo IP locale
  • In VS Code, dopo aver cliccato su Live Server, ci sarà il numero della porta (p)
  • Nel dispositivo desiderato, scrivi nella barra degli indirizzi: n:p

Chiudo sempre il Live Server quando ho finito. Per quanto il rischio in realtà sia basso, considerando che per accedere alla porta bisogna comunque essere sotto la mia stessa rete wifi.


Prossimo Progetto: Imparare le basi della OOP costruendo un carrello della spesa