11485 sujets

JavaScript, DOM et API Web HTML5

Bonjour à tous !
Je suis un jeune codeur qui a beaucoup de difficultés sur une réalisation de projet et qui, je l'espère, vous pourrez m'accorder quelques précieuses minutes de votre temps pour m'aider à avancer, puisque je tourne en rond depuis plus d'une semaine. =)

Pour vous expliquer rapidement mon problème : je dispose d'un formulaire de contact assez spécial dont à l'intérieur, j'ai un menu comme :

CODE HTML :

<a href="#" class="highlight" onclick="toggle('test1','variable1');">IMAGE CONTENU 1</a>
<a href="#" class="highlight" onclick="toggle('test2','variable2');">IMAGE CONTENU 2</a>
<a href="#" class="highlight" onclick="toggle('test3','variable3');">IMAGE CONTENU 3</a>

<div id="test1" style="display: none" class="variable1">BLABLABLA 1</div>
<div id="test2" style="display: none" class="variable1">BLABLABLA 2</div>
<div id="test3" style="display: none" class="variable1">BLABLABLA 3</div>

CODE CSS HIGHLIGHT :

a.highlight{background-color: #008166; border: 2px solid #000;  width: 282px;  border-radius: 7px;  opacity: 0.4;  height: 140px !important; display: inline-block; margin-left: 10px;}
a.highlight:active{background-color: green; border: 2px solid black;opacity:1;}
a.highlight:hover{background-color: green; border: 2px solid black;opacity:0.6;}
a.highlight:focus{background-color: green; border: 2px solid black;opacity:1;}
a.highlight:active{background-color: green; border: 2px solid black;opacity:1;}

CODE JS : Toggle :

<script type="text/javascript">
function toggle(target,cible){
   var test = cible;
  var artz = document.getElementsByClassName(test);
  var targ = document.getElementById(target);  
  var isVis = targ.style.display=='block';
    
  // hide all
  for(var i=0;i<artz.length;i++){
     artz(i).style.display = 'none'; // le i est sous forme [ ]
  }
  // toggle current
  targ.style.display = isVis?'none':'block';
    
  return false;
}
</script>


Soit un résultat comme ci-dessous :
http://img15.hostingpics.net/pics/184359boutonimages.png

Et affiche mon contenu lorsque cliqué sur l'image en question, jusque-là, tout va bien. Où presque !

Le contenu s'affiche correctement mais j'aimerai savoir s'il était possible de trouver un moyen pour récupérer une éventuelle valeur si mon onclick="toggle('test1','variable1');" = true (où même si mon <div id="test1" style="display: none" class="variable1">BLABLABLA 1</div> passe à l'état de DISPLAY: BLOCK) de manière dynamique pour savoir où l'utilisateur a cliqué lorsqu'il submit son formulaire de contact.

De plus, en sachant que l'utilisateur a cliqué sur l’élément 1, 2 où 3 : ça me permettrait de laisser le bouton allumé (le focus| active se désactivent immédiatement lorsqu'on clique en dehors du menu...)

J'ai exploré plusieurs solutions comme passer avec du Jquery TAB (élément que j'n'arrive pas à mettre en place), où passer avec plusieurs fichiers (ça va me demander de créer 33 fichiers au lieu de 11, ce qui ne me semble pas optimal en plus de devoir recharger la page à chaque fois...)

Je suis preneur de toute solution, et n'hésitez pas à demander un complément d'information si je n'ai pas été assez complet dans ma démarche !

En vous remerciant de l'attention à mon sujet Smiley smile
Modifié par Yunalesca (05 May 2015 - 18:07)
Modérateur
Salut !

Yes, ça devrait pas être trop compliqué (si j'ai bien compris).

Yunalesca a écrit :
Le contenu s'affiche correctement mais j'aimerai savoir s'il était possible de trouver un moyen pour récupérer une éventuelle valeur si mon onclick="toggle('test1','variable1');" = true (où même si mon &lt;div id="test1" style="display: none" class="variable1"&gt;BLABLABLA 1&lt;/div&gt; passe à l'état de DISPLAY: BLOCK) de manière dynamique pour savoir où l'utilisateur a cliqué lorsqu'il submit son formulaire de contact.

Qu'entends-tu ici par "récupérer" ? Tu veux récupérer en variable Js ? dans une variable du formulaire ? Là, une fois la fonction toggle déclenchée, ta variable target te dit déjà si c'est test1 2 ou 3 qui a été cliqué...

Yunalesca a écrit :
De plus, en sachant que l'utilisateur a cliqué sur l’élément 1, 2 où 3 : ça me permettrait de laisser le bouton allumé (le focus| active se désactivent immédiatement lorsqu'on clique en dehors du menu...)

Yep, il faudrait juste que tu ajoute une classe "active" quand l'élément est cliqué et que tu supprime cette classe sur ceux qui l'on, exactement de la même façon que tu gère le display block/none (je te conseille de jeter un œil à classlist).


Pas trop le temps de m'y coller plus de suite pour te faire un exemple, mais je repasse ce midi et dans l'aprem au cas ou !

Bon code Smiley murf


PS : Et en bonus une fois que t'as tout réglé, sort les onclick de ton html pour les mettre dans le Js avec un Listener de cette facon : http://www.w3schools.com/jsref/met_element_addeventlistener.asp
Bonjour, merci beaucoup pour ta rapide réponse ?

a écrit :
Qu'entends-tu ici par "récupérer" ? Tu veux récupérer en variable Js ? dans une variable du formulaire ? Là, une fois la fonction toggle déclenchée, ta variable target te dit déjà si c'est test1 2 ou 3 qui a été cliqué

Par récupérer, j'entend plutôt par une variable du formulaire. En effet, quand je soumet mon formulaire de contact : j'aimerai simplement "transmettre" où "savoir" l'onglet ACTIF lors de l'envoi du formulaire (si c'est test1, test2, où test3. Par mon fichier envoi.php, je dois l'afficher ainsi Smiley smile

Donc si je fais simplement <input value="<?php $target ?>" class="toto" id="toto" type="text" name="toto" readonly /></input> j'aurai ma valeur $target selon ma fonction JS ? ça m'étonne un petit peu Smiley lol

a écrit :
Yep, il faudrait juste que tu ajoute une classe "active" quand l'élément est cliqué et que tu supprime cette classe sur ceux qui l'on, exactement de la même façon que tu gère le display block/none (je te conseille de jeter un œil à classlist).

Je n'ai pas spécialement compris cette partie ^^ Je dois ajouter deux classes à mon :

<div id="test1" style="display: none" class="variable1">BLABLABLA 1</div>

Comme class="variable1 active" ? ça ne posera pas de problème avec ma fonction Javascript qui ouvre le contenu seulement en vérifiant variable1 ?

J'ai essayé ces pistes mais ... je dois vraiment être une quiche en codage pour ne pas y arriver avec ces explications claires du classList Smiley decu

Quoi qu'il en soit, merci encore du temps accordé !

(PS : Pour le bonus, je regarderai quand ça fonctionne effectivement Smiley lol )
Modérateur
Yunalesca a écrit :
Par récupérer, j'entend plutôt par une variable du formulaire. En effet, quand je soumet mon formulaire de contact : j'aimerai simplement "transmettre" où "savoir" l'onglet ACTIF lors de l'envoi du formulaire (si c'est test1, test2, où test3. Par mon fichier envoi.php, je dois l'afficher ainsi Smiley smile

Ah ok du coup il te la faut dans le formulaire. A chaud comme ça je vois 2 option :
- Avoir un input caché que tu mets à jour en Js au click sur un "onglet"
- Utiliser les radios boutons, en masquant l'aspect du radio bouton et en mettant une image en label pour garder son comportement.


Yunalesca a écrit :
Je n'ai pas spécialement compris cette partie ^^ Je dois ajouter deux classes à mon
Comme class="variable1 active" ? ça ne posera pas de problème avec ma fonction Javascript qui ouvre le contenu seulement en vérifiant variable1 ?

Je vais tenter d'être un peu plus clair. En gros tu as 3 "menus" toujours visible, dont 1 qui a un aspect actif. Avec ça tu as 3 contenu qui ne s'affiche qu'un à la fois, en fonction du menu sélectionné. C'est le fonctionnement classique d'un "tab" comme tu l'a cité plus haut.
Donc niveau html un truc qui ressemble à ça:
<div id="menu1" class="menu menu-actif"></div>
<div id="menu2" class="menu"></div>
<div id="menu3" class="menu"></div>

<div id="menu1-contenu" class="contenu contenu-actif"></div>
<div id="menu2-contenu" class="contenu"></div>
<div id="menu3-contenu" class="contenu"></div>

Note que l'id du contenu contiens l'id du menu. c'est une petite ruse pour se faciliter la suite.

Ensuite niveau Js le fonctionnement serait : Quand on clique sur un menu on vire la classe active des menu, on la met sur le menu cliqué, on vire la classe active des contenu, on affiche le contenu relatif au menu cliqué. (Et en ++ on set une valeur au input mais bon on fera ca après).
En gros ça donne :
// on récupère tous les menus et tous les contenus
var menus = document.getElementsByClassName('menu');
var contenus = document.getElementsByClassName('contenu');

// on parcours tous les menus
for(var i=0; i<menus.length; i++){
    // on attache un listner à tous les menus, au click ca run cette fonction (qu'on peut extraire hein)
    menus[ i ].addEventListener("click", function(){
        
        //on parcours tous les menus pour enlever la classe active
        for(var j=0; j<menus.length; j++){
            menus[j].classList.remove('menu-actif');
        }
        //on remet la classe active sur le menu cliqué
        this.classList.add('menu-actif');
        
        //on parcours tous les contenus pour enlever la classe active
        for(var k=0; k<contenus.length; k++){
            contenus[k].classList.remove('contenu-actif');
        }
        //on remet la classe active sur le contenu lié au menu cliqué
        document.getElementById(this.id + '-contenu').classList.add('contenu-actif'); // c'est ici qu'on ruce avec l'id du menu qui est intégré dans l'id du contenu
        
    });
}

Du coup totu est bien à sa place et tu gère tout l'aspect dans le css.
On rajoute un peu de CSS donc et voila c'est tout beau.
Le même code en ligne : http://jsfiddle.net/Undless/dhhqze12/

Il reste maintenant a rajouter un input hidden juste en dessous avec une value par défaut. Quand tu passe dans la fonction Js il te suffit de mettre à jour cette value avec l'id du menu (this.id). Comme ça ton formulaire php enverra aussi cette variable.

Il faut aussi peaufiner l'initialisation du form, le fait que si tu as déja une valeur de cet id en php il faut afficher le bon menu. ça donnera dans le php un truc du genre (j'ai pas testé ça) :
<div id="menu1" class="menu <? if($menuSelected == 'menu1'){ echo 'menu-actif'; } ?>"></div>
<div id="menu2" class="menu <? if($menuSelected == 'menu2'){ echo 'menu-actif'; } ?>"></div>
<div id="menu3" class="menu <? if($menuSelected == 'menu3'){ echo 'menu-actif'; } ?>"></div>

<div id="menu1-contenu" class="contenu <? if($menuSelected == 'menu1'){ echo 'contenu-actif'; } ?>"></div>
<div id="menu2-contenu" class="contenu <? if($menuSelected == 'menu2'){ echo 'contenu-actif'; } ?>"></div>
<div id="menu3-contenu" class="contenu <? if($menuSelected == 'menu3'){ echo 'contenu-actif'; } ?>"></div>


Yunalesca a écrit :
J'ai essayé ces pistes mais ... je dois vraiment être une quiche en codage pour ne pas y arriver avec ces explications claires du classList Smiley decu

Mais non, mais non. Faut le faire une fois, la deuxiemme coulera plus facilement et après tu feras ca d'une main sans regarder Smiley cligne

C'est certainement pas la seule, ni la meilleure façon de faire. Mais j’espère que ça répondra au moins à ton besoin. Smiley murf
Modifié par _laurent (06 May 2015 - 12:47)
Oh ! Je vois beaucoup mieux le fonctionnement (même si, j'aurai été incapable de reproduire ce code javascript, c'est un élément tout nouveau pour moi) et effectivement, ça fonctionne beaucoup mieux, en plus de simplifier le code et c'est exactement ce que je voulais !

Me reste plus que le input avec la récupération de l'id avec le this.id comme préconisé et comme j'ai pu entrevoir sur la toile mais je ne vois pas comment le mettre en oeuvre :

<input value="????" class="test" id="test" type="text" name="test" onchange="(this.value)" readonly /></input> //pour des tests avant de le cacher

Mais quel est l'id ? menu-actif ? $menuSelected ?

Donc normalement dans ma page, la value de mon input se modifie automatiquement selon le menu selected si je comprend bien ? (enfin, pour le moment, ça ne m'affiche rien ^_^)
Modérateur
Alors, un input caché aura le même fonctionnement qu'un input classique sauf qu'il n'a pas un type="text" ou "number" mais un type="hidden". Il sera donc invisible. Par contre il garde le meme fonctionnement et sera envoyé comme toute les autres variables avec ton formulaire. Donc on a un champs comme ça :
<input id="inputMenuSelected" type="hidden" name="menuSelected" value="menu1"> 

hop la doc qui va bien : http://www.w3schools.com/tags/att_input_type.asp

Pour le nom "menuSelected" j'ai pris ce nom au pif hein appelle ça comme tu veut. L'idée c'est que c'est le nom de la variable PHP qui contient le nom du menu sélectionné. Idem pour l'id "inputMenuSelected".

Du coup si on reprends la même fonction Js, au moment ou tu met a jour ton affichage tu rajoute juste une ligne pour mettre a jour l'input avec l'id du menu (pour faire simple, on aurait pu donner un autre nom de variable et tout mais pourquoi faire compliqué...) :
var menus = document.getElementsByClassName('menu');
var contenus = document.getElementsByClassName('contenu');
for(var i=0; i<menus.length; i++){
    menus[ i ].addEventListener("click", function(){
        for(var j=0; j<menus.length; j++){
            menus[j].classList.remove('menu-actif');
        }
        this.classList.add('menu-actif');
        for(var k=0; k<contenus.length; k++){
            contenus[k].classList.remove('contenu-actif');
        }
        document.getElementById(this.id + '-contenu').classList.add('contenu-actif');

        // Hop ici on rajoute une action
        // On selectionne l'input grace a son id et on lui colle l'id du menu cliqué
        document.getElementById('inputMenuSelected').value = this.id;
        // Et... et bah c'est tout.
        
    });
}

Maintenant quand tu clique sur un menu ça change aussi la valeur de l'input caché. Quand ton formulaire est envoyé tu récupère la variable php $menuSelected comme n'importe quel autre champs et dedans tu as l'id du menu qui était sélectionné (à savoir menu1, menu2 ou menu3...). Smiley smile

PS : Au passage, Yunalesca c'est bien une ref à FFX ?! #souvenirDeJeunesse Smiley biggrin
Modifié par _laurent (06 May 2015 - 15:41)
Modérateur
Pour tester tu peux mettre exactement le même input mai en type="text" (au lieu de hidden) ça aura exactement le même comportement mais tu pourras voir le contenu changer. Smiley smile
Ho, ça fonctionne parfaitement, c'est la ligne qui me manquait à la fonction JS =)
document.getElementById('inputMenuSelected').value = this.id;)

Je comprend mieux maintenant le fonctionnement de this.id et getElementsByClassName, je pensais qu'il était obligatoirement nécessaire de faire un appel à une fonction mais le GetElement est vraiment intéressant et ça me donne quelques idées pour développer quelques outils à l'avenir =D

J'ai commencé à adapter, et cette solution est vraiment parfaite pour la conception de ma fonctionnalité : un énorme merci [sujet en résolu]

PS : Oui Yünalescä est une vieille référence à Final Fantasy X étant mon jeu favori pour son histoire totalement épique ^_^
Modérateur
Bah parfait alors Smiley smile

Yunalesca a écrit :
Je comprend mieux maintenant le fonctionnement de this.id et getElementsByClassName


C'est le fonctionnement du this hein, le .id c'est juste qu'il a un argument id (tout comme on peut faire this.style ou this.value si c'est un champ etc). C'est le this qui fait référence à l'objet sujet d'une fonction a un moment donné dans un état donné... bref c'est à la fois super pratique mais assez complexe à maitriser... j'me viande souvent avec.

Et pour le getElementsByClassName il est pratique mais à utiliser quand getElementsById ne suffit plus car il est un peu plus gourmand. Smiley smile

Bonne continuation ! Smiley smile
Merci pour ces explications Smiley smile
Je bidouillerai quand mon système sera mis en place car des éléments de code servent toujours à adapter sur d'autres situations plus où moins similaires ! Smiley smile Et puis, ça me permettra de mieux maîtriser ces fonctions, parfois on pense avoir compris, mais en pratique... Smiley lol

Merci, bonne continuation également ! Enfin je reste quand même sur Alsacreation pour les cours et même le forum si j'ai besoin (où pour ceux qu'on besoin mais au vu de mes connaissances... Smiley langue )

Seeya'