dimanche 12 octobre 2014

DNN + Bootstrap + DDRMenu : Comment garder ouvert un sous-menu

Voici une petite astuce à utiliser dans un cas très précis. Je travaille actuellement sur un skin DNN, basé sur Bootstrap. Arrive le moment tant redouté de l'intégration du menu DNN (DDRMenu) dans le skin et je rencontre là un problème pour la gestion du menu "Rechercher".

En effet, dans DNN lors de la sélection du menu rechercher, un panel s'ouvre permettant de saisir le texte rechercher. Pour intégrer ce genre de fonctionnalité avec Bootstrap, l'utilisation d'un menu dropdown s'impose. Malheureusement lors de la sélection d'un sous-item la dropdown est automatiquement fermé. Mais dans mon cas cela pose soucis, puisque dès que ma zone de texte de mon contrôle de recherche prend le focus, la dropdown se referme.

A tout problème une solution... Voici tout d'abord la définition de mon menu rechercher "à la Bootstrap" :

<ul class="nav navbar-nav searchMenu">
     <li class="dropdown">
          <a href="#" class="dropdown-toggle" data-toggle="dropdown">Search<b class="caret"></b></a>
               <ul class="dropdown-menu">
                    <li>
                         <div class="searchBox">
                              <dnn:Search id="dnnSearch1" runat="server" showsite="false" showweb="false" cssclass="btn btn-success btn-xs" />
                         </div>
                    </li>
               </ul>
          </li>
     </ul>
Cette définition permet d'avoir une dropdown "Search" qui a pour contenu, lorsqu'on la déplie, le contrôle de recherche DNN constitué d'une zone de texte et d'un bouton "Rechercher". Si l'utilisateur clique dans la zone de texte, la dropdown est automatiquement fermé.

Pour éviter cela, il s'agit dans un premier temps de supprimer l'attribut "data-toggle='dropdown'" définie sur l'élément "A" de la dropdown. En supprimant cet attribut, la dropdown ne s'ouvre plus.

L'étape suivante consiste à remettre en place le fonctionnement de la dropdown avec du javascript tout en excluant les cas où l'on ne souhaite pas que la dropdown se ferme. Voici le code JS à mettre en place pour arriver à cela :
$(document).ready(function () {
    $('.searchMenu li.dropdown a').click(function (event) {
        $(this).parent().toggleClass("open");
    });

    $('body').click(function (e) {
        if (!$('.searchMenu li.dropdown').is(e.target) &&
            $('.searchMenu li.dropdown').has(e.target).length === 0 &&
            $('.open').has(e.target).length === 0) {
            $('.searchMenu li.dropdown').removeClass('open');
        }
    });
});
 La première partie du script permet de mettre en place la classe "open" sur le menu dropdown permettant d'ouvrir la dropdown, et cela est fait lors du click sur la dropdown.

La seconde partie du script permet de refermer la dropdown (en supprimant la classe "open") sauf dans le cas où l'on clique dans la dropdown.

Avec cela mon problème de menu "Rechercher" est réglé...