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) :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
|
<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></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 code postaux qui constituent l’Ile-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, Ile-de-France) que nous avons établi.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
|
// 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 initale 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(); |
Code jQuery complet sans les commentaires:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
|
$(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(); }); |