views:

134

answers:

2

I'm looking for a way to sort my elements, but it isn't as easy as it sounds. Please let me explain

My elements are grouped per 6 elements (thumbnails), each x represents a thumbnail However all thumbnails are inside one div

xx   xx   xx
xx   xx   xx
xx   xx   xx

The first column (6 x's) is visible and when you click on a button the next column appears and the old one disappears.

If it happens that the ammount of x's is not possible to devide with 6, e.g. you have 11 x's, then it adds filler elements (o's)

xx   xx
xx   xx
xx   x0

If each element no matter thumbnail or filler represents a number in which order their added in this 'table' then it looks like this

1,2    3,4    5,6
7,8    9,10   11,12
13,14  15,16  17,18

However I want to have the latest thumbnails (1->6) on the initial page. as they are the latest (newest thumbnails) so I want to show them first. (ordered by 'date') Which means the previous 'table' needs to be like this:

1,2    7,8    13,14
3,4    9,10   15,16
5,6    11,12  17,18

Now the difficulty is that it should re-order the thumbnails no matter how many columns there are whether there are only 2 columns or 10 columns.

Here's a live link of the problem (2 columns, 7 thumbnails and 5 fillers): link text then click on gallery and you'll see 'column' 1 (6 thumbnails)

all the elements (thumbnails and fillers) are insert into an array (javascript) so I would need to change it's position for each element with JS (or jquery if easier for you)

I know this isn't really a simple question, I tried my best to explain if you have any questions regarding the question feel free to ask and I'll answer asap.

edit: OK I'm a lot closer thanks to Vincent Robert. My array of objects (my thumbnails are in here) just now needs to be ordered the way it does with Vincent's array of numbers. I tested out his method which orders the elements of the array to their perfect place. They use the number as index, but I don't have that. Anyone know how to do this?

+1  A: 

You have to think of your values as pixels. If you want to sort them, you need to first compute their position and then translate this position into an offset in the table.

Once you have the offset, it is easy to sort the array. Here is an example code (0-based to simplify):

// Your constants
var nbGroup = 3, 
    nbCol = 2
    nbLine = 3,
    nbPerGroup = nbCol * nbLine;

function computeOffset(index)
{
   // Search the block
   var group = Math.round(index / nbPerGroup - 0.5);
   var groupPos = index % nbPerGroup;

   // Search the line
   var line = Math.round(groupPos / nbCol - 0.5);
   // Search the column
   var col = groupPos % nbCol;

   // This formula is dependent on your layout
   return col
        + line * nbCol * nbGroup
        + group * nbCol;
}

// Fill an array from 0 to 17
var array = [];
for( var i = 0; i < 18; ++i )
{
  array.push(i);
}

// Sort our array based on the position offset
array.sort(function(a, b)
{
  return computeOffset(a) - computeOffset(b);
});


console.log(array); // [0, 1, 6, 7, 12, 13, 2, 3, 8, 9, 14, 15, 4, 5, 10, 11, 16, 17]

I didn't do the actual sorting of DOM nodes but you are smart enough to do it by yourself, do you? ;-)


Ok, to sort an array of DOM nodes, you must have access to the index of your node or compute it. Here is a solution (untested code):

var elements = ...

var nodes = []
for( var i = 0, l = elements.length; i < l; ++i )
{
    nodes.push({ index:i, element:elements[i] });
}

nodes.sort(function(a, b)
{
    return computeOffset(a.index) - computeOffset(b.index);
});

// Your DOM array should be sorted now.
// Note that you will have to append DOM nodes (yes again) 
// to the document to actually sort the displayed elements.

var target = ...

for( var i = 0, l = nodes.length; i < l; ++i )
{
    target.appendChild(nodes[i].element);
}
Vincent Robert
thanks a lot, I tested your theory and it worked like a charm. Keep up the good work.
Ayrton
It only seems to work if the array you sort on containers numbers only. But in this example my array contains my thumbnails. Any Idea how to fix this?
Ayrton
when I test on the a and b in the function (which needs to be an integer) and isn't at this moment. I would need to pass on the index of the element. I have tried but did not succeeded.Thanks in advance
Ayrton
Edited to add sorting of DOM nodes, hope this helps :)
Vincent Robert
you're awesome thanks a lot vincent!
Ayrton
A: 

I see there is already an answer, I took a slightly less computational approach, but I wasn't sure if this was just about displaying them once in the right order or if you need to later really SORT stuff.

here is my code:

<style type="text/css">

    ul { 
     padding: 0; 
     margin: 0 2px 2px 0; 
     overflow: hidden; width: 200px; 
     background-color: red; 
     float: left;
    }



</style>
<script type="text/javascript">
    var thumbsDOTlength = 30;

    var col = 0;
    var perRow = 6;

    var html = [];
    html.push("<ul>");
    for(var i = 0; i < thumbsDOTlength; i++) {
     html.push("<li> Item " + i + "  (" + col + "," + (i - col * perRow) + ")</li>");

     if(i % perRow == perRow - 1) {
      html.push("</ul><ul>");
      col++;
     }
    }

    html.push("</ul>");

    document.write(html.join(''));

</script>
Les