6
votes

I'm trying to write a helper function for jQueryUI to set an attribute on an item being dragged from a 'draggable' list to a 'sortable' list. (The reason I need to do this is that the latest version of jQueryUI deletes the 'id' attribute of dropped items)

However the attribute is not making it to the 'sortable' list. Am I doing something wrong in the helper function?

$("#draggable > li").draggable({
  connectToSortable: "#sortable",
  helper: function (event) {
    var id = $(this).attr('id');
    var ret = $(this).clone();
    ret.attr('dragId', id);
    console.log('dragId: ', ret.attr('dragId'));
    return ret();
  }
});

$( "#sortable" ).sortable({
    start: function( event, ui ) {
          console.log( "sortable start: dragId=", ui.item.attr( "dragId" ) );
    },
    stop: function( event, ui ) {
          console.log( "sortable stop: dragId=", ui.item.attr( "dragId" ) );
    }
});

When I drag an item from the draggable list to the sortable list, it prints in the console:

dragId: itemA
sortable start: dragId= undefined
sortable stop: dragId= undefined

I would expect it to print:

dragId: itemA
sortable start: dragId= itemA
sortable stop: dragId= itemA

Here is the full example (with HTML) on JsBin

2
If it's true that "the latest version of jQueryUI deletes the 'id' attribute of dropped items", then save the id off and re-apply it in the drop event handler of your droppable (you'll need to add a droppable). - Michael
Global variable, a child of the li, any number of places. - Michael
Note: the code is slightly different in the JsBin example. the last line of the helper function here has () after it, which should not be there. You want to return the ret object, not execute it and return the result. - RufusVS
The jsbin example generates an error and doesn't work. ($ not defined) - RufusVS

2 Answers

5
votes

You're setting the dragId attribute on the helper element, so you should use ui.helper instead of ui.item:

console.log("sortable start: dragId=", ui.helper.attr("dragId"));

EDIT: Nicola Peluchetti is right in his comment below: ui.helper will indeed be null during the stop event. Since you probably want to use the dragId attribute during that event, a workaround would be to copy the attribute during the start event, when both ui.helper and ui.item are available:

$("#sortable").sortable({
    start: function(event, ui) {
          ui.item.attr("dragId", ui.helper.attr("dragId"));
          console.log("sortable start: dragId=", ui.item.attr("dragId"));
    },
    stop: function(event, ui) {
          console.log("sortable stop: dragId=", ui.item.attr("dragId"));
    }
});
1
votes

The only way to keep the id i found is adding a droppable and this code:

    $( "#sortable" ).droppable({
        drop: function( event, ui ) {
            $(ui.draggable).attr('id', $(ui.helper).attr('id'));
        }
    });

There is a fiddle here (and there must be a better way of doing this) http://jsfiddle.net/MdZwB/1/