2010-09-10 5 views
8

Je n'ai aucune difficulté à saisir une liste d'éléments et à les trier par ordre alphabétique, mais j'ai de la difficulté à comprendre comment le faire avec un module.Trier une liste par ordre alphabétique avec un module

### MISE À JOUR ###

est ici le code de travail « mon chemin », cependant, j'aime la réutilisabilité de la réponse fournie ci-dessous plus, ont donc accepté cette réponse.

<script type="text/javascript"> 
$(document).ready(function() { 
    $('.sectionList2').each(function() { 
     var oldList = $('li a', this), 
      columns = 4, 
      newList = []; 
     for(var start = 0; start < columns; start++){ 
      for(var i = start; i < oldList.length; i += columns){ 
       newList.push('<li><a href="' + oldList[i].href + '">' + $(oldList[i]).text() + '</a></li>'); 
      } 
     } 
     $(this).html(newList.join('')); 
    }); 
}); 
</script> 

Par exemple. Dites que j'ai la liste non ordonnée suivante:

<ul> 
    <li><a href="~">Boots</a></li> 
    <li><a href="~">Eyewear</a></li> 
    <li><a href="~">Gloves</a></li> 
    <li><a href="~">Heated Gear</a></li> 
    <li><a href="~">Helmet Accessories</a></li> 
    <li><a href="~">Helmets</a></li> 
    <li><a href="~">Jackets</a></li> 
    <li><a href="~">Mechanic's Wear</a></li> 
    <li><a href="~">Pants</a></li> 
    <li><a href="~">Protection</a></li> 
    <li><a href="~">Rainwear</a></li> 
    <li><a href="~">Random Apparel</a></li> 
    <li><a href="~">Riding Suits</a></li> 
    <li><a href="~">Riding Underwear</a></li> 
    <li><a href="~">Socks</a></li> 
    <li><a href="~">Vests</a></li> 
</ul> 

J'ai cette liste à afficher dans 4 colonnes avec chaque li flottant à droite. Visuellement, cela rend difficile la recherche d'éléments dans des listes plus grandes. La sortie j'ai besoin est la suivante:

<ul> 
    <li><a href="~">Boots</a></li> 
    <li><a href="~">Helmet Accessories</a></li> 
    <li><a href="~">Pants</a></li> 
    <li><a href="~">Riding Suits</a></li> 
    <li><a href="~">Eyewear</a></li> 
    <li><a href="~">Helmets</a></li> 
    <li><a href="~">Protection</a></li> 
    <li><a href="~">Riding Underwear</a></li> 
    <li><a href="~">Gloves</a></li> 
    <li><a href="~">Jackets</a></li> 
    <li><a href="~">Rainwear</a></li> 
    <li><a href="~">Socks</a></li> 
    <li><a href="~">Heated Gear</a></li> 
    <li><a href="~">Mechanic's Wear</a></li> 
    <li><a href="~">Random Apparel</a></li> 
    <li><a href="~">Vests</a></li> 
</ul> 

Ce que je suis à la recherche est une fonction que je peux passer mon tableau d'éléments de liste et obtenir mon tableau retourné, classés par ordre alphabétique, avec un module de choix; dans ce cas 4.

Toute aide serait appréciée car je ne peux trouver aucune documentation sur le sujet.

+0

Pouvez-vous poster le code que vous avez déjà? –

+0

Et, en supposant que vous développiez ceci à partir d'un backend, pourquoi ne faites-vous pas cela côté serveur? – Chubas

+1

Il existe actuellement une solution CSS pour cela, avec 'column-count' –

Répondre

2
  1. Alphabetisez votre liste. Cela se fait déjà, dans votre cas, mais sinon:

    function alphabetizeElements(a, b) 
    { 
        var aText = $(a).text(); 
        var bText = $(b).text(); 
        return aText > bText ? 1 : aText < bText ? -1 : 0; 
    } 
    var alphabetizedList = $("#myList li").sort(alphabetizeElements); 
    
  2. Stocker l'index alphabétique de chaque élément:

    $.each(alphabetizedList, function(i) 
    { 
        $(this).data("alphaIndex", i); 
    }); 
    
  3. Trier la liste alphabétique par module, puis l'indice:

    function listColumnSortFn(columns) 
    { 
        return function(a, b) 
        { 
         var aIndex = $(a).data("alphaIndex"); 
         var bIndex = $(b).data("alphaIndex"); 
         return ((aIndex % columns) - (bIndex % columns)) || (aIndex - bIndex); 
        } 
    } 
    var columnSortedList = alphabetizedList.sort(listColumnSortFn(4)); 
    
  4. Remplacer les éléments de la liste avec vos éléments triés:

    $("#myList li").remove(); 
    $("#myList").append(columnSortedList); 
    

Voici la chose, tous ensemble:

function sortList(columns) 
{ 
    var alphabetizedList = $("#myList li").sort(alphabetizeElements); 
    $.each(alphabetizedList, function(i) 
    { 
     $(this).data("alphaIndex", i); 
    }); 
    var columnSortedList = alphabetizedList.sort(listColumnSortFn(columns)); 
    $("#myList li").remove(); 
    $("#myList").append(columnSortedList); 
} 
function alphabetizeElements(a, b) 
{ 
    var aText = $(a).text(); 
    var bText = $(b).text(); 
    return aText > bText ? 1 : aText < bText ? -1 : 0; 
} 
function listColumnSortFn(columns) 
{ 
    return function(a, b) 
    { 
     var aIndex = $(a).data("alphaIndex"); 
     var bIndex = $(b).data("alphaIndex"); 
     return ((aIndex % columns) - (bIndex % columns)) || (aIndex - bIndex); 
    } 
} 
$(function() 
{ 
    sortList(4); 
}); 
0
var columnify = function (a,n) { 
    var result = []; 
    for (var i = 0, lastIndex = a.length - 1; i < lastIndex; i++) 
     result.push(a[i * n % (lastIndex)]); 
    result[lastIndex] = a[lastIndex]; 
    return result; 
} 

var products = ["Boots", 
"Eyewear", 
"Gloves", 
"Heated Gear", 
"Helmet Accessories", 
"Helmets", 
"Jackets", 
"Mechanic's Wear", 
"Pants", 
"Protection", 
"Rainwear", 
"Random Apparel", 
"Riding Suits", 
"Riding Underwear", 
"Socks", 
"Vests",] 

columnify(products, 4) 
["Boots", "Helmet Accessories", "Pants", "Riding Suits", "Eyewear", "Helmets", "Protection", "Riding Underwear", "Gloves", "Jackets", "Rainwear", "Socks", "Heated Gear", "Mechanic's Wear", "Random Apparel", "Vests"] 

Appliquer cette fonction à la liste déjà triée, puis il retournera une liste de chaînes dans l'ordre (presque) que vous voulez. Ajoutez ensuite la liste qui a été renvoyée dans la liste non ordonnée dans le DOM.

Aussi, je ne l'ai pas testé avec autre chose que cette liste. Donc je ferais ça si j'étais toi. D'après ce que je vois, cela ne fonctionne que si la longueur de la liste est un multiple de n. Ce n'est pas une bonne solution, mais il est tard pour moi et je ne peux pas être dérangé pour trouver quelque chose de mieux.

EDIT: correction d'un problème le dernier élément

+0

la théorie est assez solide mais la mise en œuvre n'est pas correcte. Le fait de passer dans un tableau de 17 éléments avec n = 4 donne quatre fois 4 4 8 avec une finale de 16 dans la cinquième rangée. – ErikE

+0

@Emtucidifor: Oui. Comme je l'ai dit, ça ne marche pas quand n% de longueur! = 0. –

0

Voir si cela fonctionne: http://jsfiddle.net/6xm9m/2

var newList = new Array(); 
var listItem = $('#list > li'); 
var mod = 4; 
var colCount = Math.ceil(listItem.length/mod); 

listItem.each(function(index) { 
    var newIndex = ((index % colCount) * mod) + Math.floor(index/colCount); 
    // $(this).text(newIndex); 

    newList[newIndex] = this; 
}); 

$('#list').empty(); 

for(var i = 0; i < newList.length; i++){ 
    $('#list').append(newList[i]); 
} 

a besoin d'améliorations, probablement, mais je ne suis pas vraiment sûr comment cela fonctionne à tous.

0

C'est parti. Le code est étonnamment simple une fois que vous l'avez compris. Je me rends compte que vous utilisez jQuery mais je ne suis pas assez familier avec lui pour utiliser ses fonctionnalités. C'est assez simple que ce n'est peut-être pas nécessaire.

function pivotArray(arr, columns) { 
    var l = arr.length, out = [], ind = 0, i = 0; 
    for (; i < l; i += 1) { 
     out[ind] = arr[i]; 
     ind += columns; 
     if (ind >= l) { 
     ind = ind % columns + 1; 
     } 
    } 
    return out; 
} 

Et voici le test pour prouver qu'il fonctionne (testé dans Firefox 3.6.9, IE 6, Chrome 1.0.154.36):

<html> 
<head> 
<style type="text/css"> 
a.panelnum { 
    display:block; 
    float:left; 
    width:40px; 
    height:40px; 
    border:1px solid black; 
    text-align:center; 
    vertical-align:middle; 
    text-decoration:none; 
    font-size:2em; 
} 
</style> 
</head> 
<body onload="doit(17, 4);"> 
<div id="output" style="border:1px solid blue;"> 
</div> 
<script type="text/javascript"> 

function pivotArray(arr, columns) { 
    var l = arr.length, out = [], ind = 0, i = 0; 
    for (; i < l; i += 1) { 
     out[ind] = arr[i]; 
     ind += columns; 
     if (ind >= l) { 
     ind = ind % columns + 1; 
     } 
    } 
    return out; 
} 

function doit(size, columns) { 
    document.getElementById('output').innerHTML = 'starting'; 
    var l = size; 
    var inp = []; 
    for (var i = 0; i < l; i += 1) { 
     inp[i] = i; 
    } 
    var result = pivotArray(inp, columns); 
    var str = ''; 
    for (i = 0; i < l; i += 1) { 
     str += '<a class="panelnum">' + result[i] + '</a>'; 
    } 
    var d = document.getElementById('output') 
    d.innerHTML = '<p>Some pre text</p>' + str + '<p style="clear:both;">and some post text</p>'; 
    d.style.width = (columns * d.childNodes[1].offsetWidth + 2) + 'px'; 
} 
</script> 
</body> 
</html> 

Encore une chose: il pourrait être utile de simplement déplacer les éléments autour de l'endroit. J'avais presque un script pour ça mais mon script courait en arrière (comme si les flotteurs allaient d'abord du haut vers le bas). Si j'ai le temps je vais travailler dessus et poster le code.

P.S. Quelqu'un veut me donner des indications sur pourquoi j'ai dû ajouter 2 au calcul de la largeur pour IE6? Attends ... c'est les frontières de la div n'est-ce pas?

Questions connexes