Reputation: 601
I wanna make a sortable table and using jquery sortable I can either sort the rows in the tables or the cells in a row, but I can't move a cell between rows. How can I do that?
For example. In here: http://jsfiddle.net/dado_eyad/mKaFe/2/
I wanna move Second row: 2
to the place of First row: 1
Upvotes: 3
Views: 14391
Reputation: 121
Simple sortable table in javascript
<!DOCTYPE html>
<html >
<head>
<meta charset="UTF-8">
<title>Bootstrap extras: Table sort indicator</title>
<link rel='stylesheet prefetch' href='http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css'>
<link rel='stylesheet prefetch' href='https://maxcdn.bootstrapcdn.com/font-awesome/4.4.0/css/font-awesome.min.css'>
<style>
/* Table sort indicators */
th.sortable {
position: relative;
cursor: pointer;
}
th.sortable::after {
font-family: FontAwesome;
content: "\f0dc";
position: absolute;
right: 8px;
color: #999;
}
th.sortable.asc::after {
content: "\f0d8";
}
th.sortable.desc::after {
content: "\f0d7";
}
th.sortable:hover::after {
color: #333;
}
/* Heading styles */
h1.age-header {
margin-bottom: 0px;
padding-bottom: 0px;
}
h2.page-header {
margin-top: 0px;
padding-top: 0px;
line-height: 15px;
vertical-align: middle;
}
h1 > .divider:before,
h2 > .divider:before,
h3 > .divider:before,
h4 > .divider:before,
h5 > .divider:before,
h6 > .divider:before,
.h1 > .divider:before,
.h2 > .divider:before,
.h3 > .divider:before,
.h4 > .divider:before,
.h5 > .divider:before,
.h6 > .divider:before {
color: #777;
content: "\0223E\0020";
}
</style>
<script>
function sortTable(n) {
var table, rows, switching, i, x, y, shouldSwitch, dir, switchcount = 0;
table = document.getElementById("myTable");
switching = true;
//Set the sorting direction to ascending:
dir = "asc";
/*Make a loop that will continue until
no switching has been done:*/
while (switching) {
//start by saying: no switching is done:
switching = false;
rows = table.getElementsByTagName("TR");
/*Loop through all table rows (except the
first, which contains table headers):*/
for (i = 1; i < (rows.length - 1); i++) {
//start by saying there should be no switching:
shouldSwitch = false;
/*Get the two elements you want to compare,
one from current row and one from the next:*/
x = rows[i].getElementsByTagName("TD")[n];
y = rows[i + 1].getElementsByTagName("TD")[n];
/*check if the two rows should switch place,
based on the direction, asc or desc:*/
if (dir == "asc") {
if (x.innerHTML.toLowerCase() > y.innerHTML.toLowerCase()) {
//if so, mark as a switch and break the loop:
shouldSwitch= true;
break;
}
} else if (dir == "desc") {
if (x.innerHTML.toLowerCase() < y.innerHTML.toLowerCase()) {
//if so, mark as a switch and break the loop:
shouldSwitch= true;
break;
}
}
}
if (shouldSwitch) {
/*If a switch has been marked, make the switch
and mark that a switch has been done:*/
rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
switching = true;
//Each time a switch is done, increase this count by 1:
switchcount ++;
} else {
/*If no switching has been done AND the direction is "asc",
set the direction to "desc" and run the while loop again.*/
if (switchcount == 0 && dir == "asc") {
dir = "desc";
switching = true;
}
}
}
}
</script>
</head>
<body>
<table class="table table-bordered table-hover" id="myTable">
<thead>
<tr>
<th class="sortable" onclick="sortTable(0)">Field 1</th>
<th class="sortable" onclick="sortTable(1)">Field 2</th>
<th class="sortable" onclick="sortTable(2)">Field 2</th>
</tr>
</thead>
<tbody>
<tr><td>1</td><td>Data 1</td><td>Data 4</td></tr>
<tr><td>2</td><td>Data 2</td><td>Data 5</td></tr>
<tr><td>3</td><td>Data 3</td><td>Data 6</td></tr>
</tbody>
</table>
</div>
<script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>
<script src="js/index.js">
/*
Use this below code in a separated file(index.js)
var $sortable = $('.sortable');
$sortable.on('click', function(){
var $this = $(this);
var asc = $this.hasClass('asc');
var desc = $this.hasClass('desc');
$sortable.removeClass('asc').removeClass('desc');
if (desc || (!asc && !desc)) {
$this.addClass('asc');
} else {
$this.addClass('desc');
}
});
*/
</script>
</body>
</html>
Upvotes: -1
Reputation: 109
Just use connectWith parameter and some script:
$('table tr').sortable({
items: 'td',
connectWith:'table tr',
stop:function(e,prop){
var id = prop.item;
const colNum=3;
$('table tr').not(':last').each(function(){
var $this=$(this);
if($this.children().length<colNum)
{
$this.append($this.next().children(':first'));
}
else if($this.children().length>colNum)
{
$this.next().prepend($this.children(':last'));
}
});}
})
Upvotes: 3
Reputation: 141
I have a CSS trick to let sortable table cells
act like the sortable grid sample:
https://jqueryui.com/sortable/#display-grid
the Javascript part it as simple as:
$('table').sortable({
items: 'td',
});
The point is to make use of the CSS display
property.
when you drag a cell from row2 to row1,
row1 would become 4 cells, row2 only have 2 cells left,
and the width would be shrinked to match the table width.
If we use tr display: inline;
in the stylesheet,
let td
display as inline-block
.
The layout rendering would behave more like a list of inline-blocks.
Ignoring the restrictions of tr.
For a live demo, see the fiddle below:
http://jsfiddle.net/elin/4Q6Qn/
Upvotes: 6
Reputation: 87073
Wrap your < tr >
's in a < tbody >
and change the your code to:
$("table tbody tr").sortable({
items: 'td',
}).disableSelection();
You have to specify the container that contains the elements you want to be sortable not the actual elements.
$("table tbody").sortable({
items: 'tr',
}).disableSelection();
Upvotes: 4