Ruby on Rails: How to provide a list of items that can be dragged and dropped on each other
In this example, the drag-and-drop action results in submission of a form followed by rendering of a new page.
Preparation
No special preparation is required.
Database
It is assumed only that the database includes a table of items with identifiers.
Model
No modifications to models are required.
View
First, there is a JavaScript function to submit the form upon drag-and-drop:
<script>
function merge(draggable, droppable, event) {
document.merge.source.value = draggable.id;
document.merge.destination.value = droppable.id;
document.merge.submit();
}
</script>
Then, there is the form referencing the action to perform upon drag-and-drop. The form tag requires a name for the JavaScript function to work:
<% form_tag('/items/merge', :name => 'merge') do -%>
<input name="source" type="hidden">
<input name="destination" type="hidden">
<% end -%>
Each item that can be dragged and dropped on should be in a container with a unique id.
<% for item in @items %>
<div class=â€items†id=â€item_<%= item.id %>â€>
<%= item.name %>
</div>
<%= draggable_element(“item_†+ item.id.to_s, :revert => true) %>
<%= drop_receiving_element(“item_†+ item.id.to_s,
:onDrop => “function(drag, drop, e) { merge(drag, drop, e); }â€,
:hoverclass => “hoverâ€) %>
<% end %>
Controller
The controller includes an action that extracts the IDs of the dragged and dropped-on elements:
def merge
drag = Summary.find(params[:source].split('_')[1])
target = Summary.find(params[:destination].split('_')[1])
After performing the necessary actions, the method can render or redirect to the necessary page.