jurchiks
jurchiks

Reputation: 1404

jquery sortable disable dragging/dropping between specific items

My situation is as follows - I'm sorting a table which may contain linked rows:

<table>
    <tr class="sortable-row"><td>row 1</td></tr>
    <tr class="sortable-row"><td>row 2</td></tr>
    <tr class="linked-to-previous"><td>row 3</td></tr>
    <tr class="sortable-row"><td>row 4</td></tr>
    <tr class="sortable-row"><td>row 5</td></tr>
</table>

What I need is to disallow dropping the dragged row between .linked-to-previous and the row before it.

I was thinking it could be done by something like this:

jQuery('table').sortable({
    items: '.sortable-row',
    axis: 'y',
    change: function (event, ui)
    {
        return (ui.placeholder.next('.file-version').length === 0);
    }
});

But unfortunately that doesn't work quite like needed - row 1 can't be dragged below row 3 because it cancels the sorting altogether.

Fiddle here: http://jsfiddle.net/qbhykh5e/3/

Suggestions?

Upvotes: 0

Views: 4679

Answers (1)

John R
John R

Reputation: 2801

Use start and stop method.

You can achieve both the requirements:

  1. disallow dropping the dragged row between .linked-to-previous and the row before it.
  2. row 1 can't be dragged below row 3 because it cancels the sorting altogether.

Code snippets:

jQuery('table').sortable({
    items: '.sortable-row',
    axis: 'y',
    start: function (event, ui) {
        $(ui.item).data("startindex", ui.item.index());
    },
    stop: function (event, ui)
    {        
        var startIndex = ui.item.data("startindex");
        if ((startIndex < 2 && $(ui.item).prevAll('.linked-to-previous').length>0) || (startIndex > 2 && $(ui.item).nextAll('.linked-to-previous').length>0))
                $(this).sortable('cancel');        
    }    
});

DEMO: FIDDLE

UPDATE:

Note: Check your HTML code snippets, there you have an additional </td> to every rows. Please change it that to </tr>.

Then try the below jQuery code snippets, which meets your requirement.

jQuery('table').sortable({
  items: '.sortable-row',
  axis: 'y',
  start: function(event, ui) {
    $(ui.item).data("startindex", ui.item.index());
    $(ui.item).data("linkedindex", $(ui.item).siblings('.linked-to-previous').index());
  },
  stop: function(event, ui) {
    var startIndex = ui.item.data("startindex"),
      linkedIndex = ui.item.data("linkedindex");
    if (startIndex > linkedIndex && $(ui.item).nextAll('.linked-to-previous').length > 0)
      $(this).sortable('cancel');
  }
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.10.4/jquery-ui.min.js"></script>
<table>
  <tr class="sortable-row">
    <td>row 1</td>
  </tr>
  <tr class="sortable-row">
    <td>row 2</td>
  </tr>
  <tr class="linked-to-previous">
    <td>row 3</td>
  </tr>
  <tr class="sortable-row">
    <td>row 4</td>
  </tr>
  <tr class="sortable-row">
    <td>row 5</td>
  </tr>
</table>

DEMO: FIDDLE

Latest Update:

Simply try this Code snippets

jQuery('table').sortable({
    items: '.sortable-row',
    axis: 'y',
    stop: function (event, ui) {
        if ($(ui.item).next('.linked-to-previous').length > 0)
            $(this).sortable('cancel');
    }
});

DEMO: UPDATED FIDDLE

Upvotes: 1

Related Questions