CSS
Un peu de bling bling: jQuery & cartes

Introduction

Le but de ce TD est de rendre vos pages plus interactives grâce à l'utilisation de Javascript (principalement de jQuery), d'Ajax et de cartes géographiques.

À la différence des TD précédents, obligatoires pour la réussite de votre site, ce TD est plutôt une collection de petits exercices illustrant les possiblilités qui vous sont offertes. Il y a systématiquement des exemples et un corrigé. Sélectionnez les exercises qui vous intéressent le plus et dont vous pourrez avoir besoin pour votre propre site !

jQuery

jQuery vs Javascript

Il est tout d'abord important de souligner que jQuery n'est rien d'autre qu'une bibliothèque Javascript. Son principal avantage est qu'il simplifie de nombreuses choses généralement fastidieuses à faire en Javascript brut, et ce en gardant toute la puissance du langage de départ. En particulier, il n'y a pas à se soucier des compatibilité avec le navigateur : jQuery s'en chargera pour vous.

Une autre force de jQuery est qu'il existe de nombreuses bibliothèques (ou plugins) qui s'y intègrent directement, mais nous n'en parlerons pas ici. Vous les trouverez tout seul en cherchant sur le net.

Utilisation

Pour pouvoir utiliser jQuery, il faut ajouter la ligne suivante dans le head de votre fichier HTML. Bien sûr, il faudra télécharger le fichier jquery-3.6.0.min.js et l'enregistrer dans un sous-répertoire js.

    
    <script type="text/javascript" src="js/jquery-3.6.0.min.js"></script>
        

Grands principes

Ce TD ne prétend pas être un cours sur jQuery. Nous allons donc juste évoquer les grandes idées derrière jQuery.

Autorisons-nous un parallèle entre jQuery et CSS. L'emploi du CSS permet de séparer le contenu et sa mise en forme. jQuery permet quand à lui de séparer le contenu et son comportement. Ainsi, la manière classique d'utiliser jQuery est de produire un fichier HTML (éventuellement via PHP) qui ne contient pas de Javascript si ce n'est une fonction qui va modifier le document une fois ce dernier chargé (enfin, une fois sa structure chargée : inutile donc d'attendre le chargement des images par exemple).

Le plus simple est donc d'ajouter la ligne suivante dans le head de votre fichier HTML. Bien sûr, il faudra écrire le code jQuery dans le fichier code.js et l'enregistrer dans le sous-répertoire js.

    
    <script type="text/javascript" src="js/code.js"></script>
        

Il est important que votre site fonctionne même sur un navigateur où Javascript n'est pas activé (peut-être que certaines fonctionnalités seront indisponibles, mais le principal doit être accessible). Testez donc systématiquement votre code avec Javascript désactivé. Le plugin Web Developer de Firefox permet de facilement activer et désactiver Javascript.

JQuery modifie en profondeur le HTML une fois ce dernier chargé ; néanmoins, en affichant le code source de votre page, vous ne verrez que le code avant modification, ce qui n'est pas très utile pour du débuggage. Dans Firefox ou Chrome, vous pourrez pour cela utiliser le plugin Web Developer (Voir Source -> Voir le code généré). Le plugin Firebug pourra se révéler precieux pour le débuggage du Javascript / jQuery.

Il sera utile de se référer à la documentation de jQuery.

L'ouvrage jQuery in Action est très bien fait (sur la page web deux chapitres sont téléchargeables librement, dont le premier qui propose une très bonne introduction à jQuery).

Interface de test

Nous avons mis en place deux interfaces de tests: la première, pour vous familiariser avec les sélecteurs de jQuery; la seconde, pour vous familiariser avec des commandes plus complexes. Les deux ont la même structure : une zone de saisie d'un sélecteur / d'une commande, une page de test (qui sera modifiée et dont les éléments sélectionnés seront encadrés) et enfin le code HTML de la page.

Sélecteurs

Ouvrez le testeur dans un nouvel onglet.

Écrivez un sélecteur qui capture tous les liens de la page.
a
Écrivez un sélecteur qui capture toutes les entrées de classe myList d'une liste (on utilisera .).
li.myList
Écrivez un sélecteur qui capture le div d'id someDiv (on utilisera #).
div#someDiv
Écrivez un sélecteur qui capture tous les liens se trouvant dans un item de liste qui est un fils direct d'une liste de classe myList (on utilisera >).
ul.myList > li > a
Écrivez un sélecteur qui capture tous les liens dont l'adresse contient INF441a (on utilisera *=).
a[href*=INF441a]
Écrivez un sélecteur qui capture la dernière entrée de chaque liste (on utilisera last-child).
li:last-child
Écrivez un sélecteur qui capture toutes les checkbox cochées (on utilisera type=checkbox et :checked).
input[type=checkbox]:checked 
ou
:checkbox:checked
Écrivez un sélecteur qui capture tous les inputs qui ne sont pas des checkbox (on utilisera :not).
input:not([type=checkbox])
ou
input[type!=checkbox]
Écrivez un sélecteur qui capture toutes les images qui n'ont pas de titre alternatif (on utilisera img[alt]).
img:not(img[alt])
      
ou
img:not([alt])

Commandes

Ouvrez le testeur dans un nouvel onglet.

Écrivez une commande qui remplace le contenu du div d'id someDiv par Salutation (on utilisera .html).
$("div#someDiv").html("Salutation")
Écrivez une commande qui ajoute à toute image sans titre alternative le titre Young Rossin (on utilisera .attr).
$("img:not(img[alt])").attr("alt","Young Rossin")
Écrivez une commande qui change la couleur de fond à rouge pour le div d'id someDiv
$("div#someDiv").css('background-color','red')
Faites plaisir à Dominique. Remplacez toutes les images par la photo de Dominique.
$("img").attr("src","images/youngRossin.jpg")
Écrivez une commande qui ajoute à la fin de chaque entrée de liste le nombre de liens qu'il contient (on utilisera .each, .find et .size).
   $("li").each(function(i){
   $(this).append(" (Il y a "+$(this).find("a").size()+" liens dans cette entrée)");
   })
      
Écrivez une commande qui fait disparaitre toutes les images sauf celle de votre enseignante préférée.
$("img:not(#hardebolle)").fadeOut()

Exemples simples

Afficher / Masquer du texte

On souhaite avoir une zone cliquable qui affiche un texte. Une fois ce texte affiché il est masqué lors d'un nouveau clic. Voici un exemple.

Le modal web c'est vraiment fabuleux

Réaliser cette animation. On pourra utiliser les commandes jQuery hide, show, slideToggle, attr, html,toggle et click.

    
    <span id="ZoneDeClic"></span>
    <div id="TexteAAfficher" style="text-align:center;font-size: large">Le modal web c'est vraiment fabuleux</div>
        
    
$(document).ready(function(){
    // on masque la zone
    $("#TexteAAfficher").hide();
    // on ajoute le texte cliquable et on y met un attribut pour savoir si on est masqué ou affiché
    $("#ZoneDeClic").html("<p>Cliquer pour faire apparaitre le texte</p>")
    .attr("statut","1")
    .click(function(){
        $("#TexteAAfficher").slideToggle("slow");
        // selon le statut on renomme le texte
        if ($("#ZoneDeClic").attr("statut")=="1"){
            $("#ZoneDeClic").html("<p>Cliquer pour faire disparaitre le texte</p>").attr("statut","0");
        }
        else{
            $("#ZoneDeClic").html("<p>Cliquer pour faire apparaitre le texte</p>").attr("statut","1");
        };
    });
});

Tout au long de ce sujet, les solutions peuvent être affichées par un clic sur une zone de texte. Comme il y a beaucoup de solutions, nous avons écrit une seule commande jQuery pour gérer l'affichage des solutions. On va faire de même ici.

Notre but est d'obtenir le rendu suivant

Le modal web c'est vraiment fabuleux
Le modal réseau c'est vraiment fabuleux
Les autres modal sont moins drôles

Avec ce code HTML:

    
    <div class="zoneTexteAfficherMasquer">
        <span class="inviteClic"></span>
        <div class="TexteAAfficher" style="text-align:center;font-size: large">Le modal web c'est vraiment fabuleux</div>
    </div>

    <div class="zoneTexteAfficherMasquer">
        <span class="inviteClic"></span>
        <div class="TexteAAfficher" style="text-align:center;font-size: large">Le modal réseau c'est vraiment fabuleux</div>
    </div>

    <div class="zoneTexteAfficherMasquer">
        <span class="inviteClic"></span>
        <div class="TexteAAfficher" style="text-align:center;font-size: large">Les autres modal sont moins drôles</div>
    </div>
    
Attribuez automatiquement des id à l'aide de jquery au div de classe TexteAAfficherMasquer à l'intérieur des différents div de classe zoneTexteAfficherMasquer. Le premier élément div.TexteAAfficher recevra comme identifiant TexteAAfficher1, puis TexteAfficher2 et ainsi de suite. Pour parcourir tous les éléments div.TexteAAfficherMasquer vous pouvez utiliser la function .each() de jquery de la manière suivante:
    
$("div.TexteAAfficherMasquer").each(function(i) {
    // i contient le numéro de l élément; attention, la numerotation commence a 0
});    
À l'intérieur de la boucle, la fonction $(this).find() de jQuery pourra vous permettre de sélectionner des éléments à l'intérieur de l'élément actuel.
    
$(document).ready(function(){
    $("div.zoneTexteAfficherMasquer").each(function(i){
        $(this).find("div.TexteAAfficher").attr("id","TexteAAfficher"+(i+1));
    });
});
Écrivez le code jQuery pour obtenir les trois zones de texte à faire apparaître et disparaître.
    
$(document).ready(function(){
    // on sélectionne tous les div avec la classe zoneTexteAfficherMasquer et on les parcourt
    $("div.zoneTexteAfficherMasquer").each(function(i){
        // find permet d appliquer un sélecteur sur un ensemble selectionné
        $(this).find("div.TexteAAfficher").attr("id","TexteAAfficher"+(i+1)).hide();
        $(this).find("span.inviteClic").attr("id","inviteClic"+(i+1)).html("<p>Cliquer pour faire apparaitre le texte</p>").attr("statut","1").click(
        function(){
            $("#TexteAAfficher"+(i+1)).slideToggle("slow");
            // selon le statut on renomme le texte
            if ($("#inviteClic"+(i+1)).attr("statut")=="1"){
                $("#inviteClic"+(i+1)).html("<p>Cliquer pour faire disparaitre le texte</p>").attr("statut","0");
            }
            else{
                $("#inviteClic"+(i+1)).html("<p>Cliquer pour faire apparaitre le texte</p>").attr("statut","1");
            };
        })
    });
});

Tronquer du texte trop long

Imaginons par exemple un forum. Les messages trop longs sont souvent tronqués et peuvent être déroulés si besoin. Voici un exemple

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

Ce texte est un court, on n'a pas besoin de le tronquer

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

À vous de jouer. Le code HTML consistera simplement de blocs <div class="zoneTexte">...<div>. On pourra utiliser la fonction javascript substr pour tronquer du texte. La fonction jQuery find sera aussi utile.

    
$(document).ready(function(){
    // on sélectionne tous les div avec la classe zoneTexte et on les parcourt
    $("div.zoneTexte").each(function(i){
        // on récupère la longueur du texte et on coupe à la longueur 100 (s'il est aussi long)
        var contenu = $(this).html();
        var longueur = contenu.length;
        if (longueur > 100){
            var debut = contenu.substr(0,100);
            var suite = contenu.substr(101);
            $(this).html(debut);
            $(this).append("<span style='font-weight: bold' id='continuer"+(i+1)+"'> [Afficher la suite...]</span>");
            $(this).append("<span id='suite"+(i+1)+"'>"+suite+"</span>");
            $(this).append("<span style='font-weight: bold' id='masquer"+(i+1)+"'> [Réduire]</span>");
            $("#suite"+(i+1)).hide();
            $(this).find("span#continuer"+(i+1)).click(
            function(){
                $(this).hide();
                $("#suite"+(i+1)).fadeIn("slow");
                $("#masquer"+(i+1)).fadeIn("slow");
            })
            $(this).find("span#masquer"+(i+1)).click(
            function(){
                $(this).hide();
                $("#suite"+(i+1)).fadeOut("slow",function(){
                $("#continuer"+(i+1)).fadeIn("slow")});
            }).hide()
        }
    });
});

Attention, si le texte à afficher contient des balises HMTL le problème se complique fortement…

Formulaires: affichage conditionnel de champs

On souhaite réaliser le formulaire suivant dans lequel un champ n'apparait que si une case est cochée (et disparait si elle est décochée).

Raisons pour lesquelles vous suivez le modal web

Voici le code html du formulaire

    
<form action="" method="get" class="exempleCacherMasquer">
    <fieldset>
        <legend>Raisons pour lesquelles vous suivez le modal web</legend>
        <p class="formulaire">
            <label for="charge" class="left">Les chargés de TD sont trop sympas</label>
            <input id="charge" type="checkbox" name="charge"/>
        </p>

        <p class="formulaire">
            <label for="binet" class="left">Mon binet n'avait pas de site web</label>
            <input id="binet" type="checkbox" name="binet"/>
        </p>

        <p class="formulaire">
            <label for="CBDominique" class="left">A cause de Dominique</label>
            <input id="CBDominique" type="checkbox" name="Dominique" value="0"/>
        </p>
        <p id="SiDominique" class="formulaire">
           <label for="MaisPourquoi" class="leftIt">A oui? mais pourquoi donc?</label>
           <input name="MaisPourquoi" id="MaisPourquoi" size="30" value=""/>
        </p>
    </fieldset>
</form>

    

et le CSS associé

    
form.exempleCacherMasquer{
   padding:10px;
   height:200px;
}
form.exempleCacherMasquer p.formulaire{
   width:400px;
   padding-left: 305px;
   text-align: left;
   vertical-align: top;
}
form.exempleCacherMasquer label.left{
   float: left;
   margin-left: -305px;
   font-weight:bold;
}

form.exempleCacherMasquer label.leftIt{
   float: left;
   margin-left: -305px;
   font-style: italic;
}

form.exempleCacherMasquer legend{
   font-weight:bold;
   font-size:larger;
}

form.exempleCacherMasquer fieldset{
   float:left;
   height:auto;
   width:90%;
}
    

Pour réaliser le formulaire, on pourra utiliser les commandes jQuery suivantes: click, hide, show. De plus on remarquera que $('#CBDominique:checked').val() !== undefined vaut true si et seulement s'il existe un input d'id CBDominique qui est coché.

    
$(document).ready(function(){
    $("#SiDominique").hide();
    $("#CBDominique").click(function () {
        if ($('#CBDominique:checked').val() !== undefined) {
            // la case est donc cochée -> on affiche
            $("#SiDominique").show();
        }
        else {
            // la case n'est donc pas cochée -> on affiche
            $("#SiDominique").hide();
        }
    });
});
    

Un formulaire de login

On souhaite proposer, à la manière des placeholders des formulaires en HTML5, un formulaire où la nature de l'information à saisir est écrite dans le champ mais s'efface dès que le champ est sélectionné. Bien sûr si le champ n'est plus sélectionné et si rien n'a été saisi, on veut revoir l'information. Voici un exemple.

Inscription

Voici le code html associé

    
    <form action="" method="get"  class="exempleLogin">
        <fieldset>
            <legend>Identification</legend>
            <input name="Nom" id="ExempleNom" type="text" size="30" />
            <input name="Prenom" id="ExemplePrenom" type="text" size="30" />
        </fieldset>
    </form>

Pour le réaliser, on pourra utiliser les commandes jQuery suivantes: attr, css, focusin et focusout.

    
$(document).ready(function(){
    // sélection de l'input, changement de la couleur et mise de la valeur par défaut
    // Si on a le focus sur l'input, on efface le texte et on repasse avec des couleurs normales
    // Quand le focus n'est plus sur l'input, on remet le texte par défaut et la couleur grise si rien n'a été saisi
    $("#ExempleNom").css("color","gray").attr("value","Nom").focusin(function(){
        $("#ExempleNom").attr("value","").css("color","black");
    }).focusout(function(){
        if ($("#ExempleNom").attr("value") == ""){
            $("#ExempleNom").css("color","gray").attr("value","Nom")
        }
    });
    // idem.
    $("#ExemplePrenom").css("color","gray").attr("value","Prénom").focusin(function(){
        $("#ExemplePrenom").attr("value","").css("color","black");
    }).focusout(function(){
        if ($("#ExemplePrenom").attr("value") == ""){
            $("#ExemplePrenom").css("color","gray").attr("value","Prénom")
        }
    });
});

Maintenant, imaginons que l'on souhaite réaliser de la sorte un formulaire de login. Il faut alors changer le type du champs de saisie de mot de passe lorsqu'il est sélectionné.

Identification

Malheureusement, on ne peut changer en javascript le type d'un input. Proposez une soution pour réaliser le formulaire ci-dessous. Vous pourrez utiliser la commande jQuery focus.

    
     <!-- on duplique le champ password: un vrai et un faux-->
     <form action="" method="get" class="exempleLogin">
        <fieldset>
            <legend>Identification</legend>
            <input name="Login" id="ExempleLogin" type="text" size="30" />
            <input name="Password" id="ExemplePasswordFaux" type="text" size="30" />
            <input name="Password" id="ExemplePasswordVrai" type="password" size="30" />
        </fieldset>
    </form>
        
    
$(document).ready(function(){
    // on cache le vrai champs password sauf s'il est rempli
    $("#ExemplePasswordVrai").hide().focusout(function(){
        if ($("#ExemplePasswordVrai").attr("value") == ""){
            $("#ExemplePasswordVrai").hide();$("#ExemplePasswordFaux").show()
        }
    });
    $("#ExempleLogin").css("color","gray").attr("value","Login").focusin(function(){
        $("#ExempleLogin").attr("value","").css("color","black");
    }).focusout(function(){
        if ($("#ExempleLogin").attr("value") == ""){
            $("#ExempleLogin").css("color","gray").attr("value","Login")
        }
    });
    // une fois dans le champs password faux, on le masque et on affiche le vrai et on y met le focus à la vrai
    $("#ExemplePasswordFaux").css("color","gray").attr("value","Mot de passe").focusin(function(){
        $("#ExemplePasswordFaux").hide();$("#ExemplePasswordVrai").show().focus();
    })
});

De l'utilité du callback

On souhaite avoir un bouton qui permet de passer d'une image à une autre. Par exemple:



youngRossin

Réaliser cette animation.

    
        <button type="button" id="PoidsAnneesBouton">Le poids des années</button><br/><br/>
        <div style="text-align:center"><img src="./testeur/images/youngRossin.jpg" id="PoidsAnneesImage" style="height:100px" alt="youngRossin" /></div>
        
    
$(document).ready(function(){
    $("#PoidsAnneesBouton").click(function(){
        $("#PoidsAnneesImage").attr("src","./testeur/images/rossin.jpg");
        $("#PoidsAnneesBouton").hide();
    });
});

On souhaite maintenant que les images apparissent/disparraisent en fondu (fadeOut puis fadeIn). Par exemple:



youngRossin

Réalisez cette animation. Pour cela, vous devrez utiliser le callback du fadeOut pour éviter que les images ne se chevauchent lors de leur disparition.

    
$(document).ready(function(){
    $("#PoidsAnneesBouton2").click(function(){
        $("#PoidsAnneesImage2").fadeOut("slow",function(){// callback function
            $("#PoidsAnneesImage2").attr("src","./testeur/images/rossin.jpg").fadeIn();
        });$("#PoidsAnneesBouton2").hide();}
    );
});

Exemples avancés

Table des matières automatiques

Nos énoncés de TD sont souvent très longs et il faut parcourir une bonne dizaine d'écrans pour retrouver une information. Il serait fortement utile d'avoir une table des matières permettant de choisir la section et la sous-section désirées pour naviguer plus rapidement.

Construction du répertoire

Dans un premier temps, on va récupérer tous les éléments de type h1 dans le document et leur affecter un identifiant id. En effet, notre document se présente sous la forme suivante:

    
<h1>Introduction</h1>

blah, blah

<h1>Première partie</h1>

Le seconde est mieux

<h1>Seconde partie</h1>

En attendant la troisième
        

Attribuez automatiquement des id à l'aide de jquery. Le premier élément de type h1 recevra comme identifiant h1Entree1 puis h1Entree2 et ainsi de suite.

    
$(document).ready(function(){
    $("h1").each(function(i) {
        $(this).attr("id","h1Entree"+(i+1));
    });
});

Nous allons maintenant créer une liste en début de document avec des liens vers les différentes parties. Nous allons donc dans un premier temps insérer un nouveau bloc de type div au début du document, puis créer à l'intérieur de ce bloc une liste où chaque élément est un lien vers une partie. On rapelle que pour faire un lien en interne dans un document on peut écrire

    
<ul>
<li><a href="#h1Entree1">Introduction</a></li>
<li><a href="#h1Entree2">Première partie</a></li>
</ul>

Pour réaliser cette opération, il vous faut insérer du code en début de body. Vous pouvez utiliser la fonction jquery $("body").prepend("Debut de body");. Ensuite vous pouvez utiliser la fonction append similaire à prepend mais qui rajoute le code à la fin d'un élément.

    
$(document).ready(function(){
    $("body").prepend("<div><ul id=\"toc\"></ul></div>");
    $("h1").each(function(i) {
        $(this).attr("id","h1Entree"+(i+1));
        $("#toc").append("<li><a href=\"#h1Entree"+(i+1)+"\">"+(i+1)+"/"+$(this).html()+"</a></li>");
    });
});

Un peu de style

Notre table des matières est presque prête mais il faut maintenant la rendre disponible dans le document où que nous nous trouvions. En effet, si l'utilisateur est à la partie 3 de votre document il lui faut remonter jusqu'en haut du document pour la trouver.

Pour ce faire vous pouvez changer le style du conteneur div du menu en ajoutant un positionnement fixed. Pour que la liste apparaisse de manière horizontale il faut:
  • Enlever les petits ronds en début de la liste (attribut de style list-style-type:none d'une liste ul)
  • Mettre la liste à l'horizontale : (attribut de style display:inline)
    

$(document).ready(function(){
    $("body").prepend("<div style=\"border: solid 1px black; position:fixed; z-index:2; background-color:white; width:79%; padding:0 0 0 0; margin:0 0 0 0; \"><ul id=\"toc\" style=\"list-style-type:none; display:inline\"></ul></div>");
    $("h1").each(function(i) {
        $(this).attr("id","h1Entree"+(i+1));
        $("#toc").append("<li style=\"padding: 20px; display:inline\"><a href=\"#h1Entree"+(i+1)+"\">"+(i+1)+"/"+$(this).html()+"</a></li>");
    });
});

Démonstration

Si vous voulez voir fonctionner l'exemple cliquez ici.

Un joli menu déroulant avec CSS et jQuery

On souhaite faire un menu avec des sous-menus qui n'apparaissent qu'une fois que la souris passe sur l'item parent. Voici un exemple de rendu.

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum

Le code HTML de la page est le suivant:

    
<body>
    <div class="menu">
        <div class="menuItem">
            <div class="intituleItem">Item 1</div>
            <div class="sousMenuItem">Sous item 1</div>
            <div class="sousMenuItem">Sous item 2</div>
            <div class="sousMenuItem">Sous item 3</div>
            <div class="sousMenuItem">Sous item 4</div>
        </div>
        <div class="menuItem">
            <div class="intituleItem">Item 2</div>
        </div>
        <div class="menuItem">
            <div class="intituleItem">Item 3</div>
            <div class="sousMenuItem">Sous item 1</div>
            <div class="sousMenuItem">Sous item 2</div>
        </div>
    </div>

<div style="clear:both;margin-top:110px">
        <div>
            Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum
        </div>
    </div>
</body>

Le code CSS associé est donné ci-dessous.

    
div.menu{
    left:10px;
    top:10px;
}

div.menuItem{
    display:inline-block;
    vertical-align:top;
    padding:0px;
    margin:2px;
    width:8em;
}

div.sousMenuItem{
    padding: 10px 10px 10px 10px;
    background-color: red;
    text-align: center;
}

div.sousMenuItem:hover{
    background-color: #ffff99;
}


div.intituleItem:hover{
    background-color: #ffff99;
}

div.intituleItem{
    padding:10px;
    background-color: orange;
    margin:0px;
    text-align: center;
}

Il ne vous reste plus qu'à écrire le code jQuery!

    
$(document).ready(function(){
   $("div.sousMenuItem").css ("visibility", "hidden");
   $("div.intituleItem").each(function(){
      $(this).mouseenter(function(){
            $(this).nextAll(".sousMenuItem").css ("visibility", "visible");
      });
   });
   $("div.menuItem").each(function(){
      $(this).mouseleave(function(){
            $(this).children(".sousMenuItem").css ("visibility", "hidden");
      });
   });
});

// Une solution plus bling-bling :
// Si on veut que les menus se deroulent et se cachent progressivement
// on peut utiliser slideUp et slideDown
$(document).ready(function(){
    $("div.intituleItem").each(function(){
        $(this).mouseenter(function(){
            $(this).nextAll(".sousMenuItem").slideDown("slow");
        });
	// Pour cacher les menus. 0 correspond au nombre de millisecondes, donc c'est instantanné
        $(this).nextAll(".sousMenuItem").slideUp(0);
    });
    $("div.menuItem").each(function(){
        $(this).mouseleave(function(){
            $(this).children(".sousMenuItem").slideUp("slow");
        });
    });
});

Ajuster la hauteur d'une colonne à la hauteur de la fenêtre

Imaginons que l'on a la structure suivante de page, et que la partie d'idi colonne soit un menu.

    
        <header style="width:100%;background-color:yellow;height:60px" id="header"></header>
        <div id="colonne" style="width:20%;background-color:red">
            <ul>
                <li>item 1</li>
                <li>item 2</li>
                <li>item 3</li>
            </ul>
        </div>        
        
        <footer style="width:100%;background-color:yellow;height:20px" id="footer"></footer>

        

On souhaite que la colonne de gauche s'étalle jusqu'en bas de la fenêtre même si son contenu s'arrête avant et on souhaite bien sûr ne pas la limiter si son contenu est plus long que la fenêtre.

Utilisez $(window).height() pour récupérer la hauteur de la fenêtre, et $(window).resize pour détecter lorsque la fenêtre est redimensionnée.

    
            //on ajuste la hauteur que si x - hauteur footer - hauteur header > y
            function ajuster(x,y) {
                x = x - $("header").height() - $("footer").height() - 15;
                if (x>y){
                    $("#colonne").css("height",x+"px");
                }
            }

            $(document).ready(function() {
                // on ajuste si besoin la hauteur
                ajuster($(window).height(),$("#colonne").height());
            });

            $(window).resize(function(){
                //si on redimensionne la fenêtre, on ajuste la hauteur (en récupérant au préalable la vraie hauteur)
                $("#colonne").height("auto");
                ajuster($(window).height(),$("#colonne").height());
            })

Un petit formulaire en AJAX

On aimerait faire un formulaire dans lequel on entre un texte. Ensuite, grâce à un appel AJAX on teste si le texte saisi est bon. Si oui on affiche "succès", sinon on affiche un message d'erreur et on réaffiche le formulaire. On pourrait par exemple utiliser un tel formulaire pour faire gérer un formulaire de login. Voici un exemple ci-dessous.

Formulaire Quel est le nom du prof d'amphi du modal web?

Voici le code HTML du formulaire:

    
<div style="width:400px;margin:auto;margin-bottom:200px">
    <div id="message" style="display: none;width: 385px;border: black 1px solid;padding: 5px;text-align: center">
    </div>
    <div id="attente" style="display: none;">
        Un instant<br />
        <img src="ajax-loader.gif" title="Loader" alt="Loader" />
    </div>
    <form action="" id="demoForm" method="post" style="width:400px;margin-bottom: 20px">
        <fieldset style="height:120px;width:360px;">
            <legend>Formulaire</legend>
            <span style="font-size: 0.9em;">Quel est le nom du prof d'amphi du modal web?</span>
            <p>
                <label for="nom">Nom:</label>
                <input type="text" name="nom" id="nom" value="" />
            </p>
            <p>
                <input type="submit" name="Soumettre" id="submit" style="float: right; clear: both; margin-right: 3px;" value="Soumettre" />
            </p>
        </fieldset>
    </form>
</div>

Et le code dans post.php:

    
 <?php
    // on attend un peu
    sleep(1);

    if ($_POST['nom']!="Rossin") {
            $return['erreur'] = true;
            $return['message'] = "Ne vas-tu jamais en amphi???";
    }
    else {
            $return['erreur'] = false;
            $return['message'] = "VICTOIRE!!!";
    }

    echo json_encode($return);
?>

A vous de jouer: écrivez le code jQuery associé.

    
$(document).ready(function(){
	$("#submit").click(function() {
		$("#attente").show();
		$("#demoForm").hide();
		$("#message").hide();
		$.ajax({//envoie les données en POST vers post.php et on récupère le tout au format json
			type : "POST",
			url : "post.php",
			// Type de transformation de données HTTP. On va passer ces données transformées
			// comme argument dans notre fonction de traitement de "success" plus bas
			dataType : "json",
			// ce qu'on envoie: la valeur qui est dans l'input de l'element avec l'id "nom"
			data: {
				nom : $("#nom").val()
			},
			// si tout se passe bien et on a reçu la réponse du serveur :
			success : function(data){// on applique la fonction suivante
                                $("#attente").hide();// on masque l'image d'attente
                                if (data.erreur == true){// en cas de réponse inexacte
                                    //on met sur fond orange le message
                                    $("#message").css("background-color","orange");
                                    // et on reaffiche le formulaire
                                    $("#demoForm").show();
                                }
                                else{ // en cas de réponse correcte
                                    $("#message").css("background-color","white");
                                }
                                $("#message").text(data.message).show();
			},
			error : function(XMLHttpRequest, textStatus, errorThrown) {// une erreur côté serveur web
				$("#waiting").hide(500);
				$("#message").css("background-color","orange").text("Erreur").show();
				$("#demoForm").show();
			}
		});

		return false;
	});
});