Drag order
An HTML list of items could have an HTML form containing an order input to reorder the list. Flux can automatically convert this server-rendered form into a drag-and-drop list that works on touch or pointer devices.
The server remains responsible for storing and rendering the order. Flux only provides the browser interaction: it hides the manual order controls, adds a drag handle, moves the item in the DOM while dragging, and submits the existing form in the background when the item is dropped.
Server-side contract
Each sortable item should contain:
data-flux="drag-order"on the sortable item- a form inside the sortable item
- an input named
order - a submit button
The order input uses a zero-based position. If the user drags an item to the first position, Flux submits order=0; if they drag it to the fourth position, Flux submits order=3.
<ul data-flux="update">
<li data-flux="drag-order">
<form method="post">
<input type="hidden" name="id" value="1" />
<label>
<span>Move to order</span>
<input type="number" name="order" />
<button name="do" value="move">Move</button>
</label>
</form>
<span>one</span>
</li>
</ul>
Without JavaScript, the user can type a zero-based number into the order input and press the button. With Flux running, those controls are hidden and replaced with a .drag-handle element inside the form, while the sortable host element is what actually moves in the DOM.
PHP example
The server should treat the submitted order as the source of truth:
$doAction = $_POST["do"] ?? null;
$id = filter_input(INPUT_POST, "id", FILTER_VALIDATE_INT);
$newOrder = filter_input(INPUT_POST, "order", FILTER_VALIDATE_INT);
if($doAction === "move" && isset($items[$id])) {
$index = array_search($id, $order, true);
unset($order[$index]);
$order = array_values($order);
$newOrder = max(0, min(count($items) - 1, $newOrder ?? 0));
array_splice($order, $newOrder, 0, [$id]);
$_SESSION["drag-order"] = $order;
header("Location: $_SERVER[SCRIPT_NAME]");
exit;
}
The full working version is in example/06-drag-order.php.
Page updates
Add an update target around the list:
<ul class="drag-drop" data-flux="update">
<!-- sortable items -->
</ul>
Flux moves the dragged item immediately for responsiveness, then submits the form. The returned HTML document refreshes the list from the server-rendered order.
Touch support
drag-order works with mouse, pen, and touch input. Touch dragging uses Pointer Events and tracks movement on the document while a drag is active, so the drag keeps working even when the finger moves away from the handle.
To keep users from firing repeated requests too quickly, we can add throttling with rate limiting.