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.