2010-09-10 19 views
8

Non ho alcun problema ad afferrare un elenco di elementi e ordinarli alfabeticamente, ma ho difficoltà a capire come farlo con un modulo.Ordinare una lista alfabeticamente con un modulo

### UPDATE ###

Ecco il codice di lavoro 'a modo mio', però, mi piace la riutilizzabilità della risposta fornita al di sotto di più, così ho accettato quella risposta.

<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> 

Ad esempio. Dire che ho il seguente elenco non ordinato:

<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> 

Ho questo elenco impostato per la visualizzazione in 4 colonne con ogni li floatato a destra. Visivamente questo rende difficile trovare oggetti in elenchi più grandi. L'uscita ho bisogno è questo:

<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> 

Quello che sto cercando è una funzione che posso passare la mia serie di voci di elenco e ottenere la mia matrice restituita, in ordine alfabetico, con un modulo di scelta; in questo caso 4.

Qualsiasi aiuto sarebbe apprezzato in quanto non trovo documentazione sull'argomento.

+0

Potrebbe pubblicare il codice avete già? –

+0

E, supponendo che tu stia sviluppando questo da un back-end, perché non lo stai facendo dal lato server? – Chubas

+1

In realtà c'è una soluzione CSS, con 'column-count' –

risposta

2
  1. Alphabetize your list. Questo è già stato fatto, nel tuo caso, ma se non:

    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. Conservare l'indice alfabetico di ogni elemento:

    $.each(alphabetizedList, function(i) 
    { 
        $(this).data("alphaIndex", i); 
    }); 
    
  3. Ordinare l'elenco in ordine alfabetico per modulo, poi index:

    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. Sostituire gli elementi della lista con i vostri elementi ordinati:

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

Ecco il tutto, tutti insieme:

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"] 

Applicare quella funzione all'elenco già ordinato e quindi restituirà un elenco di stringhe nell'ordine (quasi) desiderato. Quindi aggiungi l'elenco che è stato restituito per l'elenco non ordinato nel DOM.

Inoltre, non l'ho provato con altro oltre quella lista. Quindi lo farei se fossi in te. Da quello che vedo, funziona solo se la lunghezza della lista è un multiplo di n. Non è una grande soluzione, ma è tardi per me e non posso essere disturbato a inventare qualcosa di meglio.

EDIT: risolto il problema con l'ultimo elemento

+0

la teoria è abbastanza solida ma l'implementazione non è corretta. Passare in una schiera di 17 elementi con n = 4 produce 0 4 8 12 quattro volte con un 16 finale nella quinta fila. – ErikE

+0

@Emtucidifor: Sì. Come ho detto, non funziona quando n% lenght! = 0. –

0

Vedere se questo funzionerà: 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]); 
} 

Necessita miglioramenti, probabilmente, ma non sono davvero sicuro di quanto bene funziona affatto.

0

Ecco qui. Il codice è sorprendentemente semplice una volta capito. Mi rendo conto che stai usando jQuery ma non ne ho abbastanza familiarità per usare le sue funzionalità. Questo è abbastanza semplice che forse non è necessario.

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; 
} 

Ed ecco il test per dimostrare che funziona (testato in 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> 

Ancora una cosa: potrebbe essere utile a poco mossa gli elementi attorno al posto. Avevo quasi una sceneggiatura, ma il mio script stava girando all'indietro (come se i float andassero da cima a fondo prima). Se avrò tempo lavorerò su di esso e pubblicherò il codice.

P.S. Qualcuno vuole darmi dei suggerimenti sul motivo per cui ho dovuto aggiungere 2 al calcolo della larghezza per IE6? Aspetta ... sono i confini del div non è vero?

Problemi correlati