Tutoriel : créez une FAQ accessible et facile à mettre à jour avec JQuery

Dérouleur de FAQ JQuery

Lorsqu’un site doit être mis à jour par un animateur de contenus dépourvu de compétences techniques en HTML ou Javascript, le développeur a généralement deux alternatives :

  • limiter les possibilités d’édition au strict minimum : pas d’effets, pas de pages dynamiques ; l’animateur va tout péter et appeler au secours après dix minutes d’utilisation. Résultat : en dehors des fonctionnalités techniques pointues, les pages éditables sont tristounes et statiques.
  • créer des outils d’édition sur mesure : interfaces de gestion de contenus, tables de bases de données bien structurées, plugins super élaborés, le tout en langage serveur (PHP, ASP, Ruby…) ; ainsi on s’assure par divers garde-fous que les données sont au format voulu. Le site gagne en dynamisme, mais en contrepartie d’une complexité accrue, tant côté développement qu’administration.

A l’heure de mettre en ligne une FAQ (Foire aux questions), je me suis posé la question suivante : comment concilier la souplesse de mise à jour avec le dynamisme de javascript ? Pour rappel, le fonctionnement classique d’une FAQ est le suivant : une liste de questions rangées par thème, un clic sur la question affichant immédiatement la réponse associée.

Je me suis donc mis en tête d’utiliser la puissance de JQuery et des sélecteurs pour réaliser ce travail. Voici comment procéder, en

1. Créer les balises

Partons d’une structure de pages simple, aisément déclinable : un titre principal (h1), des sections (h2), des questions (h3) et enfin des réponses (p). Il s’agit d’un code facile à produire et à éditer dans un éditeur Wysiwig (ex. TinyMCE). Nous n’allons pas créer une page HTML complète, puisque cette FAQ sera mise à jour par l’animateur de contenus. Le code pourra donc ressembler à ça :

<h1>FAQ de l'administrateur</h1> <h2>Section 1 : Connexion</h2> <h3>Comment puis-je m'inscrire ?</h3> <p>L'inscription est gratuite et ouverte à tout le monde. Cliquez sur le lien "inscription" présent à droite du logo.</p> <h3>Je suis inscrit, mais le site ne me reconnaît pas. Comment faire ?</h3> <p>Cliquez sur "connexion" puis saisissez l'adresse e-mail ainsi que le mot de passe saisis lors de votre inscription. </p> <h2>Section 2 : Publication</h2> <h3>Comment publier un article</h3> <p>Après vous être connecté, vous pourrez immédiatement proposer un article en cliquant sur "publier un article" dans le menu de gauche. Votre article sera relu par notre comité de rédaction qui décidera de le publier ou non.</p> 

2. Un peu de mouvement avec jquery

Nous souhaitons maintenant que ce texte se comporte comme une FAQ. Nous voulons donc pour chaque question :

  • masquer/replier la réponse associée au chargement de la page
  • afficher la question comme un lien (par ex. bleu, souligné, avec un curseur en forme de pointeur)
  • lors d’un clic sur la question, basculer l’état du paragraphe qui suit : visible s’il était masqué, masqué s’il était visible.

JQuery rend cette manipulation extrèmement aisée. Voici le code nécessaire :

// On inclut le source JQuery (en head) <script type="text/javascript" src="jquery-1.2.3.min.js"></script> <script type="text/javascript"> // On lance la boucle sur tous les H3 $('h3').each(function() {     // On masque le paragraphe qui suit     $(this).next('p').hide();     // On copie le style des balises A     var couleurLien = $('a').css("color");     $(this).css({"text-decoration" : "underline", "color" : couleurLien, "cursor":"pointer"});     // A chaque clic, on bascule l'état de l'élément P suivant     $(this).click(function() {         $(this).next('p').toggle();     }); }); </script>

Et voilà ! Votre FAQ s’anime et réagit à chacun des clics. Il reste à choisir d’inclure le code en intégralité, ou le lier sous forme externe dans une balise SCRIPT directement à la fin du code source éditable (avec le risque que l’utilisateur l’efface) ou de le charger sur toutes les pages de votre site, en le déclenchant uniquement lorsqu’une condition est remplie (par exemple en fonction de l’url, ou encore en détectant la présence d’un ID d’élément particulier).

Attention cependant : la réponse à chaque question ne doit comporter qu’un seul paragraphe. Les éventuels sauts de ligne auront la forme de balises BR exclusivement.

Démonstration

 

Conclusion

On fait en toute simplicité un pas supplémentaire vers la séparation entre la forme et le contenu. De plus, cette méthode se dégradera grâcieusement sur les dispositifs ne disposant pas de Javascript.

Mise à jour 23 juillet 2008 : pour l’impression, il est nécessaire de dérouler l’ensemble des réponses, sinon il n’affichera que les titres. Pour cela, on crée avec JQuery un lien « version imprimable » qui se contente d’afficher tous les paragraphes et d’appeler la fonction window.print(). Le code :

  On crée l'élément "version imprimable" qu'on insère avant le H1 du titre var imprimer = document.createElement('a'); imprimer.id = "imprimer"; imprimer.innerHTML = "Version Imprimable"; $(imprimer).insertBefore('h1'); A chaque clic sur cet élément, les P sont affichés et l'impression peut se lancer. $('#imprimer').click(function() {     $('p').show();     window.print(); }); 

 

Outil de référencement professionnel - essai gratuit Ce contenu a été publié dans Webdesign, avec comme mot(s)-clé(s) , , , , , , , . Vous pouvez le mettre en favoris avec ce permalien.

16 réponses à Tutoriel : créez une FAQ accessible et facile à mettre à jour avec JQuery

  1. Iridium dit :

    Salut :)
    Je cherchais un truc sympa comme cela à mettre en place sur des fonctionnalités de mon site, mais je n’y arrive pas.
    J’ai essayé plusieurs choses. Tout mettre entre les balises HEAD, tout mettre dans un fichier externe js appelé dans la balise HEAD, mettre ça à la fin avant la balise /BODY
    C’est surement un truc simple sur lequel je passe à côté, mais rien n’y fait. J’aurais bien aimé le mettre en place, pour le gain de temps de programmation… à la place du DHTML que j’ai fais pour le même résultat.
    a+
    Iridium

  2. @Iridium, il peut y avoir des dizaines de causes différentes. As-tu une page en ligne histoire que je puisse voir ce qui ne marche pas ?

    Sinon, je te conseille d’installer l’extension Firebug pour Firefox. Cela t’aidera à débugger les erreurs javascript.

  3. Iridium dit :

    Ah oui bonne idée ;)
    Je vais installer l’extension et auditer ça, car il doit y avoir un problème autre (j’aurais dû le faire avant d’ailleurs).
    Surtout que je récupère quelques choses de déjà créé avec des appels à différents templates.
    Je vérifie ça aussi aujourd’hui et je repasse te tenir informé.
    Bonne journée
    Iridium

  4. Tchup dit :

    @Damien : Un CSS spécifique au media "print" contenant p {display:inline} devrait permettre d’afficher l’intégrité du contenu pour l’impression

  5. @Tchup : non, ta méthode ne peut pas fonctionner parce que le Javascript s’exécute avant l’impression et cache les P, même s’ils sont affichés en "inline".

    Mais j’ai une piste : un bouton "version imprimable" qui affiche l’ensemble des P.

  6. Iridium dit :

    @Damien : Impec !
    (ça venait bien du capharnaum de mes css. Désolé du dérangement)
    Bonne continuation
    Iridium

  7. Tchup dit :

    Et si pourtant !
    Après recherche, je me suis rendu compte que les styles CSS appliqués (display:none) via le JS était prioritaire au style de la feuille CSS de type print.
    L’astuce était donc de ne pas utiliser la propriété style="display:none" avec hide() / show() mais la classe de l’élément.
    Ainsi, avec ce style :
    ————————————
    <style type="text/css">
    @media print {
    p {display:block;}
    }
    @media screen {
    p.invisible {display:none;}
    }
    </style>
    ————————————
    et en remplaçant :
    .hide() et .toggle() par .toggleClass("invisible");
    les p sont visibles à l’impression.

    @+ ;)

  8. @Tchup : vu comme ça, ça peut marcher effectivement. Cependant, si l’on oblige l’éditeur de la FAQ à ajouter des classes sur chaque paragraphe, on perd l’objectif initial qui était de permettre une mise à jour simplifiée de la FAQ par un néophyte.

    @Iridium : heureux d’avoir pu t’aider sans faire grand chose :-)

  9. Tchup dit :

    Comme tu pourras le constater avec mon code suivant, les paragraphes sont initialisés par jQuery (comme ton exemple !)
    Y a juste un bout de CSS supplémentaire.

    ———————————————————
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "link to w3.org.
    <html xmlns="link to w3.org.
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Test FAQ</title>

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta http-equiv="Content-Style-Type" content="text/css" />
    <meta http-equiv="Content-Script-Type" content="text/javascript" />

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

    $(document).ready(function() {

    // On lance la boucle sur tous les H3
    $(‘h3’).each(function() {
    // On masque le paragraphe qui suit
    $(this).next(‘p’).toggleClass("invisible");
    // On copie le style des balises A
    var couleurLien = $(‘a’).css("color");
    $(this).css({"text-decoration" : "underline", "color" : couleurLien, "cursor":"pointer"});
    // A chaque clic, on bascule l’état de l’élément P suivant
    $(this).click(function() {
    $(this).next(‘p’).toggleClass("invisible");
    });
    });

    })
    </script>

    <style type="text/css">
    @media print {
    p {display:block;}
    }
    @media screen {
    p.invisible {display:none;}
    }
    </style>
    </head>

    <body>

    <h1>FAQ de l’administrateur</h1>

    <h2>Section 1 : Connexion</h2>

    <h3>Comment puis-je m’inscrire ?</h3>
    <p>L’inscription est gratuite et ouverte à tout le monde. Cliquez sur le lien "inscription" présent à droite du logo.</p>

    <h3>Je suis inscrit, mais le site ne me reconnaît pas. Comment faire ?</h3>
    <p>Cliquez sur "connexion" puis saisissez l’adresse e-mail ainsi que le mot de passe saisis lors de votre inscription. </p>

    <h2>Section 2 : Publication</h2>

    <h3>Comment publier un article</h3>
    <p>Après vous être connecté, vous pourrez immédiatement proposer un article en cliquant sur "publier un article" dans le menu de gauche. Votre article sera relu par notre comité de rédaction qui décidera de le publier ou non.</p>

    </body>
    </html>
    ———————————————————

    @+

  10. @Tchup : là d’accord. Belle mise en pratique, en effet. Merci à toi.

  11. Tchup dit :

    Tout le plaisir était pour moi. ;)

  12. Erwin dit :

    Bonjour les amis,

    Tout ça ne marchait pas chez moi vu que j’avais plein d’autres morceaux de HTML dans ma page, j’ai donc recodé en mettant toutes les entrées de la faq dans une balise div. A noter que l’id "faq" cause des problèmes dans IE (authentique) ! Donc j’ai mis "faqs".

    [code]<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "link to w3.org.
    <html xmlns="link to w3.org. xml:lang="de" lang="de">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    </head>
    <body><div style="margin: 5px 15px 0px 5px; text-align: justify;" id="faqs">
    <h1 align="center">Questions fréquemment posées (FAQ)</h1>

    <h3>Courage</h3>
    <h4>&#9658; Pourquoi ne faut-il pas avoir peur ?</h4>
    <p>La peur est l’ennemie du Bien.<br /><br />
    Pour que le Bien vous accompagne dans votre vie, donnez sur <a href="http://www.kamashanti.org"&...
    </p>
    <br />

    <h4>&#9658; Comment puis-je obtenir la rédemption ?</h4>
    <p>Donnez sur <a href="http://www.kamashanti.org"&... Remercier le Bien est la source de tout salut.</p>
    <br />

    <h4>&#9658; J’ai déjà donné, mais je n’ai pas l’impression que le Bien est avec moi, que puis-je faire ?</h4>
    <p>Il ne faut pas perdre la foi ! Peut-être votre générosité n’est pas à la hauteur du Bien que vous attendez. <a href="http://www.kamashanti.org"&... votre coeur</a>.</p>
    <br />

    <h4>&#9658; Je ne trouve pas réponse à ma question, que faire ?</h4>
    <p><a href="http://www.kamashanti.org"&... !</a>. Les réponses sont transcendantes lorsque l’on est allégé des fardeaux de la vie.</p>

    </div>
    <br />
    <br />

    <center><a href="#" onClick="faq_toggle_all(‘block’)"><small>Tout afficher</small></a> | <a href="#" onClick="faq_toggle_all(‘none’)"><small>Tout masquer</small></a> </center>

    </body>
    <script type="text/javascript">
    function faq_toggle(pdiv) {
    var action = (pdiv.style.display == "block") ? "none" : "block";
    pdiv.style.display = action;
    }
    function faq_toggle_all(action) {
    var faqs = document.getElementById(‘faqs’);
    var pfaqs = faqs.getElementsByTagName(‘p’);
    for(i=0;i<pfaqs.length;i++) {
    pfaqs[i].style.display=action;
    }
    }

    var faqs = document.getElementById(‘faqs’);
    var pfaqs = faqs.getElementsByTagName(‘p’);
    var hfaqs = faqs.getElementsByTagName(‘h4’);
    for(i=0;i<pfaqs.length;i++) {
    //hfaqs[i].setAttribute("onclick","faq_toggle(pfaqs["+i+"])"); // Does not work in IE.
    hfaqs[i].onclick = function(){
    var faqs = document.getElementById(‘faqs’);
    var pfaqs = faqs.getElementsByTagName(‘p’);
    var hfaqs = faqs.getElementsByTagName(‘h4’);
    for(j=0;j<hfaqs.length;j++) {
    if(hfaqs[j] === this) {
    faq_toggle(pfaqs[j]);
    }
    }
    }
    hfaqs[i].style.fontStyle="italic";
    hfaqs[i].style.cursor="pointer";
    hfaqs[i].style.color="#006699";
    pfaqs[i].style.display="none";
    }
    </script>
    </html>[/code]

    Pensez à remercier le Bien si cela vous a été utile ;-).

  13. streaming dit :

    Merci pour ce tuto mais personnellement j’utilise rarement jQuery. Je vous propose ici un autre exemple mais avec Mootools (qui est d’après moi plus souple d’utilisation) : demos.mootools.net/Accord…

    a++

  14. @streaming : dans l’exemple du site MooTools, l’élément déclencheur doit posséder une classe particulière (<h3 class="toggler">), ce qui rend sa mise à jour plus difficile pour un néophyte.
    Cela dit je ne doute pas que mon tutorial soit déclinable sous Mootools, Prototype, Yahoo UI ou autre librairie Javascript.

  15. pierret dit :

    la démonstration ne fonctionne pas. est-il possible de la remettre en place.

    Merci,
    Pierre

  16. @pierret : bien vu, elle avait été oubliée dans la mise à jour du site.

    C’est corrigé, désolé pour le désagrément.

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *