Guides
Retool ListView Drag and Drop Reorder: What to Know
If you've tried to add Retool ListView drag and drop reorder functionality to your internal tool, you've likely hit the same wall as dozens of other developers in the Retool community. The ListView component and the Reorderable List component exist as two separate tools — and the gap between them causes real friction. This guide breaks down the current state, why it matters, and what you can do right now while Retool's team works toward a native fix.
What Is the Retool Reorderable List and Why Is It Falling Behind?
The Reorderable List component allows users to drag and drop items to change their order — a common UX pattern for priority queues, task lists, ranked selections, and more. The problem is that it's been left behind as Retool has invested heavily in the ListView component, which received a major upgrade in the form of a native grid layout option.
The result is a split ecosystem: you get modern features (grid mode, richer layout options) in ListView, but you lose drag-and-drop reordering. You get reordering in Reorderable List, but you lose the power and flexibility of ListView. Neither component does both — and that's the core issue developers are frustrated about.
Why Merging ListView and Reorderable List Makes Sense
The community case for merging these two components is straightforward. Here's what a unified component would unlock:
- Drag-and-drop reordering in list mode — letting users manually sort rows just like in
Reorderable List, but with the full power ofListViewinternals. - Drag-and-drop reordering in grid mode — a pattern used in Kanban-style tools, image galleries, and card-based dashboards.
- Stable state when adding rows programmatically — a known bug where adding a new item to a
ListViewvia JavaScript causes all other rows to lose their component state (input values, toggle states, etc.).
All three of these are solvable in a merged, redesigned component. Retool has confirmed that a ListView V2 (alongside a GridView V2) is planned, and reorderability is on the roadmap — though no release date has been set as of this writing.
The Programmatic Row Addition Bug Explained
One of the most painful issues tied to this gap is what happens when you try to add a row to a ListView dynamically. If you update the data source driving your ListView — say, by pushing a new object into a variable or re-running a query — the entire list re-renders. This wipes out any unsaved user input across all existing rows.
For example, if a user has filled in three rows of a form inside a ListView and then clicks "Add Row," all three rows reset. The workaround most developers use is to store component state externally in a variable or localStorage and sync on every change — but this is brittle and adds significant complexity to your app logic.
Current Workarounds for Drag-and-Drop Reordering in Retool
Until a native solution ships, here are the most practical approaches teams are using:
- Use
Reorderable Listwith a custom template: If your layout needs are simple, lean intoReorderable Listand style it as close to your design as possible. You loseListView's flexibility, but you gain working drag-and-drop. - Pair
ListViewwith manual up/down buttons: Add an "↑" and "↓" button inside eachListViewrow. On click, run a JavaScript transformer that reorders the underlying array and writes it back to avariable. Not as elegant as drag-and-drop, but fully functional and easy to implement. - Use a
Custom Componentwith a drag-and-drop library: Libraries likeSortableJSordnd-kitcan be embedded in a RetoolCustom Component. You pass your list data in viamodel, handle reorder events, and emit the new order back to Retool viamodelUpdate. This is the most powerful option but requires front-end development effort. - Preserve state on row addition with a
variable: Before adding a new row, use aScriptto read all current component values and save them to avariable. After the list re-renders, usesetInorsetValuecalls to restore each component's state. Tedious, but it works.
How to Implement Up/Down Reordering in a Retool ListView
If you want a no-custom-component solution, here's the step-by-step approach using manual sort buttons:
- Store your list data in a
variable(e.g.,listData) as an array of objects. - Set your
ListViewdata source to{{ listData.value }}. - Inside each
ListViewrow, add twoButtoncomponents: one for "Move Up" and one for "Move Down." - On the "Move Up" button's click handler, run a script: get the current
iindex fromlistItem.index, swap the element atiwithi - 1in a copy of the array, and calllistData.setValue(newArray). - Mirror this logic for "Move Down," swapping with
i + 1. - Disable the "Move Up" button when
{{ listItem.index === 0 }}and "Move Down" when the index equals the last item.
This pattern is stable, requires no external libraries, and works reliably across Retool versions.
What to Expect from Retool ListView V2
Retool's team has acknowledged the demand for a unified, more powerful ListView experience. The planned V2 is expected to address drag-and-drop reordering in both list and grid modes, as well as the component state loss issue when rows are added programmatically. Keep an eye on the Retool changelog and the original community thread for timeline updates. Until then, the workarounds above are your best path forward.
Ready to build?
We scope, design, and ship your Retool app — fast.