views:

386

answers:

2

Is there any way to have a jQuery sortable list show a placeholder for where the initial item was when you drag one out to sort?

i.e. when a user goes to move one of the LIs in my list, I want a rectangle outline to show where the one they're dragging came from.

A: 

If you know the place of the item being moved, you could have a sub-function that says that while the li is in a state of being dragged, the nth li has a dashed border.

I'm not sure I can right out the code off the top of my head, but basically, when the sortable function in in play, it moves the other list items up and down in the actual DOM, so, for example, if you set the css of the 3rd list item to have a dashed border, it wouldn't matter if the list items move around like crazy, because whichever one slides into that spot will be the 3rd list item and thus get the dashed border.

What you can't do is have the slot stay vacant while the user moves thing around (I don't believe) as then the list items aren't visually making room for the drop. Essentially as you drag the item, the DOM is being adjusted to slide up where the missing list item was...

Anthony
yeah, I tried that and it was a complete pain in the bum and not very reliable (appending stuff into the list on the start and stop events, that is)
Ed Woodcock
could you just set a class for that position so that the actual css handling is done somewhere else?
Anthony
Well, there's not actually an element in the original position, so no!
Ed Woodcock
+1  A: 

Short version: you can use sortable's start event handler to reveal the original item, and modify its appearance however you like. E.g.:

$(listOfStuff).sortable({
  start: function (e, ui) { 
    ui.item.show().addClass('original-placeholder');
  });

With the above, rather than your original item dissappearing when the user begins to drag, it will maintain its original position, and it will gain the 'original-placeholder'.

What's going on (as far as I can tell):

  • The start function is run when the user begins to drag.
  • When the user begins to drag, the original item isn't actually moved, it's just hidden. (ui.helper is a separate object that the user drags around). By calling ui.item.show(), you keep it revealed. (Well, technically it gets hidden and then immediately un-hidden, but I can't see any flicker.)
  • And then you can modify ui.item to your heart's content. In the above example I just added a class, but you could instead replace its internal HTML, etc.

I'm not particularly familiar with the internals, but I'd imagine others may be able to say more about how far one can push this technique.

brahn
Actually, the ui-helper is the original element unless you tell it otherwise, but I get the idea: I'd forgotten you could call start() with the ui parameter!
Ed Woodcock