Remarque préliminaire: ce fichier contient une erreur javascript volontaire.

JavaScript et les formulaires

Vérification à l'expédition

Premier exemple

On veut tester que le nom et le prénom fournis par l'utilisateur ne sont pas vides.

nom prénom





Critique de la méthode précédente

On utilisera plutôt la manipulation du DOM (voir ci-dessous) pour écrire les messages d'erreur directement sur la page...

nom
prénom


Traitement des champs en cours d'édition

nom
prénom


Vérification lors de la frappe

On peut utiliser onkeydown pour un traitement avant modification du champ ou onkeyup pour un traitement a posteriori.

Noter l'utilisation de return (ne fonctionne qu'avec onkeydown)

Tapez du texte (mais pas de chiffre)





Traitement d'un formulaire uniquement en Javascript

Propriétés spécifiques aux éléments de formulaire

Valables pour certains des éléments (pas forcément tous, ex. selected).
value
Pour les champs de formulaire uniquement. Contient la valeur actuelle du champ. L'attribut value, accessible par getAttribute(), quant à lui, contient la valeur par défaut.
name
pour les éléments qui ont un attribut name, et en particulier les champs de formulaire, la valeur de l'attribut en question.
disabled
un booléen. Permet de désactiver/activer un champ
readOnly
un booléen. Permet de placer un champ en lecture seule
checked
pour les cases à cocher (CheckBox). Permet de les cocher/décocher
selectedIndex
pour des listes de type Select, permet de fixer ou consulter l'élément sélectionné
selected
S'utilise sur un élément option dans une liste. Permet de le sélectionner/déselectionner.

Propriétés des éléments de formulaire textuels: input (texte), textarea

name
nom de l'élément (et variable qui sera envoyée au serveur)
value
valeur de l'élément. en lecture et en écriture.

Événement spécifique : onchange

Propriétés de <input type="checkbox"> et <input type="radio">

name
nom de l'élément (et variable qui sera envoyée au serveur)
checked
booléen (true ou false) permettant de savoir si l'élément est coché. en lecture et en écriture.
value
valeur de l'élément.

Checkbox





Attention, pas de "onchange" !

Solution : onclick

Checkbox





Propriétés des éléments de formulaire: select

Un élément select contient des éléments option.

Si le select ne permet qu'une sélection, on utilisera la propriété value du select :

  	var monSelect= document.getElementById("idSelect");
	var monOpt= monSelect.value;
Sinon, on récupèrera le tableau des options (options[]) ou on attaquera directement l'option désirée.

Le code suivant donne la première option sélectionnée:

	var monOpt= monSelect.options[monSelect.selectedIndex].value;
Dans le cas où il y a plusieurs options sélectionnables, le code suivant les range dans un tableau:
	var o= monSelect.options;
	var resultat= new Array();
	var i;
	for (i= 0; i < o.length; i++) {
		if (o[i].selected) {
			resultat.push(o[i].value);
		}
	}

Le select a aussi une propriété selectedIndex qui donne la position de l'élément selectionné.

Notez que value, selectedIndex (pour les select) et selected pour les options peuvent être modifiés.

Méthodes des éléments de page : les tables

On peut éventuellement manipuler directement le DOM des tables, mais des méthodes spécifiques sont prévues : Si tabElt est un élément de type table, il dispose des propriétés et méthodes suivantes:

Méthodes pour les lignes de tableau

On devra aussi pouvoir manipuler les tr: Pour ajouter une ligne de trois cases à la fin d'un tableau (désigné par la variable tabElt) on fera donc:
var tabElt= document.getElementById("monTableau");
var rowElt= tabElt.insertRow(-1);
var cellule= rowElt.insertCell(-1);
cellule.textContent= "case 0";
cellule= rowElt.insertCell(-1);
cellule.textContent= "case 1";
cellule= rowElt.insertCell(-1);
cellule.textContent= "case 2";

Les événements

Quelques propriétés des événements

Position d'un événement relativement à un élément

Pour donner la position d'un événement dans l'élément auquel il est lié, on ne dispose pas de méthode standard.

IE propose offsetX/offsetY, et les autres, rien.

D'où le code

        // offsetX est-il défini ??
        if (event.offsetX) {
	   x= event.offsetX;
	   y= event.offsetY;
	} else {
           // On calcule la position
	   pos_x = event.pageX-document.getElementById("eltID").offsetLeft;
	   pos_y = event.pageY-document.getElementById("eltID").offsetTop;	   
	}
  

Le DOM (Document Object Model)

Représentation d'un document

Un document HTML, aux yeux du DOM, est un arbre composé de noeuds, qui représentent les balises (appelées éléments), le texte, et les attributs. En pratique, on traitera les attributs à part.

Soit donc le document (simplifié):

<html>
	<head>
		<title>Un titre</title>
	</head>
	<body>
		<p> Un essai <em>de texte</em>.</p>
	</body>
</html>

Les noeuds (introduction)

Accès aux éléments

Accès aux éléments (suite)

Accès aux éléments (HTML5)

Exemple

    
un exemple pour tester
op

Propriétés et méthodes des éléments

Tout élément elt a les propriétés suivantes.

Propriétés des noeuds textes

nodeType
toujours à 3 pour un noeud texte.
nodeValue
texte contenu dans le noeud. On peut modifier cette valeur.
Exemple:

ce texte sera modifié, pas celui-ci



Parcours d'un document

Pour parcourir un document, on va typiquement:
  1. Récupérer l'élément racine à partir duquel on fera le parcours.
  2. Utiliser childNodes pour parcourir les fils des éléments en question.
  3. Pour les dit fils, on regardera quel est leur type, et on agira en conséquence.

=> parcours d'arbre

Exemple: on veut afficher le texte de la liste précédente dans l'élément ci-dessous.
texte quelconque




Remarques sur les propriétés

En théorie, on peut aussi manipuler des noeuds qui représentent les attributs. Mais en pratique, un bon nombre de navigateurs internets ont des interprétations trop personnelles de ceux-ci. On utilisera donc les propriétés des éléments :
style
pour accéder aux informations CSS (en lecture et en écriture)
className
pour lire ou écrire la classe CSS d'un élément
id
pour accéder à l'identifiant d'un élément

Modification des éléments: 1) innerHTML

Principe

innerHtml est une propriété des éléments DOM, et représente le code HTML compris à l'intérieur d'une balise. Par exemple, si j'ai la balise :
	<ul id='maliste'>
		<li> un</li>
		<li> deux</li>
	</ul>
	
Alors, document.getElementById("maliste").innerHTML vaut
		<li> un</li>
		<li> deux</li>
	

L'intérêt de cette propriété est qu'on peut l'utiliser pour modifier le contenu d'une balise.

Exemple

Du texte à remplacer....

Le code correspondant:


	
	

Intérêt et limitations de innerHTML

<button onclick="document.getElementById('inner2').innerHTML= document.getElementById('inner1').value" >remplacer</button>

Ce texte sera remplacé...

Solution au dernier problème: écrire une fonction qui remplace les caractères <, > et & par &lt;, &gt; et &amp;, et l'utiliser lors du remplacement... ou passer par le DOM.

Création en passant par le DOM

Création de noeud

Deux méthodes de l'objet document :

Les éléments sont simplement créés, et pas insérés dans l'arbre.

Insertion d'élément

On insère les éléments dans un élément parent, en utilisant les méthodes suivantes (n étant un noeud) :

Exemple: pour insérer en première position, on fera
   parent.insertBefore(nouveau, parent.firstChild);
Si la liste des enfants est vide, firstChild est null et ça fonctionne quand même.

Remplacement et suppression d'élément

Premier exemple

On reprend l'exemple utilisé pour innerHTML, mais en l'écrivant de manière sûre

Ce texte sera remplacé...




Exemple de modification au travers du DOM...

On crée une liste dont la taille augmente à chaque click sur un bouton. Utilisation pratique: formulaire avec nombre variable d'entrées...





Remarque: ce code n'est pas du HTML valide, car une liste n'a pas le droit d'être vide (en voilà une idée qu'elle est étrange, car quand le code est créé automatiquement, on peut très bien se retrouver avec des "listes" vides. Supposez une requête qui ne renvoie rien, par exemple). Pour bien faire, il faudrait, soit ajouter un élément <li> caché (display="hidden"), soit ne créer la liste qu'avec le premier élément.

Version ancienne du DOM (Pré-XML)

Exemple:

<form name="monFormulaire2" action="uneAction" onsubmit="return prixPositif()">
<input type="text" name="prix">
........
</form>

<script type="text/javascript">
function prixPositif() {
	var p= document.monFormulaire2.prix.value;
	p= parseFloat(p); 
	// si p non numérique, retourne la valeur NaN (not a number)
	// On peut tester avec isNaN
	return ! isNaN(p) && p > 0;
}
</script>

système simple, mais qui rend difficile l'écriture de code réutilisable.

Ne fonctionne pas en XHTML strict: name n'est plus défini pour les <form>.

Chargement des pages

L'intéraction entre javascript et la page web dépend de l'existence de certains objets DOM. Il importe donc de savoir comment se passe le chargement des pages:

Exemple où l'ordre est respecté

Ce paragraphe sera en rouge sur fond jaune

<p id='par1'>Ce paragraphe sera en rouge sur fond jaune </p>

<script type="text/javascript">
	document.getElementById('par1').style.backgroundColor='yellow';
	document.getElementById('par1').style.color='red';
</script>

Exemple où l'ordre n'est pas respecté

Ce paragraphe ne va pas changer de couleur

<script type="text/javascript">
	document.getElementById('par2').style.backgroundColor='yellow';
	document.getElementById('par2').style.color='red';
</script>

<p id='par2'>Ce paragraphe ne va pas changer de couleur </p>
En revanche, une fonction peut référencer un élément qui n'existe pas encore. Ce qui importe, c'est qu'il existe quand la fonction est appelée.

Ce paragraphe sera aussi en rouge sur fond jaune

<script type="text/javascript">
	function changerCouleurPar3() {
		document.getElementById('par3').style.backgroundColor='yellow';
		document.getElementById('par3').style.color='red';
	}
</script>

<p id='par3'>Ce paragraphe sera aussi en rouge sur fond jaune </p>

<script type="text/javascript">
	changerCouleurPar3();
</script>

L'événement onload

Étude du fichier presentation.js

Principes:

That's all folks