IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

limiter les réponses pour un QCM


Sujet :

JavaScript

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 5
    Points : 2
    Points
    2
    Par défaut limiter les réponses pour un QCM
    Bonjour à tous !

    Plus que débutant, je travail via le logiciel eXelearning à l'élaboration de cours QCM et autre moyen pédagogique pour un centre de formation. Le logiciel génère du code html et javascript.
    Je souhaiterais vérouiller le nombre de réponse possible lors des tests de controle.
    Je m'explique, lors d'un QCM par exemple on peut cocher les case à plusieur reprise jusqu'à obtenir la bonne réponse. Peut grace à java, n'autoriser qu'une seule action ?

    Merci de vos avis et reponses.

  2. #2
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Je mets -1 pour le titre de topic qui sert à rien, et parce que c'est JavaScript, pas Java.

    Pour ton problème, comment souvent, il y a plusieurs façons de faire. Une est simple mais fastidieuse, car il faut rajouter un attribut dans le code HTML de chaque bouton radio. Une autre, reposant sur la délégation d'évènements, serait plus élégante mais plus complexe. Je te propose la première.

    Je commence par créer une fonction qui va désactiver tous les boutons de même nom :
    Code JS : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    function desactiver( nom ) {
       var boutons = document.getElementsByName(nom);
       var length = boutons.length;
       for (var i = 0; i < length; i++) {
          boutons[i].disabled = true;
       }
    }

    Ensuite, il faudra rajouter un appel à cette fonction sur chaque bouton radio :
    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    <input type="radio" ... onclick="desactiver(this.name);" />

    Si tu te sens d'attaque pour la solution « plus élégante », y'a qu'à demander

    Autre chose : je sais, de ma propre expérience, que le e-learning se soucie parfois peu de la sécurité des questionnaires. Mais il faut que tu saches qu'une vérification côté client n'est pas suffisante. Par exemple, avec une console JavaScript (il y en a dans tous les navigateurs actuels), il suffit de taper un tout petit bout de code pour casser la protection que je viens de te donner.

    L'idéal serait de faire une requête auprès du serveur (avec ou sans Ajax) quand l'utilisateur propose une réponse, et de s'assurer, côté serveur, qu'il ne pourra pas proposer une autre réponse par la suite.

    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 5
    Points : 2
    Points
    2
    Par défaut
    Merci beaucoup de ces precieuses informations.

    Je suis partant pour la solution "elegante"
    manière de tester tout ça.

    Merci aussi pour l'astuce de securité. Je n'y avait effectivement pas pensé.

  4. #4
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Pour la seconde solution,
    l'idée c'est d'utiliser un gestionnaire d'évènement addEventListener, en surveillant non pas chaque input, mais le formulaire qui les contient tous. C'est ça qu'on appelle la délégation.
    Pour que ça marche, il faut qu'il y ait dans le code HTML au moins le <form> et les <input>, mais je te mets des balises en bonus pour améliorer la sémantique et l'accessibilité.
    Code HTML : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    <form method="post" action="" id="questionnaire">
    	...
    	<fieldset>
    		<legend>Question 2</legend>
    		<input type="radio" name="q2" id="q2A" />
    		<label for="q2A">réponse A</label>
    		<input type="radio" name="q2" id="q2B" />
    		<label for="q2B">réponse B</label>
    		<input type="radio" name="q2" id="q2C" />
    		<label for="q2C">réponse C</label>
    		<input type="radio" name="q2" id="q2D" />
    		<label for="q2D">réponse D</label>
    	</fieldset>
    	<fieldset>
    		<legend>Question 3</legend>
    		<input type="radio" name="q3" id="q3A" />
    		<label for="q3A">réponse A</label>
    		<input type="radio" name="q3" id="q3B" />
    		<label for="q3B">réponse B</label>
    		<input type="radio" name="q3" id="q3C" />
    		<label for="q3C">réponse C</label>
    		<input type="radio" name="q3" id="q3D" />
    		<label for="q3D">réponse D</label>
    	</fieldset>
    	...
    </form>

    La fonction en elle-même est très courte, et tu reconnaîtras une partie commune avec la première solution :
    Code JS : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function gererClic( e ) {
       var target = e.target || e.srcElement;
       if ('INPUT' == target.tagName && 'radio' == target.type) {
          var nom = target.name;
          var boutons = document.getElementsByName(nom);
          var length = boutons.length;
          for (var i = 0; i < length; i++) {
             boutons[i].disabled = true;
          }
       }
    }
    La ligne 2 permet de récupérer la cible réelle du clic. D'habitude on utilise this, mais comme le gestionnaire sera attaché au formulaire, this correspond au formulaire et ce n'est pas ce qu'on veut. e.target fonctionne avec les navigateurs qui respectent le standard, et e.srcElement marche sous IE<9.

    De même, il faut prendre en compte IE<9 au moment d'attacher le gestionnaire :
    Code JS : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if (window.addEventListener) { // standard
       document.getElementById('questionnaire').addEventListener('click', gererClic, false);
    } else { // IE<9
       document.getElementById('questionnaire').attachEvent('onclick', gererClic);
    }

    Note le 3e paramètre false de la méthode standard, qui ne sert (presque) à rien mais qui est obligatoire

    Le gros avantage de cette méthode, c'est que le script n'est plus intrusif : il n'apparaît plus du tout dans le code HTML, ce qui rend la maintenance plus facile. C'est le même principe que déclarer les styles dans une feuille CSS externe.
    Pour faire les choses bien jusqu'au bout, on déclare les scripts dans le <head>. Mais ça pose un problème : au moment où les scripts sont exécutés, le contenu de la page n'existe pas encore… Pour pallier ce problème, on retarde l'exécution des scripts, en les plaçant dans un gestionnaire de l'évènement load de la page.

    Voilà ce que ça donne au final, si on place le code dans le <head> :
    Code JS : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    function gererClic( e ) {
       ... // cf. au-dessus
    }
     
    if (window.addEventListener) { // standard
       window.addEventListener('load', function() {
          document.getElementById('questionnaire').addEventListener('click', gererClic, false);
       }, false);
    } else { // IE<9
       window.attachEvent('onload', function() {
          document.getElementById('questionnaire').attachEvent('onclick', gererClic);
       });
    }
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  5. #5
    Expert confirmé
    Avatar de RomainVALERI
    Homme Profil pro
    POOête
    Inscrit en
    Avril 2008
    Messages
    2 652
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : POOête

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 652
    Points : 4 164
    Points
    4 164
    Par défaut
    Citation Envoyé par Watilin
    <solution élégante>
    Un tutoriel complet à la demande... techniquement exact, bien écrit, avec code à l'appui...

    >>> Watilin for President !

    ...pour les linguistes et les curieux >>> générateur de phrases aléatoires

    __________________

  6. #6
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 959
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    Très belle explication +1
    il me semble qu'il manque e = e || event;en début de fonction gererClic au cas ou l'event ne soit pas passé à la fonction.

  7. #7
    Expert éminent
    Avatar de Watilin
    Homme Profil pro
    En recherche d'emploi
    Inscrit en
    Juin 2010
    Messages
    3 093
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : En recherche d'emploi

    Informations forums :
    Inscription : Juin 2010
    Messages : 3 093
    Points : 6 754
    Points
    6 754
    Par défaut
    Arrêtez je vais prendre la grosse tête '^^
    Citation Envoyé par NoSmoking Voir le message
    il me semble qu'il manque e = e || event;en début de fonction gererClic au cas ou l'event ne soit pas passé à la fonction.
    De mémoire, le seul cas où l'event n'est pas passé, c'est sous IE quand on utilise les propriétés « DOM 0 » on..., par exemple window.onload. En tout cas, avec attachEvent ça ne pose pas de problème.
    La FAQ JavaScript – Les cours JavaScript
    Touche F12 = la console → l’outil indispensable pour développer en JavaScript !

  8. #8
    Modérateur

    Avatar de NoSmoking
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    16 959
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Janvier 2011
    Messages : 16 959
    Points : 44 122
    Points
    44 122
    Par défaut
    Citation Envoyé par Watilin Voir le message
    De mémoire, le seul cas où l'event n'est pas passé, c'est sous IE quand on utilise les propriétés « DOM 0 » on..., par exemple window.onload. En tout cas, avec attachEvent ça ne pose pas de problème.
    c'est tout à fait vrai, c'est simplement que dans le cas d'une réutilisation de ta fonction en l'affectant, justement, directement sur le onclick d'un objet cela plantera.

    Ceci devient de plus en plus fréquent lorsque l'on met l'initialisation en fin de page, pour être sur que les éléments sont présent dans le DOM et éviter les attachEvent et addEventListener, c'est pour cela que j'ai tendance à le mettre systématiquement.

    Citation Envoyé par Watilin Voir le message
    Arrêtez je vais prendre la grosse tête '^^
    mais non, cela vaut quand même bien une

Discussions similaires

  1. Réponses: 9
    Dernier message: 04/01/2012, 09h54
  2. Limiter les réponses en fonction d'un besoin
    Par gsbreizh dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 29/06/2010, 11h10
  3. [MySQL] Récupérer les réponses d'un QCM
    Par ptitepo dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 23/03/2009, 17h40
  4. Conseils pour l'écriture de questions/réponses pour les FAQ
    Par LittleWhite dans le forum Contribuez
    Réponses: 0
    Dernier message: 18/05/2006, 19h15
  5. Composant pour limiter les décimales à deux
    Par Droïde Système7 dans le forum Composants VCL
    Réponses: 9
    Dernier message: 20/08/2005, 12h00

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo