KenC KenC - 8 months ago 34
Javascript Question

Modifying attributes of items as they are dropped into a sortable list with jQuery

I have a list of items that are draggable from a source list to a destination list contained in a form element. This works fine for one destination list as the 'name' attribute can be specified statically. However, I'm trying to figure out a way to support multiple destination lists, and I thought that if I could grab the ID from the destination list and dynamically add that as the name attribute to an input field as it is dropped into the sortable list, each list could be submitted as a separate array. My sortable, draggable, and droppable functions are working exactly the way I want them to with the following code:

Available Items
<ul id="avail">
<li><input type="hidden" name="options[]" value="1">Option 1</li>
<li><input type="hidden" name="options[]" value="2">Option 2</li>
<li><input type="hidden" name="options[]" value="3">Option 3</li>
<li><input type="hidden" name="options[]" value="4">Option 4</li>
<p class="clear"></p>
<form action="myForm.php" method="post" enctype="multipart/form-data">
<div style="float:left;">
List #1
<ul class="sortable" id="list1">
<div style="float:left;margin-left:5px;">
List #2
<ul class="sortable" id="list2">
<div class="clear"></div><br>

and the following jQuery:

$('#avail li').draggable({
connectToSortable: ".sortable",
helper: "clone",
opacity: 0.75,
var sortableIn;
receive: function(event, ui) {
sortableIn = 1;
over: function(event, ui) {
sortableIn = 1;
out: function(event, ui) {
sortableIn = 0;
beforeStop: function(event, ui) {
if (sortableIn == 0) {
greedy: true

You can see it in action on this fiddle. So to summarize based on this example, I'm trying to replace 'option[]' with either 'list1[]' or 'list2[]' as the name attribute of the input field when an option is dropped into one of these lists.

I assume I'd need to use something like attr('name',$(this).attr('id')) in the "receive" function or in a "drop" function but I'm not exactly sure where to put it and how to define the input field as the target of the attr() change instead of the containing

I changed the
function to
and added Twisty's second code snipped to it so that it now looks like:

update: function(event, ui) {
sortableIn = 1;
ui.item.find("input").attr("name", $(this).attr("id") + '[]');


I would put it in the data-list attribute of the destination element. For example:

<ul class="sortable" id="list1" data-list="1">

<ul class="sortable" id="list2" data-list="2">

Then in receive, you can assign the value you want to the name attribute:

ui.item.find("input").attr("name", "list" + $(this).data("list") + "[]");

Or you could read the ID:

ui.item.find("input").attr("name", $(this).attr("id") + "[]");

This will result in the received item of having either:


Since $(this) will be the sortable list the element was dragged to, it will get assigned the list number from the data.