Créer des catégories avec jQuery

Comment créer à l'aide de jQuery des catégories et utiliser leurs scopes pour trier des éléments présents dans le DOM ?

jquery

Problème:

Mon code m'affiche une liste de boutiques d'une même enseigne sur l'ensemble des villes françaises. Cette liste ne fait l'objet d'aucun tri. J'ai besoin de créer 3 groupes bien distincts de boutiques:

  • Les boutiques sur Paris
  • Les boutiques en région parisienne
  • Les boutiques en province

Exemple du code source de ma liste de boutiques (vous observerez pour la suite de ce tutoriel la présence des classes .shop-all pour la liste et .shop-zipcode pour baliser chaque code postal) :

<ul class="shop-all">
  <li id="2269">
    <a class="link" href="#">
      <span class="shop-label">Boutique BORDEAUX</span>
      <span class="shop-address1">34 cours de l'Intendance</span>
      <span class="shop-address2"></span>
      <span class="shop-zipcode">33000</span> <span class="shop-city">Bordeaux</span>
    </a>
  </li>
  <li id="2227">
    <a class="link" href="#">
      <span class="shop-label">Boutique BOULOGNE</span>
      <span class="shop-address1">121 bd Jean Jaures</span>
      <span class="shop-address2"></span>
      <span class="shop-zipcode">92100</span> <span class="shop-city">Boulogne</span>
    </a>
  </li>
  <li>
    <a class="link" href="#">
      <span class="shop-label">Boutique ST ANTOINE</span>
      <span class="shop-address1">6 rue St Antoine</span>
      <span class="shop-address2"></span>
      <span class="shop-zipcode">75004</span> <span class="shop-city">Paris</span>
    </a>
  </li>
[...]
</ul>

Solution:

Préparer le markup HTML à la création dynamique de 3 listes.

Dans la source HTML, on initie une liste pour chacun des 3 groupes précités.

<ul id="shop-paris"></ul>
<ul id="shop-idf"></ul>
<ul id="shop-province"></ul>

Récupérer une information de nature similaire sur chaque élément qui nous permettra ensuite d'effectuer le tri voulu.

Pour chaque boutique, on commence via les méthodes jQuery .each() et .text() par récupérer le code postal complet (5 caractères) marqué par la classe .shop-zipcode qui se trouve dans le DOM pour baliser chaque code postal. On tronque immédiatement chaque valeur récupérée pour ne conserver que les 2 premiers caractères via la méthode .substring() et on l'affiche dans le DOM via un data-attribute data-zipcode="" qu'on affecte à chaque élément li de notre liste initiale de boutiques.

// Pour chaque boutique, on récupère le code postal complet (5 caractères).
$('.shop-zipcode').each(function(){
  var getShopZipcode = $(this).text();

  // On tronque chaque code postal récupéré pour ne conserver que les 2 premiers caractères
  // et on l'affiche dans le DOM via un data-attribute.
  $(this).closest('li').attr('data-zipcode', getShopZipcode.substring(0, 2));
});

Déterminer un scope pour chaque catégorie et marquer chaque élément de la liste en fonction.

On attribue à chaque boutique (chaque élément de notre liste initiale) une classe .is-paris, .is-idf ou .is-province en fonction de la zone géographique (nos catégories) dans laquelle elle se situe.

Au préalable, on crée un tableau idfCodeList qui regroupe tous les codes postaux qui constituent l’Île-de-France.

On va ensuite marquer par une classe ajoutée dans le DOM chaque élément de notre liste en fonction de sa catégorie. On commence par localiser les boutiques sur Paris dont le scope est constitué des codes postaux qui commencent par "75" avec une première condition if().

On marque ensuite les éléments dont le code postal figure dans notre tableau idfCodeList avec une seconde condition else if(). La méthode jQuery .inArray va nous permettre de vérifier si chaque élément de liste possède un code postal qui correspond au scope du tableau que nous venons de créer et de marquer les éléments correspondants en fonction.

Pour finir, on marque les éléments restants (boutiques en province) puisqu'ils n'entrent dans aucun des deux premiers scopes (Paris, Île-de-France) que nous avons établi.

// On attribue à chaque boutique une classe .is-paris, .is-idf ou .is-province
// en fonction de la zone géographique dans laquelle elle se situe.
$('ul.shop-all li').each(function(){
  var dataZipcode = $(this).attr('data-zipcode');
  // Pour la zone IDF, on crée un tableau qui regroupe tous les code postaux
  // qui constituent l'Ile-de-France.
  var idfCodeList = ["77","78","91","92","93","94"];

  // On commence par localiser les boutiques sur Paris.
  if((dataZipcode == 75)){
    $(this).addClass('is-paris');
  }

  // On localise ensuite les boutiques en Ile-de-France.
  else if($.inArray(dataZipcode, idfCodeList) >= 0){
    $(this).addClass('is-idf');
  }

  // Si tout a bien fonctionné jusqu'ici, il ne reste que les boutiques sur
  // le reste de la France.
  else{
    $(this).addClass('is-province');
  }
});

On déplace chaque élément précédemment marqué dans la catégorie correspondante.

On commence, pour écrire moins de code, par déclarer dans un tableau isZones un libellé pour chacune des trois zones qui serviront à trier les boutiques. Ces libellés doivent être repris de ceux des IDs des 3 listes initiées précédemment dans votre source HTML.

On peut ensuite créer une boucle qui affectera dynamiquement chaque boutique à l'une des 3 listes correspondante dans le DOM en fonction de la zone géographique dans laquelle elle se trouve. Pour ce faire, on utilise les libellés déclarés dans le tableau isZones.

// On déclare, dans un tableau "isZones", un libellé pour chacune des trois zones qui
// serviront à trier les boutiques.
var isZones = ["paris","idf","province"];

// On crée une boucle qui affectera dynamiquement chaque boutique à l'une des 3 listes correspondante 
// dans le DOM en fonction de la zone géographique dans laquelle elle se trouve.
// Pour ce faire, on utilise les libellés déclarés dans le tableau "isZones".
$.each(isZones, function(index,value){
  $('li.is-'+ value).each(function(){
    $(this).appendTo('ul#shop-' + value);
  });
});

Pour finir, nettoyer le DOM de tout markup inutile.

La liste initiale de boutiques est maintenant vide. Supprimons là du DOM.

// On supprime la liste initiale du DOM puisqu'elle est désormais vide.
$('ul.shop-all').remove();

Le DOM après transformation:

Nous avons désormais, en remplacement d'une liste unique pourtant la classe .shop-all, trois listes bien distinctes #shop-paris, #shop-idf et #shop-province.

<ul id="shop-paris">
  <li id="2224" data-zipcode="75" class="is-paris">
    <a class="link" href="#">
      <span class="shop-label">Boutique CAPUCINES</span>
      <span class="shop-address1">39 bd des Capucines</span>
      <span class="shop-address2"></span>
      <span class="shop-zipcode">75002</span> <span class="shop-city">Paris</span>
    </a>                  
  </li>
  /* Autres boutiques sur Paris */
</ul>

<ul id="shop-idf">
  <li id="2227" data-zipcode="92" class="is-idf">
    <a class="link" href="#">
      <span class="shop-label">Boutique BOULOGNE</span>
      <span class="shop-address1">121 bd Jean Jaures</span>
      <span class="shop-address2"></span>
      <span class="shop-zipcode">92100</span> <span class="shop-city">Boulogne</span>
    </a>                  
  </li>
  /* Autres boutiques en IDF */
</ul>

<ul id="shop-province">
  <li id="2269" data-zipcode="33" class="is-province">
    <a class="link" href="http://manfield-manbow.netapsys.fr/boutique-manfield-bordeaux.html">
      <span class="shop-label">Boutique BORDEAUX</span>
      <span class="shop-address1">34 cours de l'Intendance</span>
      <span class="shop-address2"></span>
      <span class="shop-zipcode">33000</span> <span class="shop-city">Bordeaux</span>
    </a>
  </li>
  /* Autres boutiques en province */
</ul>

Code jQuery complet sans les commentaires:

Utiliser le lien Pastebin ou l'affichage brut.

$(document).ready(function(){
  $('.shop-zipcode').each(function(){
    var getShopZipcode = $(this).text();
    $(this).closest('li').attr('data-zipcode', getShopZipcode.substring(0, 2));
  });   

  $('ul.shop-all li').each(function(){
    var dataZipcode = $(this).attr('data-zipcode');
    var idfCodeList = ["77","78","91","92","93","94"];

    if((dataZipcode == 75)){
      $(this).addClass('is-paris');
    }

    else if($.inArray(dataZipcode, idfCodeList) >= 0){
      $(this).addClass('is-idf');
    }

    else{
      $(this).addClass('is-province');
    }
  });

  var isZones = ["paris","idf","province"];
  $.each(isZones, function(index,value){
    $('li.is-'+ value).each(function(){
      $(this).appendTo('ul#shop-' + value);
    });
  });

  $('ul.shop-all').remove();       
});

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Captcha *

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.