Web: Client 2

Formulaires

HTML nous offre des composants de formulaire standards pour permettre à l'utilisateur de saisir des données. HTML5 ajoute des types spécifiques(date, couleur, slider, ...)

📚 developer.mozilla.org/fr/docs/Web/HTML/Element#Formulaires

📚 htmlreference.io/forms/

📚 w3schools.com/html/html_form_elements.asp

ℹ️ Respecter la sémantique dans les formulaires

Interactivité

  • JavaScript nous a permis de construire dynamiquement le DOM
  • Nous avons offert une interaction minimale à l'utilisateur avec les boîtes de dialogue ou la console
  • Donc, la logique de notre programme influence le contenu et l’expérience de l’utilisateur
  • On souhaite offrir à l’utilisateur la possibilité de participer directement à l’expérience de la page web
  • En combinant les formulaires et les événements(ex. clic) on peut récupérer efficacement des données auprès de l’utilisateur et les manipuler dans notre logique applicative

Récupérer les valeurs

js
Récupérer l'élément concerné
const element = document.getElementById('...');
const element = document.querySelector('...');
// ...
const elements = document.getElementsByName('...'); // tableau []
const elements = document.querySelectorAll('...'); // tableau []
js
Récupérer la valeur ou l'état
element.value // Valeur associée au composant
// ValueAsDate valueAsNumber
element.checked // radio/check indique si activé
optionElement.selected // <options> d'un select, indique si sélectionné
Ouvrir

Événements

On peut demander aux éléments du DOM de nous informer de certains changements d’état et y réagir via JavaScript.

  • Clic, Survol de la souris
  • Appui/relâchement d’une touche
  • Changement de valeur
  • Chargement de la page/élément
  • On peut spécifier plusieurs événements, ex: clic ET survol de la souris
📚 Liste des événements disponibles

Événements: Attributs

On spécifie directement le nom de l’événement en tant qu’attribut HTML et la valeur est le code JavaScript à exécuter.

html
copier
<!DOCTYPE html>
<html>
<body>
<h1 style="margin-top: 0;">Attributs HTML</h1>
<!-- onclick="code javascript;" -->
<button type="button" onclick="alert('Bonjour!');">Cliquez ici!</button>

<!-- On peut spécifier plusieurs événements
et appeler une fonction pour soulager la lecture du code -->

<button
id="btn"
type="button"
onclick="hello();"
onmouseover="document.getElementById('btn').innerHTML = 'Oui cliquez!';"
onmouseout="document.getElementById('btn').innerText = 'Cliquez ici!';"
>
Cliquez ici!
</button>

<script>
function hello() {
alert('Bonjour de la fonction!');
}
</script>
</body>
</html>

Événements: Propriétés

On peut également assigner directement un événement à partir des propriétés correspondantes en JavaScript.

html
copier
<!DOCTYPE html>
<html>
<body>
<h1 style="margin-top: 0;">Propriétés JS</h1>
<button id="btn" type="button">Cliquez ici!</button>
<script>
const btn = document.getElementById('btn');

// On peut spécifier la fonction par son NOM
btn.onclick = hello; // hello SANS les ()

// On peut également déclarer une fonction ANONYME
btn.onmouseover = function() {
btn.innerText = 'Oui cliquez!';
}

btn.onmouseout = () => { // ARROW FUNCTION
btn.innerText = 'Cliquez ici!';
}

function hello() {
alert('Bonjour fonction standard!');
}
</script>
</body>
</html>

Événements: Listeners

Un élément peut ajouter ou retirer l'écoute: addEventListener ou removeEventListener

html
copier
<!DOCTYPE html>
<html>
<body>
<h1 style="margin-top: 0;">Listeners</h1>
<button id="btn" type="button">Cliquez ici!</button>
<script>
const btn = document.getElementById('btn');

// On précise le nom de l'événement SANS on
btn.addEventListener('click', function() {
alert('Bonjour fonction ANONYME');
});

// On peut écouter plusieurs fois le même événement
btn.addEventListener('click', hello);

btn.addEventListener('mouseover', function() {
btn.innerText = `Oui c'est ici!`;
});
btn.addEventListener('mouseout', function() {
btn.innerText = 'Cliquez ici!';
});

function hello() {
alert('Bonjour fonction STANDARD'); // affichera 1 fois
btn.removeEventListener('click', hello); // car on remove après
}
</script>
</body>
</html>

📚 addEventListener

📚 removeEventListener

Quel mécanisme favoriser?

Quelle est la différence entre les différentes méthodes pour écouter les événements du DOM?

  • Attributs : Généralement moins utilisé car disperse le JS dans le HTML. On favorise parfois d'organiser la structure(HTML), la mise en forme(CSS) et la logique(JS). Appeler une function existante via l'attribut est un compromis intéressant OU utiliser les components.
  • Propriétés : Méthode simple à mettre en place, surtout lorsque l'affichage est bâti en JS.
  • Listener : Offre plus de flexibilité, par exemple on peut écouter plusieurs fois le même événement, mais demande plus de rigueur si on ajoute et retire des événements pour ne pas perdre le fil.

Données de l'événement

La fonction de l'événement peut recevoir un paramètre contenant ses détails

ℹ️ Récupérer les données
📚 Données des événements

html
copier
<!DOCTYPE html>
<html>
<body>
<h1 style="margin-top: 0;">Détails event</h1>
<script>
const items = ['A', 'B', 'C'];
for(let i = 0; i < items.length; i++){
const btn = document.createElement('button');
btn.style.marginRight = '16px';
btn.innerHTML = items[i];
btn.onmousedown = mouseDownEvent; // Lier la fonction
btn.dataset.myNumber = (i * 10); // Ajouter des données spécifiques: https://developer.mozilla.org/fr/docs/Learn/HTML/Howto/Use_data_attributes
document.body.appendChild(btn);
}

function mouseDownEvent(event) {
// event est une variable reçue en param qui contient les détails de l'événement
// event.target représente l'élément déclencheur
alert(`${event.target.outerHTML}\n i = ${event.target.dataset.myNumber}\n ${event.button == 0 ? 'gauche' : 'droite'}`);
}
</script>
</body>
</html>

Ressources

Explications des événements

Référence des événements disponibles

Exemples d'utilisation de divers événements

Aller plus loin

Démo!

html
HTML de départ
copier
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<script src="script.js"></script>
</head>
<body>
<!-- onchange vs oninput -->
<input type="text" name="message" onchange="console.log(`ONCHANGE: ${event.target.value}`)">

<div>
<label>
<input type="radio" name="transform" value="lower">
Lowercase
</label>

<label>
<input type="radio" name="transform" value="upper">
Uppercase
</label>

<label>
<input type="radio" name="transform" value="none" checked>
None
</label>
</div>

<p><b>Transformed</b></p>
<p id="result"></p>
</body>
</html>
Solution script.js
js
copier
const EMPTY_MESSAGE = `
<i>Empty message...<i>
`
;

document.addEventListener('DOMContentLoaded', function() {
const input = document.querySelector('[name="message"]');
input.oninput = onMessageInput;

const radios = document.querySelectorAll('input[type="radio"]');

for(let i = 0; i < radios.length; i++) {
radios[i].onchange = onTransformChange;
}

applyTransform();
});

//
// Functions
//

function onMessageInput(evt) {
console.log(`ONINPUT ${evt.target.value}`);

applyTransform();
}

function onTransformChange(evt) {
console.log(`RADIO: ${evt.target.value}`);

applyTransform();
}

function applyTransform() {
const original = document.querySelector('[name="message"]').value
let result = EMPTY_MESSAGE;

if (original.trim().length > 0) {
result = original;

const transform = document.querySelector('[name="transform"]:checked').value;
switch (transform) {
case 'lower':
result = original.toLowerCase();
break;

case 'upper':
result = original.toUpperCase();
break;
}
}

const resultParagraph = document.querySelector('#result');
resultParagraph.innerHTML = result;
}