How can I sort a list of values in the loaded order?

168 Views Asked by At

Application You have a list of items 1 through n and you want users to rank them n through 1. Each item has a due date. Item 1 has the nearest due date, item n the latest due date. You want users to rank/sort the items in their desired rank order before items' due dates lapse. You do not want users to be able to rank/sort an item once its due date lapses, but you still want to display all items with their sorted rank.

To separate items due from items past due, you load them into two separate tables.

--Items Due table: The top table holds due items only that users can rank by sorting. The order is loaded in the rank order descending. (rank order is the visible number in jsFiddle examples below)

--Items Past Due table: The bottom table holds items past due that users can no longer sort. Once an item(s) goes past due and into this table it holds the rank that was previously saved. The order is in item order counting up..the same as due date order ascending.

Example Say you have a list of ten items that you want users to rank. Before any items go past due, you will have only the items due table displaying like this: http://jsfiddle.net/jpl1618/DdShg/ There you have the items listed 1-10 and due date ascending (due date not shown). The number displayed on screen is the rank in descending order.

The rank in the items due table is always in descending order so that users can move up the item to a greater confidence or down to a lesser confidence. The rank count will always match the item count but they begin with their opposites. For example, item 1 will begin with the rank position 10 (at the top) and item 10 in rank position 1 (at the bottom).

Once items go past due, the bottom table will display and hold those past due items. Let's say the user sorted the items, saved them, and half of them went past due. You might have the tables displaying like this http://jsfiddle.net/jpl1618/Y4tjJ/ Notice that the bottom table holds items 1 through 5 in that order. That's because the bottom table orders them in item order ascending which is the same as due date ascending. Also notice that the user had sorted items 4 and 5 into a rank position of 10 and 6. Those rank positions can no longer be used when re-ranking the items due table.

Examples with Past Due items Here jsfiddle.net/jpl1618/Y4tjJ/ I should be able to move item 8 (in position 5) up one to position 7 which would move item 10 (in position 7) down to position 5. So you would have the result:

item 9 => rank 9
item 6 => rank 8
item 8 => rank 7
item 10 => rank 5
item 7 => rank 4

Or I should be able to move item 8 all the way to the top in position 9 which would move items 9,6,10 down one spot. Then you would have:

item 8 => rank 9
item 9 => rank 8
item 6 => rank 7
item 10 => rank 5
item 7 => rank 4

Notice the rank order stays in the same descending order no matter the item order.

Question How can the current JS code be altered to allow the user to rank/sort the items in the items due table that holds the loaded rank positions in their descending order? In the examples, the rank order should always display 9,8,7,5,4 but the items can be moved around into those positions.

count = 5
countL = 5

L stands for locked

Another minor issue: why do the table rows switch colors when clicking down to sort? How can I have the row not flash to the other color when clicking down on a row?

1

There are 1 best solutions below

3
On

I think that given that n is a small number we can assume that an O(n^2) solution is ok.

So you could build an index map using map function :

var myIndexMap = actualyUserdSortedArray.map( function (x) { 
                           return originalArray.indexOf(x); 
                 } );

Then once you built this index map, you can access your array originalArray in the user defined order by using this map :

 var ithItem =  originalArray[myIndexMap[i]];

based on this idea i modified your fiddle as you can see here : http://jsfiddle.net/Y4tjJ/3/ I added a first line to show the current mapping array, that is re-built on each order change.

Edit : given the relative complexity of the behaviour you seek, i would rather go for a more code-oriented way of making this. You need to handle 4 informations for each item : id (1-n), isLocked(true/false), dueDate(Date), userOrder(1-c where c is the non-locked count). Then the upper list is AllItems.filter(function(x) { return x.isLocked } ) .sort(function(a,b) { return (a.userOrder - b.userOrder) } ); The lower list is AllItems.filter(function(x) { return ! x.isLocked } );

Because things will soon get more complicated : After you loaded the list from some kind of permanent storage (localStorage or server file), it could be simpler if JSON of simple js objects.
Then you will have 3 events to handle. 1) Every now and then you must check for the non locked if they elapsed. if one elapsed, increase by one all userOrder that are < the userOrder that elapsed.
2) There must be some kind of way to 'use' an item before it elapsed, otherwise the user has no interest in sorting the items.If an item is used now, it should be set as locked. Same update for userOrder as in 1). 3) then you have to handle the sorted changed event, to update the usedOrder on items that are unlocked.

good luck.