'jquery sortable remove next row before sorting
I have one table containing parent
and child
as below. parent
are sortable. When I try to sort any parent, I've to remove it's next child
and insert it after it's new position.
<table>
<tr class="parent"><td>Parent1</td></tr>
<tr class="child nosort"><td>Child1</td></tr>
<tr class="parent"><td>Parent2</td></tr>
<tr class="child nosort"><td>Child2</td></tr>
<tr class="parent"><td>Parent3</td></tr>
<tr class="child nosort"><td>Child3</td></tr>
</table>
So if I move Parent1 after Parent2, it will look:
<table>
<tr class="parent"><td>Parent2</td></tr>
<tr class="child nosort"><td>Child2</td></tr>
<tr class="parent"><td>Parent1</td></tr>
<tr class="child nosort"><td>Child1</td></tr>
<tr class="parent"><td>Parent3</td></tr>
<tr class="child nosort"><td>Child3</td></tr>
</table>
I've done with the insertion of child after sortupdate
but not able to figure out how to remove child row before sort. Below if code written on start
.
$('table').sortable({
items: 'tr:not(.nosort)',
start: function( event, ui ) {
// Removal code of child before sort
var objChild = ui.item.next();
if( objChild.hasClass('child') ) {
objChild.remove();
}
},
update: function( event, ui ) {
// insertion code of child
}
});
Solution 1:[1]
To answer exactly what you asked:
- Store the next elements into
data-*
attribute of each.parent
- On sortable
start
event use Use jQuery's.detach()
to store the child element(s) into data. - On sortable
stop
event use.after()
ti insert the previously detached elements
$('.parent').each(function(i, e) {
$(this).data('$next', $(this).nextUntil('.parent'));
});
$('table').sortable({
items: 'tr:not(.nosort)',
start: function( ev, ui ) {
$next = $(ui.item.data('$next')).detach();
},
stop: function(event, ui) {
ui.item.after($next);
}
});
<table>
<tr class="parent"><td>1 Parent</td></tr>
<tr class="child nosort"><td>1 Child</td></tr>
<tr class="parent"><td>2 Parent</td></tr>
<tr class="child nosort"><td>2 Child</td></tr>
<tr class="parent"><td>3 Parent</td></tr>
<tr class="child nosort"><td>3 Child</td></tr>
</table>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
but as you know, you could end up also having P2 P1 C1 C2 ... but that was not your question. Otherwise, to tackle with that problem the best would be to go back to the whiteboard, and simply place two <div>
s inside a <td>
Solution 2:[2]
I know this is an old thread, but I think my answer could help someone out. Here's an updated version of Roko C. Buljan's post.
In my version the children table rows are temporarily detached from the page using the .detach() in Jquery.
$('.parent').each(function() {
$(this).data('$children', $(this).nextUntil('.parent'));
});
var children = {};
$('table').sortable({
items: 'tr:not(.nosort)',
start: function() {
$('.parent').each(function() {
children[this.id] = $($(this).data('$children')).detach()
});
},
stop: function(event, ui) {
$('.parent').each(function() {
$(this).after(children[this.id]);
});
}
});
td {
padding: 1rem;
}
.red {
background-color: red;
}
.blue {
background-color: lightblue;
}
.green {
background-color: green;
}
<table style="padding: 1rem">
<tr class="parent red" id="one"><td>1 Parent</td></tr>
<tr class="child nosort red"><td>1 Child</td></tr>
<tr class="parent blue" id="two"><td>2 Parent</td></tr>
<tr class="child nosort blue"><td>2 Child</td></tr>
<tr class="parent green" id="three"><td>3 Parent</td></tr>
<tr class="child nosort green"><td>3 Child</td></tr>
<tr class="child nosort green"><td>3 Child</td></tr>
<tr class="child nosort green"><td>3 Child</td></tr>
</table>
<script src="https://code.jquery.com/jquery-3.1.0.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Roko C. Buljan |
Solution 2 |