[code]
/**
 * Reordering library
 * 
 * CHANGELOG
 * =================
 * DATE				VERSION			AUTHOR					DESCRIPTION
 * 2007-09-10		1.0.1			Rudie Dirkx				- Initial release
 * 2007-09-13		1.0.2			Rudie Dirkx				- Replaced eval() with [''+]
 *															- Added function G(), to replace $() (which is not in this library)
 *															- Updated function mf_SelectRow():
 *																- Original background color is now restored
 *																- More efficient way of selecting (removed a piece of identical code)
 * 
 * TODO
 * =================
 * Dynamic UP and DOWN action buttons -> in the same row as the selected row (when none selected, hide buttons)
 */

var Reorder = function( f_objTable, f_szHiliteBackgroundColor, f_szHtmlIdPrefix ) {
	this.m_objTable					= f_objTable;
	this.m_szHiliteBackgroundColor	= f_szHiliteBackgroundColor;
	this.m_szHtmlIdPrefix			= f_szHtmlIdPrefix;
};

Reorder.version = '1.0.2';
Reorder.prototype = {
	m_objTable						: null,
	m_szHtmlIdPrefix				: '',
	m_szSelectedId					: '',

	m_szHiliteBackgroundColor		: '',
	m_szCurrentRowBackgroundColor	: '',

	m_bReorderTableIds				: false,
	m_iReorderTableColumnIndex		: 0,
	m_iReorderTableStartsAt			: 0,

	m_szOrderListPrefix				: '',
	m_szOrderListGlue				: ',',


	G : function(id) {
		if ( 'object' != typeof id ) {
			id = document.getElementById(id);
		}
		return id;
	},

	mf_SelectRow : function( f_szRowId ) {
		objRow = this.G(f_szRowId);
		if ( this.m_szSelectedId && this.G(this.m_szSelectedId) )
		{
			// Unselect
			this.G(this.m_szSelectedId).style.backgroundColor = this.m_szCurrentRowBackgroundColor;
			if ( f_szRowId == this.m_szSelectedId )
			{
				
				this.m_szSelectedId = '';
				return false;
			}
		}
		// Select new row
		this.m_szCurrentRowBackgroundColor = objRow.style.backgroundColor;
		objRow.style.backgroundColor = this.m_szHiliteBackgroundColor;
		this.m_szSelectedId = f_szRowId;
		return false;
	},

	mf_MoveSelectedUp : function() {
		return this.mf_MoveSelect('previous');
	},

	mf_MoveSelectedDown : function() {
		return this.mf_MoveSelect('next');
	},

	mf_MoveSelect : function( f_szDirection ) {
		if ( !this.m_szSelectedId || !this.G(this.m_szSelectedId) )
		{
			return false;
		}
		objThisRow = this.G(this.m_szSelectedId);
		objOtherRow = objThisRow[f_szDirection+'Sibling'];
		while ( objOtherRow && 1 != objOtherRow.nodeType )
		{
			objOtherRow = objOtherRow[f_szDirection+'Sibling'];
		}
		if ( !objOtherRow )
		{
			return false;
		}
		tbody = this.m_objTable;
		objCopyRow = objThisRow.cloneNode(true);
		if ( 'next' == f_szDirection )
		{
			if ( objOtherRow.nextSibling )
			{
				tbody.insertBefore(objCopyRow, objOtherRow.nextSibling);
			}
			else
			{
				tbody.appendChild(objCopyRow);
			}
		}
		else
		{
			tbody.insertBefore(objCopyRow, objOtherRow);
		}
		tbody.removeChild(objThisRow);
		if ( this.m_bReorderTableIds )
		{
			r = this.m_objTable.rows;
			for ( i=0; i<r.length; i++ )
			{
				r[i].cells[this.m_iReorderTableColumnIndex].innerHTML = "" + (i+this.m_iReorderTableStartsAt) + "";
			}
		}
		return false;
	},

	mf_GetOrderList : function() {
		rows = this.m_objTable.rows;
		l = this.m_szHtmlIdPrefix.length;
		szList = "";
		for ( i=0; i<rows.length; i++ )
		{
			szList += this.m_szOrderListGlue + rows[i].id.substr(l);
		}
		return this.m_szOrderListPrefix + szList.substr(this.m_szOrderListGlue.length);
	}

};
[/code]


Het voorbeeld (index.php):
[code]
<?php

$bReorderNumbering = true;

if ( isset($_POST['l']) )
{
	$l = explode(",", $_POST['l']);
	if ( empty($l) || !is_array($l) )
	{
		exit('ERRORInvalid input list! Try again!?');
	}
	setCookie('list_order', implode(",", array_map('trim', $l)), time()+99999999);
	exit('New list was saved!');
}

$arrData = array(
	1 => array('Rudie', 'Dirkx', 'Y'),
	array('Johan', 'van Duren', 'Y'),
	array('Thiemen', 'Wijnja', 'Y'),
	array('Nils', 'Raijmakers', 'N'),
	array('Cihad', 'Yelken', 'N'),
	array('Sjuul', 'Meijers', 'Y'),
);

$arrOrder = isset($_COOKIE['list_order']) ? explode(",", $_COOKIE['list_order']) : array_keys($arrData);

?>
<html>

<head>
<title>Reorder Table</title>
<script type="text/javascript" src="/_inc/general_1_2_1.js"></script>
<script type="text/javascript" src="/_inc/ajax_1_2_1.js"></script>
<script type="text/javascript" src="/_inc/reorder_1_0_2.js"></script>
<script type="text/javascript">
<!--//
// UP = 38, DOWN = 40, LEFT = 37, RIGHT = 39
document.onkeyup = function(e) {
	e = e || window.event;
	if ( !e ) return;
	if ( e.keyCode == 38 ) {
		objOrderTable.mf_MoveSelectedUp();
	}
	else if ( e.keyCode == 40 ) {
		objOrderTable.mf_MoveSelectedDown();
	}
	else if ( e.keyCode == 37 ) {
		// Select previous row
		if ( objOrderTable.m_szSelectedId && $(objOrderTable.m_szSelectedId) && 0 < $(objOrderTable.m_szSelectedId).sectionRowIndex ) {
			SR(objOrderTable.m_objTable.rows[$(objOrderTable.m_szSelectedId).sectionRowIndex-1]);
		}
	}
	else if ( e.keyCode == 39 ) {
		// Select next row
		if ( objOrderTable.m_szSelectedId && $(objOrderTable.m_szSelectedId) && objOrderTable.m_objTable.rows.length > $(objOrderTable.m_szSelectedId).sectionRowIndex+1 ) {
			SR(objOrderTable.m_objTable.rows[$(objOrderTable.m_szSelectedId).sectionRowIndex+1]);
		}
	}
	else if ( e.keyCode == 27 ) {
		// Unselect row
		if ( objOrderTable.m_szSelectedId ) {
			objOrderTable.mf_SelectRow(objOrderTable.m_szSelectedId);
		}
	}
}

function SR(o) {
	objOrderTable.mf_SelectRow(o.id);
}
//-->
</script>
</head>

<body>

<p><?php echo implode(",", $arrOrder); ?></p>

<table border="1" cellpadding="2">
	<thead>
		<tr>
			<th>id</th>
			<th>#</th>
			<th>first</th>
			<th>last</th>
			<th>active</th>
			<th width="250"><input type="button" value="UP" onclick="return objOrderTable.mf_MoveSelectedUp();" />&nbsp;&nbsp;<input type="button" value="DOWN" onclick="return objOrderTable.mf_MoveSelectedDown();" /></th>
		</tr>
	</thead>
	<tbody id="reorder_table_body">
<?php

$c = array('yellow','blue','red');

foreach ( $arrOrder AS $k => $id )
{
	$data = $arrData[$id];
//	$p = $bReorderNumbering ? $k+1 : $id;
	echo'		<tr style="background-color:'.$c[array_rand($c)].';" id="rt_'.$id.'" onclick="SR(this);">'."\n";
	echo'			<th>'.$id.'</th>'."\n";
	echo'			<td>'.($k+1).'</td>'."\n";
	echo'			<td>'.$data[0].'</td>'."\n";
	echo'			<td>'.$data[1].'</td>'."\n";
	echo'			<td>'.$data[2].'</td>'."\n";
	echo'		</tr>'."\n";
}

?>
	</tbody>
</table>

<script type="text/javascript">
<!--//
var _page = '<?php echo basename($_SERVER['PHP_SELF']); ?>';

// Create an instance of the Reorder class: [ object TableBody, string HilightColor, string RowHtmlIdPrefix ]
var objOrderTable = new Reorder( $('reorder_table_body'), 'green', 'rt_' );
// Prefix for result of mf_GetOrderList() when the table is reordered
objOrderTable.m_szOrderListPrefix = '';
// The string used to glue the row ID's together when mf_GetOrderList() is called
objOrderTable.m_szOrderListGlue = ',';

<?php if ( $bReorderNumbering ) { ?>
// This example reorders the # of the table, which means it's renumbered every time a move is made:
objOrderTable.m_bReorderTableIds = true; // true when using this option (default: false)
objOrderTable.m_iReorderTableStartsAt = 1; // the first # in the table (default: 1)
objOrderTable.m_iReorderTableColumnIndex = 1; // the column in which the # is located (usually 0 (default) or 1)
<?php } ?>

// Save the reordered table with Ajax. My own Ajax lib is used for this, but really any method can be used.
// The only Reorder lib aspect used here is mf_GetOrderList():
function saveList() {
	szList = objOrderTable.mf_GetOrderList();
	new Ajax(_page, {
		params		: 'l='+szList,
		onComplete	: function(a) {
			if ( 'ERROR' == a.responseText.substr(0,5) ) {
				alert(a.responseText.substr(5));
				return;
			}
			alert(a.responseText);
		}
	});
	return false;
}
//-->
</script>

<p><input type="button" value="OrderList" onclick="return saveList()" /></p>

<div>
	<h2>About</h2>
	<p style="font-weight:bold;">This is not the easiest example. This example includes keyboard shortcuts, saving with Ajax and reordering the # of the table.</p>
	<p>To move a row vertically, select a row by clicking on it and use the UP and DOWN button to move it respectively UP and DOWN.</p>
	<p>When a row is selected, you can move also by using the UP and DOWN arrows on your keyboard.</p>
	<p>To change the selected row, use the LEFT and RIGHT arrows on your keyboard. Hit Escape to unselect a row.</p>
</div>

</body>

</html>
[/code]