Affichage de plusieurs vue à l'interieur d'une vue

Par ginettebaldoche, il y a 9 ans


Bonjour,

J'ai une page listes.index qui contient une liste de boutons qui, lorsqu'on clique dessus, dirigent vers une route listes.show
Actuellement tout fonctionne bien lorsque je clique sur un bouton, je suis redirigé vers ma vue show avec l'id de la liste concernée.

Ce que je veux

J'aimerai que lorsque je clique sur un bouton de la page index, la vue show s'affiche sur cette même page index, un peu sur ce principe là :
https://jsfiddle.net/TyrionGraphiste/M338a/1/

Ce que je fais

Ce que j'obtiens

Du coup sur le clic du bouton, je n'arrive pas à afficher la page show à l'interieur de la page index. Je tourne en rond...
Quelqu'un aurait il une idée ?

21 réponses

AlexJM, il y a 9 ans

Bonjour,

Tu veux le faire sans recharger la page comme sûr l'example ?

ginettebaldoche, il y a 9 ans

Bonjour,
Si c'est possible, oui, mais sinon, je voudrais déjà que ça me l'affiche avec les données correspondantes à chaque bouton.

ginettebaldoche, il y a 9 ans

J'ai rajouté à ma page index le code suivant :

<style type="text/css"> .box{ float:left; overflow: hidden; background: #ffffff; display: none; } /* Add padding and border to inner content for better animation effect */ .box-inner{ width: 400px; padding: 10px; border: 1px solid #a29415; } </style> <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script> <script type="text/javascript"> $(document).ready(function(){ $(".slide-toggle").click(function(){ $(".box").animate({ width: "toggle" }); }); }); </script>

Mais le pb c'est que quelque soit le bouton sur lequel je clique, le slideToggle m'affiche toujours le dernier élément de ma table, puis ça m'ouvre la page show (avec le bon élément de ma table)... En plus, quand je clique sur un 2eme bouton, ça me referme le premier au lieu de m'afficher le contenu du 2eme.

betaWeb, il y a 9 ans

Salut,

Tu souhaites charger dynamiquement une vue en fonction de l'item sur lequel tu cliques c'est ça ?

ginettebaldoche, il y a 9 ans

Bonjour,
Oui c'est ça, est-ce possible ?

betaWeb, il y a 9 ans

Oui, il te suffit simplement d'utiliser AJAX :)

ginettebaldoche, il y a 9 ans

Pourrais-tu me donner un exemple stp ?

betaWeb, il y a 9 ans

Tu fais un appel AJAX vers ta route qui doit te renvoyer les infos, qui va te générer le HTML correspondant et te le renvoyer. Tu n'auras plus qu'à insérer au bon endroit et le tour est joué.
Cela dit, c'est pas la meilleure solution. Tu as beaucoup de listes à charger ? Car sinon tu peux précharger les listes dans la page, et les afficher / cacher cia un jeu de JS / CSS. Rien de bien compliqué.

AlexJM, il y a 9 ans

L'ajax est une bonne idée,
Mais sinon tu peux aussi inclure directement la view fille dans la view mère, l'entourer d'un div display none et changer le display en js

betaWeb, il y a 9 ans

@AlexM Oui, cela rejoint ma seconde remarque et c'est une bonne solution également. Le chargement de la page sera un peu plus long, mais toutes les data seront là. A lui de voir maintenant comment il préfère procéder :)

AlexJM, il y a 9 ans

@betaWeb mon mauvais, je n'avais pas vu :o

ginettebaldoche, il y a 9 ans

Bonjour et merci pour vos réponses.
J'ai essayé ce que vous me proposez en faisant ça dans ma vue index :

function listechange() { if (document.getElementById("listeshow").style.display == "block") { document.getElementById("listeshow").style.display = 'none'; document.getElementById("listeshow").style.visibility = 'none'; } else { document.getElementById("listeshow").style.display = 'block'; document.getElementById("listeshow").style.visibility = 'visible'; } }

et

@foreach ($listes as $liste) <tr> <td class="text-primary">{{ $liste->name }}</td> <td><a class="btn btn-outline-warning pull-right", onclick="javascript:listechange()"><span><i class="fa fa-eye", title="Voir"></i></span></a></td> ..... </tr> @endforeach .... </div> <div class="col-md-7"> <div class="control-group" id="listeshow" name="listeshow" style="display:none"> @include('listes.show', [$liste->id]) </div> </div>

ça m'affiche bien le contenu de la page show mais systématiquement avec le dernier élément de ma table et non pas l'élément sur lequel je clique et lorsque je clique sur un autre bouton, ça le masque au lieu d'afficher son contenu. Je ne sais pas si je suis très claire là ?
En gros j'aimerai bien reproduire l'effet de cette page : https://jsfiddle.net/TyrionGraphiste/M338a/1/
sachant que le menu correspond en fait à mes boutons et que ce qui s'affiche quand on clique est le contenu de ma page show avec l'id de chaque "liste".
Pourriez-vous m'aider à corriger mon code ?

AlexJM, il y a 9 ans

Tout d'abord, si display est mis à none, visibility est "automatiquement" mise à hidden, enfin je veux dire que tu ne peux pas afficher un truc qui n'est pas dans le layout

Ce que tu veux c'est genre :
Tu as deux boutons : p1 et p2 (par exemple)
Tu as deux divs
Tu veux que p1 affiche le premier div et masque le deuxième et que p2 fasse l'inverse ?

ginettebaldoche, il y a 9 ans

En fait j'ai un tableau qui récupère les listes depuis la base de données. à l'affichage ça me donne :
liste1 voir(btn avec lien vers le contenu de la liste1)
liste2 voir(btn avec lien vers le contenu de la liste2)
Liste3 voir(btn avec lien vers le contenu de la liste3)
etc.... autant qu'il y a de listes dans la base de données

le bouton "voir" au départ, dirigeait sur ma route listes.show avec $liste->id (et m'amenait donc sur une autre page)
Je veux que le contenu de chaque liste s'affiche dans la même page que "liste1 voir" (c'est à dire la page listes.index) et que lorsque je clique sur le bouton voir de la liste1, ça m'affiche le contenu de la liste1, puis si je clique sur le bouton voir de la liste2, ça m'affiche le contenu de la liste2 etc...
Donc dans la page je crée une div qui récupère ma page listes.show (@include ('listes.show ', [$liste->id]).
Maintenant à l'écran j'ai :
liste1 voir si je clique j'ai le contenu de la liste3
liste2 voir si je clique j'ai le contenu de la liste3
Liste3 voir si je clique j'ai le contenu de la liste3

et ce que je veux c'est :
liste1 voir si je clique j'ai le contenu de la liste1
liste2 voir si je clique j'ai le contenu de la liste2 (et la liste1 se cache)
Liste3 voir si je clique j'ai le contenu de la liste3 (et la liste2 se cache)

Est-ce que tu comprends mieux mon problème à présent ? Je m'arrache les cheveux depuis plusieurs jours sans trouver de solution malgré mes recherches...

AlexJM, il y a 9 ans

Alors déjà du coup tu dois faire aussi un foreach sur les listes ici

<div class="control-group" id="listeshow" name="listeshow" style="display:none"> @include('listes.show', [$liste->id]) </div>

afin d'afficher le contenu de toutes les listes

Ensuite, tu peux ajouter l'id de la liste à l'id du listeshow, et on va aussi lui mettre une petite class "listeshow":

<div class="control-group listeshow" id="listeshow-{{$liste->id}}" name="listeshow" style="display:none"> @include('listes.show', [$liste->id]) </div>

Ensuite sur ton lien (attention pour afficher le style du lien il faut tjs avoir un href dedans sur certains navigateurs), tu peux mettre l'id du div en href et on va aussi virer le onclick qu'on va mettre directement dans le javascript pour avoir accès à l'événement (donc on lui met une classe afin d'y avoir accès):

<a class="btn btn-outline-warning pull-right listeshow-show" href="#listeshow-{{$liste->id}}"><span><i class="fa fa-eye" title="Voir"></i></span></a>

(et comme ça, y'a pas de "," entre les différents attributs)

Finalement, pour le js, tu dois afficher l'élément référencé dans href et masquer celui qui a été affiché :

//On ajoute l'événement click à chacun des liens var links = document.querySelectorAll('.listeshow-show'); for (var i = links.length - 1; i >= 0; i--) { links[i].addEventListener('click', function(e){ e.preventDefault();//Empêche le navigateur d'aller sur le lien, après si tu veux aller directement au contenu de la liste, tu peux virer cette ligne // On choppe l'élément actuellement sélectionné, on le masque et on retire la class var selected = document.querySelector('.listeshow-selected'); selected.style.display = 'none'; selected.classList.remove('listeshow-selected'); // On choppe l'élément rérérencé dans href (e.target récupère le lien sur lequel on a cliqué), on l'affiche et on ajoute la class var newSelected = document.querySelector(e.target.getAttribute('href')) newSelected.style.display = 'block'; newSelected.classList.add('listeshow-selected'); }); }

Bon j'ai pas testé mais ça m'a l'air pas mal, si jamais t'a une erreur n'hésite pas

Note1: si tu veux de la meilleure compatibilité pour le js, je t'invite à mettre un polyfill pour le classList, on en trouve sur le net
Note2: si tu veux faire plus propre, tu peux mettre le display: block dans la class listeshow-selected et mettre le display: none dans la class listeshow

ginettebaldoche, il y a 9 ans

Merci beaucoup Alex pour ta réponse ! Alors j'ai fait les modifs que tu m'as indiqué, je n'ai pas d'erreur, le lien rajoute bien le n° de la liste : http://localhost:8000/listes#listeshow-38 par exemple, mais... rien ne s'affiche à l'écran.
J'ai mis comme tu m'as dit le foreach pour la div :

@foreach ($listes as $liste) <div class="col-md-7"> <div class="control-group listeshow" id="listeshow-{{$liste->id}}" name="listeshow" style="display:none"> @include('listes.show', [$liste->id]) </div> </div> @endforeach

J'ai recopié le script js dans ma page, mais lorsque je clique sur un bouton, le lien se modifie bien mais rien ne s'affiche...
Est-ce que ça viendrait de mon script source ? :

<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
AlexJM, il y a 9 ans

Pas de problèmes,

Tu dois sûrement avoir une erreur sur le script js (je suis pas vraiment doué pour le js natif ^^), mais si tu utilises jquery j'vais te le modifier pour qu'il soit plus facile :

$(function(){ $('.listeshow-show').click(function(e){ e.preventDefault(); var $selected = $('.listeshow-selected'); $selected.hide(); $selected.removeClass('listeshow-selected'); var $newSelected = $(this); $newSelected.show(); $newSelected.addClass('listeshow-selected'); }); });

Normalement ça devrait fonctioner mais si ça ne fonctionne pas tu auras une erreur dans la console

ginettebaldoche, il y a 9 ans

Bonjour Alex, alors maintenant : lorsque je clique sur un premier bouton, il ne se passe rien, puis quand je clique sur un 2eme, le premier bouton s'efface... si je clique à nouveau sur un bouton le précédent sur lequel j'ai cliqué s'efface...

AlexJM, il y a 9 ans

Ah non mais laisse tomber je suis vraiment con x) Faut pas que j'écrive du code à minuit x)

$(function(){ $('.listeshow-show').click(function(e){ e.preventDefault(); var $selected = $('.listeshow-selected'); $selected.hide(); $selected.removeClass('listeshow-selected'); var $newSelected = $($(this).attr('href')); $newSelected.show(); $newSelected.addClass('listeshow-selected'); }); });

Ca devrait être mieux

ginettebaldoche, il y a 9 ans

Whaou ! genial, ça marche ! en fait tu as rajouté $($(this).attr('href')) à la place de $(this). Sans vouloir abuser, pourrais-tu m'expliquer la différence ? avec le .attr('href') tu lui dis d'aller à "l'attribut lien" qui se trouve dans le bouton c'est ça ?
En tout cas merci mille fois Alex pour le temps passé à m'aider.
Bonne soirée

AlexJM, il y a 9 ans

Pas de prob :)

En faite this représente l'élément sur lequel s'applique l'évémenent donc $(this) l'élement jquery sur lequel s'applique l'événement, donc on prends le lien avec .attr('href'), celui-ci représentant l'id $($(this).attr('href')) représente l'élement représenté dans l'attribut href ;)

Pense à mettre les messages contenant la solution à ton problème en résolu aussi, afin que les gens qui passent voir le poste ne doivent pas chercher les réponses ;)