Bonjour,
J'ai utilisé navbar de bootstrap, mais j'ai rencontré un problème au niveau de l'affectation de la classe active aux link cakephp

 <ul class="nav">
              <li  id="page1" class="active"><?php echo $this->Html->link('Accueil',array('controller' => 'posts','action'=>'index'));  ?></li>
              <li id="page2"> <?php echo $this->Html->link('Produits',array('controller' => 'objets','action'=>'index'));  ?></li>
              <li><a href="#mymodal" data-toggle="modal">Services</a></li>
              <li class="dropdown">

le code javascript

$('.nav > li').on('click', function(e) {
    $('.nav > li').removeClass('active');
    $(this).addClass('active');
});

lorsque je clike sur le lien services ça marche mais lorsque je clique sur le lien Produits il me redirige vers la paga adequate mais le changement de la classe actve ne se fait pas.
j'espére que j'ai bien expliqué le problème.

13 réponses


Bonjour.
C'est tout à fait normal.
Si toute la page est rechargée, le Html reprend son état d'origine, donc si à l'état d'origine de ton lien Produit n'a pas la classe active, il ne l'aura pas au rechargement de la page.
Pour que la classe reste effective, il faudrait que tu ne charge que la vue (fichier de vue) et non le layout si tes liens y sont intégrés.

Oui c'est vrai Mr Lartak, J'ai essayé de ne pas utiliser le helper Html pour pouvoir eviter le chargement de layout, pour cela ,j'ai modifié mon code

  <li id="page2"><a href="http://localhost/cakephpboot/objets">Produits</a></li>

en integrant un simple lien au lieu de Helper cakephp, mais ça persiste toujours.

J'ai essayé de ne pas utiliser le helper Html

Je n'ai pas parlé du Helper Html et je ne vois pas en quoi il en serait la cause, vu que quand le javascript est chargé, ta page est du HTML et non en PHP.
Ce n'est pas parce que tu utilises le Helper ou non que ça changera quelque chose pour le javascript.
Quand je parlais des fichiers de vue et de layout, c'était juste pour différencier les portions de la page.

A bon donc, je dois joier sur le routing pour lier le lien avec la page?

je dois joier sur le routing pour lier le lien avec la page?

Je ne vois pas le rapport si l'url généré par le Helper est correcte.
Ton problème concerne la classe active, le javascript et le chargement de page que je sache et non un problème d'url dans le lien.

Bonjour,

Tu peux faire comme suit avec une boucle, ou pleins de if sur chaque lien, ou encore passer par un helper (à toi de le créer).
Voici la méthode avec une boucle.

Dans ton AppController dans la methode beforeRender() :

<?php 

$links = array(
  'Accueil' => array(
    'controller' => 'posts',
    'action'     => 'index'
  ),
  'Produits' => array(
    'controller' => 'objets',
    'action'     => 'index'
  )
);

$this->set(compact('links'));

?>

Et dans ta vue (layout, header, ou ce que tu veux) :

<?php foreach ($links as $title => $url): $class = '' ?>

  <?php if($this->request->params['controller'] == $url['controller'] && $this->request->params['action'] == $url['action']) $class = ' class="active"'; ?>

  <li id="page-<?= strtolower($title) ?>" <?= $class ?> >
    <?= $this->Html->link($title, $url) ?>
  </li>

<?php endforeach ?>

Tu peux eviter la boucle, mais ça peut vite devenir lourd si tu as plus de liens.

Bon courage.

PS : Je n'ai pas pu tester, tu auras certainement des adaptations à faire.

@ connected : Ce n'est pas ça qu'il veut, il veut le faire en Javascript en faisant du rechargement de page sans impacter la classe active qui aura été ajouté via le javascript, mais il ne comprend pas qu'au rechargement de la page l'effet du Javascript se perde et que les liens reviennent comme avant et il croyait que ça venait du Helper Html.
Il ne semble pas comprendre que le Javascript ne voit que le code Html généré après le chargement de la page, il pense qu'une fois que le chargement de la page est effectué qu'il y a toujours le PHP au navigateur.
Sinon, je lui aurais proposé quelque chose du même genre que toi mais plus léger, du genre :

<li id="page1"<?= ($this->request->params['controller'] == 'posts' && $this->request->params['action'] == 'index') ? ' class="active"' : '' ?>
    <?php echo $this->Html->link('Accueil', ['controller' => 'posts', 'action' => 'index']);  ?>
</li>

@Lartak, ne t'inquiète pas j'ai bien compris ce qu'il souhaitait faire. On se doit de donner des solutions adéquates, je ne vais pas lui proposer du javascript pour convertir son site en "single page", ca demanderait beaucoup plus d'investissement.
Je termine, perso je garderais la solution avec la boucle car c'est plus simple à maintenir s'il veut rajouter des liens et elle a moins de répétition de code.

Merci à vous,
Mais je n'ai pas bien compris ce que vous m'avez expliqué, en effet, ce que je voulais exacteemnt c'est de pouvoir charger la page et non le layout comme Mr Lartak m'a proposé,

Mais je n'ai pas bien compris ce que vous m'avez expliqué

Les deux codes que nous avons montré, permettent de modifier l'état d'un lien en ajoutant la classe active sur celui-ci, si le controlleur et l'action correspondent à l'emplacement que consulte l'utilisateur, pour faire simple, correspondant à la vue courante pour l'utilisateur.
Par contre, c'est en utilisant le système habituel sans navigation avec Javascript et donc avec rechargement de page.

Par rapport à ce que tu veux, si tu souhaites uniquement le chargement des pages via Javascript et donc sans rechargement des pages entières, je ne sais pas dans quel cas tu comptes utiliser ce système, mais interroges toi sur sa réelle utilité, notamment concernant le SEO.
Si ce ne sont pas des pages publiques ce ne sera pas un réel problème pour le référencement, mais dans le cas contraire ...

Ensuite, si tu considères que le système via la navigation en Javascript ne posera pas de problème, il faudra que tu nous donne un peu plus de précisions pour que nous puissions t'aiguiller efficacement.

Merci encore
j'ai voulu tester

<li id="page1" class=<?pho ($this->request->params['controller'] == 'posts' && $this->request->params['action'] == 'index') ? ' class="active"' : '' ?>
    <?php echo $this->Html->link('Accueil', ['controller' => 'posts', 'action' => 'index']);  ?>
</li>

mais j'ai remarqué l'ebsence de la fermeture de la balise <li

Bonjour,

J'ai essayé le code suivant

 <li class="<?php echo (($this->params['controller']==='posts')&& ($this->params['action']=='index') )?'active' :'' ?>" >
   <?php echo $this->Html->link('Produits', array('controller' => 'posts', 'action' => 'index')); ?>
</li>

<li class="<?php echo (($this->params['controller']==='objets')&& ($this->params['action']=='view') )?'active' :'' ?>" >
   <?php echo $this->Html->link('Objets', array('controller' => 'objets', 'action' => 'index')); ?>
</li>

mais il y'a encore un problème par ce que j'ai deux actions ont le meme nom malgrés qu'elles se trouvent sous deux controlleur différent.
Lorsque je clikue sur lien produits ça marche mais lorsque je clique sur le lien Objets la classe active disparait de tous mes liens.

Merci j'ai detecté mon erreur

 <li class="<?php echo (($this->params['controller']==='posts')&& ($this->params['action']=='index') )?'active' :'' ?>" >
   <?php echo $this->Html->link('Produits', array('controller' => 'posts', 'action' => 'index')); ?>
</li>

<li class="<?php echo (($this->params['controller']==='objets')&& ($this->params['action']=='index') )?'active' :'' ?>" >
   <?php echo $this->Html->link('Objets', array('controller' => 'objets', 'action' => 'index')); ?>
</li>

et maintenant le lien cliqué prend la classe active apres l'avoir supprimer d'autres liens,
mais comment puis je donner la classe active initialement au lien Produits?