List reordering (click to insert)
This example shows a click-based way to reorder items in a long list. You first mark one row as “moving”, then click a slot to insert it before or after another row.
This pattern works better than simple Up / Down buttons when you have dozens of items, and it is easier to reason about than free-form drag and drop for some users.
Example: click-to-reorder list
The list is driven by an items array. A small helper
function nab_move rebuilds the array with one item moved
from index from to index to.
Code
<script>
// Move a single element from index "from" to index "to"
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];
// When moving to a later position, adjust index after removal
if(from < to) to = to - 1;
copy.splice(to, 0, item);
return copy;
}
// Build demo data: 100 items
var items = [];
for(var i=1; i<=100; i++){
var n = String(i).padStart(3, "0"); // 001, 002, ...
items.push({ id: i, label: "Item " + n });
}
// Data passed to Sercrod
var json = {
items: items,
move_index: null,
is_reordering: false
};
</script>
<serc-rod id="reorder-list" data="__reorder_demo_data">
<h2>Reorder (click to insert)</h2>
<p>
Click “Start move” on a row, then click “Insert here”
to move it.
</p>
<p *if="is_reordering">
Moving:
<span *print="
(move_index!=null && move_index>=0 && move_index<items.length)
? items[move_index].label
: ''
"></span>
<span
@click="
is_reordering = false;
move_index = null;
"
>[Cancel move]</span>
</p>
<p *else>No active move.</p>
<ul>
<li>
<span
*if="is_reordering"
@click="
if(move_index===null) return;
items = nab_move(items, move_index, 0);
is_reordering = false;
move_index = null;
"
>Insert at top</span>
<span *else>--------</span>
</li>
<li *for="i, item of items">
<div>
<span>%i%: %item.label%</span>
<button type="button"
@click="
if(is_reordering && move_index===i){
is_reordering = false;
move_index = null;
}else{
is_reordering = true;
move_index = i;
}
"
>Start move</button>
<em *if="is_reordering && move_index===i">Selected</em>
</div>
<div>
<span
*if="is_reordering"
@click="
if(move_index===null) return;
var to = i + 1;
items = nab_move(items, move_index, to);
is_reordering = false;
move_index = null;
"
>Insert here</span>
<span *else>--------</span>
</div>
</li>
</ul>
</serc-rod>
Sample
In the live sample below you can reorder up to 100 items.
Sercrod keeps the items array and the rendered list
in sync.
Reorder (click to insert)
Click “Start move” on a row, then click “Insert here” to move it.
Moving:
=0 && move_index
No active move.
- Insert at top --------
-
%i%: %item.label% SelectedInsert here --------
When this pattern helps
- Lists with many rows where drag handles are hard to use precisely.
- Cases where you want a clear, step-by-step reordering flow.
- Interfaces that may later add keyboard shortcuts on top of the same data operations.
For a more direct, visual interaction on smaller tables, see Sortable list (drag and drop).