sercrod

Sortable list (drag and drop)

This example shows how to combine Sercrod with HTML drag and drop. You can drag table rows to reorder a small list. Sercrod keeps the table in sync with the underlying array.

For larger lists or keyboard-focused UIs, see List reordering (buttons).

Example: sortable table

The table rows are driven by an items array. Dragging a row calls a small helper to move one item in the array, and Sercrod re-renders the rows.

Code

<script>
function nab_move(list, from, to){
	if(from === to) return list;
	if(from < 0 || to < 0) return list;
	if(from >= list.length || to >= list.length) return list;

	var copy = list.slice();
	var item = copy.splice(from, 1)[0];
	copy.splice(to, 0, item);
	return copy;
}
</script>

<serc-rod data='{
	"items": [
		{ "name": "Apple",  "price": 120, "stock": 34 },
		{ "name": "Banana", "price": 80,  "stock": 12 },
		{ "name": "Orange", "price": 100, "stock": 50 },
		{ "name": "Grape",  "price": 200, "stock": 8  }
	]
}'>
	<table>
		<thead>
			<tr>
				<th>#</th>
				<th>Name</th>
				<th>Price</th>
				<th>Stock</th>
			</tr>
		</thead>
		<tbody>
			<tr
				*for="i, item of items"
				draggable="true"
				@dragstart="
					if(event.dataTransfer){
						event.dataTransfer.effectAllowed = 'move';
						event.dataTransfer.setData('text/plain', String(i));
					}
				"
				@dragover="event.preventDefault()"
				@drop="
					event.preventDefault();
					if(!event.dataTransfer) return;

					var from = parseInt(event.dataTransfer.getData('text/plain'), 10);
					if(isNaN(from)) return;

					var row = event.target.closest('tr');
					if(!row) return;

					var rows = Array.from(row.parentNode.children);
					var to   = rows.indexOf(row);
					if(to === -1 || from === to) return;

					items = nab_move(items, from, to);
				"
			>
				<td>%i%</td>
				<td>%item.name%</td>
				<td>%item.price%</td>
				<td>%item.stock%</td>
			</tr>
		</tbody>
	</table>
</serc-rod>

Sample

Try dragging a row and dropping it on another row. The item order changes and the table updates.

# Name Price Stock
%i% %item.name% %item.price% %item.stock%

Sortable or reorder?

Drag and drop is convenient and visually clear for small or medium-sized lists. However, as the number of items grows, it can become harder to aim the drop target, and it is more difficult to support purely keyboard-driven interaction.

For large lists, or when you want a more predictable, accessible interaction, consider the button-based pattern in List reordering (buttons). There, Sercrod still manages the array and the DOM, but users move items with explicit up / down actions instead of drag and drop.