Well I'm trying to implement the drag and drop sortable rows on table using Mootools. The issue that I'm banging my head all this morning and could figure out it's solution, here's the HTML table :
<table class="table table-bordered">
<tbody>
<tr class="item">
<td>Mark</td>
<td>Otto</td>
<td>#mdo</td>
</tr>
<tr class="item">
<td>Jacob</td>
<td>Thornton</td>
<td>#fat</td>
</tr>
<tr class="item">
<td>Larry</td>
<td>the Bird</td>
<td>#twitter</td>
</tr>
</tbody>
</table>
And here's the Javascipt:
window.addEvent('domready', function() {
/* create sortables */
var d = $$('tr');
var sb = new Sortables(d, {
/* set options */
clone:true,
revert: true,
/* initialization stuff here */
initialize: function() {
},
/* once an item is selected */
onStart: function(el) {
el.setStyle('background','#add8e6');
},
/* when a drag is complete */
onComplete: function(el) {
el.setStyle('background','#ddd');
//build a string of the order
}
});
});
And here's a jsfiddle . Much appreciated.
Here is the problem you are having as I understand it:
You wish to make the rows sortable? And your Fiddle example has all cells individually sortable.
Your issue is here:
var d = $$('tr');
var sb = new Sortables(d);
You have passed in all tr's as sortable lists. This means all td's are sortable.
You need to pass in:
var d = $('tbody');
var sb = new Sortables(d);
Mootools Docs state:
Arguments:
[1] list - (mixed) required, the list or lists that will become sortable.
A list in this case is any element (or array of elements) whose children will become sortable.
See here: Updated Fiddle
Related
This question already has answers here:
HTML table sortable by ROW instead of COLUMN with JavaScript?
(2 answers)
Closed 1 year ago.
I want to sort a tree table not by columns but rows, its header is on the left in the tree part.
My tree table looks like this
the tree table plugin I used.
And the code is something like this
<table>
<tr data-node-id="index">
<th>Index</th>
<td>...</td>
<td>...</td>
</tr>
<tr data-node-id="patient">
<th>Patient Characteristics</th>
</tr>
<tr data-node-id="name" data-node-pid="patient">
<th>Name</th>
<td>...</td>
<td>...</td>
</tr>
<tr data-node-id="DOB" data-node-pid="patient">
<th>DOB</th>
<td>...</td>
<td>...</td>
</tr>
<tr data-node-id="age" data-node-pid="patient">
...
There is no <thead> part, so many sorting methods not work well on this table. I'm new to javascript sort of things, and have no idea if this is easy to do. But I did not find methods for this situation online, so I try to ask for help.
First, access the table element:
var table = document.getElementById("table").children[0]; // You can just add an id to the table
Here is a function for sorting by row:
function sortRow(rowNum) { // rowNum is index of row: for example, name is 2
var answerArray = [];
for (i = 1; i < table.children[rowNum].children.length; i++) {
answerArray.push(table.children[rowNum].children[i].innerHTML);
}
return answerArray;
This function takes in the row number, and returns an array of all values in the row.
Let's say I have a Data Table like so:
<table id="history" class="display">
<thead>
<th>Player</th>
<th>Word</th>
<th>Value</th>
<th>Message</th>
</thead>
<tbody>
<tr>
<td>1</td>
<td>2</td>
<td>3</td>
<td>4</td>
</tr>
</tbody>
</table>
I have a function that receives a payload from the server and adds a row to the datatable with the relevant information
var history_data_table = $('#history').DataTable({
"pageLength": 5,
"searching": false,
"bLengthChange": false,
"language": {
"emptyTable": "Words that you discover will appear here."
}
});
function liveRecv(word_payload) {
history_data_table.row.add([word_payload.id_in_group,
word_payload.word,
word_payload.word_value,
word_payload.message]
).draw();
Naturally, this will add the row to the end of a paginated table. This table is a list of transactions in a game, and I want to present the most recent transactions to the user, such that every row that's added is added to the top of the data-table. What is the easiest way to achieve this?
You could try this method using jQuery
$('#history tr:first').after("<tr role="row"><td></td><td>add you own row</td></tr>");
or you could use DataTables inner function to access the array of rows
var history_data_table = $('#history').dataTable();
var DisplayMaster = history_data_table.fnSettings()['aiDisplayMaster'];
var tableapi = history_data_table.api();
var getlastrow = DisplayMaster.pop();
DisplayMaster.unshift(getlastrow);
tableapi.draw(false);
I'm trying to figure out a good way to have a table which has sub data where we can sort on the main table without altering the sub data. Here's a MWE.
<table id="my-table">
<tr>
<th>Name</th>
<th class="selectable">Num</th>
</tr>
<tr id="main-1" class="main">
<td>Main 1</td>
<td>1</td>
</tr>
<tr class="main-1 sub">
<td>Sub 1</td>
<td>3</td>
</tr>
<tr id="main-2" class="main">
<td>Main 2</td>
<td>2</td>
</tr>
<tr class="main-2 sub">
<td>Sub 2</td>
<td>4</td>
</tr>
</table>
So you can kind of see I have 4 rows altogether, 2 rows that are "main" rows and 2 that are "sub" rows which are associated to certain "main" rows as can be seen through their classes.
What I'm looking to do is sort the table in such a way that only the main rows get sorted and the sub rows travel with the main rows. So if I sort by the second column I would have Main 1 - Sub 1 - Main 2 - Sub 2 and if I reverse the sort I would have the order Main 2 - Sub 2 - Main 1 - Sub 1.
I tried using https://github.com/padolsey-archive/jquery.fn/tree/master/sortElements but this seems to do the entire table and I can't figure out how to make it move "groups" of rows together.
Any ideas?
(Note: the reason I'm doing the HTML structure as is, is because normally all ".sub" are hidden and when you click on ".main" it grabs the id and shows everything that has a class with that id. I'm open to changing the HTML structure if needed, and I don't mind either way if the sub elements get sorted too, I just prefer that they move with the main row)
This is the code I was using, but since it only does every line in the table, it's not really relevant:
$('.sub').toggle();
$('.main').on('click', function(e) {
e.preventDefault();
$('.' + $(this).attr('id')).toggle();
});
var table = $('#my-table');
$('th.selectable')
.wrapInner('<span title="sort this column"/>')
.each(function(){
var th = $(this),
thIndex = th.index(),
inverse = true;
th.click(function(){
table.find('td').filter(function(){
return $(this).index() === thIndex;
}).sortElements(function(a,b){
a_num = parseInt($.text([a]))
b_num = parseInt($.text([b]))
if (a_num == b_num)
return 0;
return a_num > b_num ?
inverse ? -1 : 1
: inverse ? 1 : -1;
}, function() {
// parentNode is the element we want to move
return this.parentNode;
});
inverse = !inverse;
});
});
I'm using Datatables and mark ids of my table with
<tr data-id='1'>
tags. I want to get the ids of selected rows. I tried this but it doesn't seem to work:
var $issueID = $(my_table.rows('.selected').nodes()).data('id');
$.each($issueID, function (value, index ) {
alert(value);
});
If I want to do it for a single row it works fine if I use
row().node()
but I can't get it right for many rows.
This should do the trick:
var selectedIds = [];
var my_table = $('#my_table').DataTable();
my_table.rows('.selected').every( function() {
selectedIds.push(this.data().id);
});
As Mike mentioned in a comment, notice that a capital D which is used to initialise the DataTable here. $().DataTable() returns a DataTables API instance, while $().dataTable() will also initialise a DataTable, but returns a jQuery object.
While searching for the same answer I came across this article. I modified the code in your question to find a working solution.
var inactiveRecord = $(my_table.rows('.selected').nodes());
$.each(inactiveRecord, function (idx, value) {
alert($(value).data('id'));
});
You should use a Class to do this in addition to your data-id.
JQUERY
$('.row').each( function() {
var value = $(this).attr('data-id');
alert(value);
})
HTML
<tr class="row" data-id="1">
<td></td>
</tr>
<tr class="row" data-id="2">
<td></td>
</tr>
<tr class="row" data-id="3">
<td></td>
</tr>
or without a Class you could just use
$('tr').each( function() {
var value = $(this).attr('data-id');
alert(value);
})
I recommend adding a class to tr so you don't accidentally get it mixed up with other rows that may not need to be counted.
Im trying too append data to a table with the tablesorter plugin (http://tablesorter.com)
Im using the following code:
<table id="sortme" border="1" style="width: 200px;">
<thead>
<tr>
<th>first name</th>
<th>last name</th>
<th>age</th>
</tr>
</thead>
<tbody>
<tr>
<td>will</td>
<td>smith</td>
<td>1</td>
</tr>
...................
</tbody>
</table>
Click me!
And:
$(document).ready(function() {
var i = 5;
$("#sortme").tablesorter({
sortList: [[2,0]]
});
$("#test").click(function() {
$("#sortme tbody").append('<tr><td>NEW</td><td>NEW</td><td>'+(i++)+'</td></tr>');
$("#sortme").trigger("update");
var s = [[2,0]];
$("#sortme").trigger("sorton",[s]);
return false;
});
});
Problem is the appended row stays at top, why?
See example: http://jsfiddle.net/jmU3Z/8/
In case anyone else stumbles across this.
By the time the "sorton" event is handled the DOM hasn't been assigned the table.config.parsers. The "sorton" event handling needs to be wrapped in a 1 millisecond timeout.
Replace the existing "sorton" bind in jquery.tablesorter.js (line ~803) with the following:
}).bind("sorton", function (e, list) {
var me = this;
setTimeout(function () {
$(this).trigger("sortStart");
config.sortList = list;
// update and store the sortlist
var sortList = config.sortList;
// update header count index
updateHeaderSortCount(me, sortList);
// set css for headers
setHeadersCss(me, $headers, sortList, sortCSS);
// sort the table and append it to the dom
appendToTable(me, multisort(me, sortList, cache));
}, 1);
You're problem is the [s]. You're sort parameter is already an array, just pass it the var not the var in an array.
$("#sortme").trigger("sorton",s);
Works for me, FF4.