Thursday, October 13, 2005

Javascript Custom Sort

In case you ever find yourself trying to handle a custom sort where you are moving countries around (like I described in my previous post) but you want to keep the US and Canada on top of the list, then you can use this code.

function move(fromBox, toBox)
{
// The lookup array has the value needed for each item.
// It is used to set the value of the option in the listbox.
var arrLookup = new Array();
var arrfromBox = new Array();
var arrtoBox = new Array();
var idx;

// Populate arrLookup and arrtoBox from the to listbox.
for( idx = 0; idx < toBox.options.length; idx++ )
{
arrLookup[ toBox.options[idx].text ] = toBox.options[idx].value;
arrtoBox[idx] = toBox.options[idx].text;
}

for( idx = 0; idx < fromBox.options.length; idx++)
{
// Add to the lookup array items from the fromBox.
arrLookup[ fromBox.options[idx].text ] = fromBox.options[idx].value;
if( fromBox.options[idx].selected && fromBox.options[idx].value != "" )
{
// put selected items into the toBox array at the end.
arrtoBox[arrtoBox.length] = fromBox.options[idx].text;
}
else
{
// Else put the item into the fromBox array.
arrfromBox[arrfromBox.length] = fromBox.options[idx].text;
}
}
// Sort the arrays.
arrfromBox.sort();
arrtoBox.sort();

// clear the list boxes
fromBox.length = 0;
toBox.length = 0;

arrfromBox = CustomSort(arrfromBox)
arrtoBox = CustomSort(arrtoBox)

// Add all of the items into the from box.
for(idx = 0; idx < arrfromBox.length; idx++)
{
var opt = new Option();
opt.value = arrLookup[ arrfromBox[idx] ];
opt.text = arrfromBox[idx];
fromBox[idx] = opt;
}

// Add all of the items into the to box.
for(idx = 0; idx < arrtoBox.length; idx++)
{
var opt = new Option();
opt.value = arrLookup[ arrtoBox[idx] ];
opt.text = arrtoBox[idx];
toBox[idx] = opt;
}
}

// --------------------------------------------------
function CustomSort(arrItems)
{
var arrExclusions = new Array();
// a for loop has a shortfall it only evaluates the length property once,
// But we need it to be fluid.
var checkLength = arrItems.length;
currentIdx = 0;
while( currentIdx < checkLength )
{
if( arrItems[currentIdx] == "USA" || arrItems[currentIdx] == "Canada" )
{
// populate the exclusion array with the items that should appear at the top.
arrExclusions[arrExclusions.length] = arrItems[currentIdx];
arrItems.splice(currentIdx, 1);
checkLength--;
}
else
{
// only increment if the value did not get removed.
// if it was removed, we need to check the same record.
currentIdx++
}
}
arrItems = arrExclusions.concat(arrItems);
return arrItems;
}

No comments: