Very Quick points. I have seen very similar questions here on SO but they usually use the table ID or assume there is only one table. I have a page with many tables using the same template (no unique ID) and would like to know if when a particular data is loaded, if the rows are empty. I have tried :
jQuery: count number of rows in a table
Jquery- Get the value of first td in table and many others
//var row = $(this).closest('table tbody:tr:first');
// var row = $(this).closest('tr').children('td:first').text();
// var row = $(this).closest('tr').length;
// var row = $(this).closest('tr').children('td:first').length;
// var row = $(this).closest('table').find("tbody").children().length;
// var row = $(this).closest('table').children('tr:last').index() + 1;
// var row = $(this).closest('table').rowIndex;
// var row = $("tbody").has("tr");
// var row = $(this).closest('tbody').has("tr");
var row = $('#tbody').children('tr:first').length;
But cannot get the right answer.
Below is the table structure:
To get number of rows, use length or size()
//$(this) assumed as element inside table.
$(this).closest('table').find('tr').length
As you mentioned that you've many tables in a page. you need to let jQuery identify the table index from where you want to get tr length.
To get the specific table, use eq()
//To get TR length in 2nd table of a page
$('table:eq(1) tr').length
FYI,
For class selector, use $('.table:eq(1) tr').length
Use $(document).ready(function(){} to wrap your code, that will work when your page gets ready.
Looking at your table structure,
you can use
$(".dataTable tr").length
to get the count of rows in table
$("table").each(function(){
console.log($(this).find("tr").length));
})
This will log the count of trs in all tables that you have in your page
If you want to run some code when data gets loaded into any table you got to use Mutation Observer
MutationObserver = window.MutationObserver || window.WebKitMutationObserver;
//create observer
var observer = new MutationObserver(function(mutations, observer) {
console.log("Table Loaded");
//whatever you want to do when table is loaded
});
//set to observe childs ( options )
observer.observe(document.querySelector("table"), {
subtree: true,
childList:true,
attributes:true
});
I went through people's suggestions which mostly assumed (like the other pages) that there was an ID and that there was a single table on the page although the question mentioned it wasn't so.
Ended up using: var row = table_values.context.tBodies["0"].firstElementChild;
I got this by inspecting the tbody via dev tools.
Related
I have a paginated table. It's being built dynamically based on the results of a database call. I should write script code to affect all rows in table, I need to loop through all of the table rows, but it seems like I'm only able to iterate over the current rows that are visible on-screen, due to the pagination. So basically I may have 100 rows, but its only showing me rows 1-10 due to the pagination, which is expceted. But when i try to loop through the table contents, it only iterates through rows 1-10, instead of all 100 rows. Are there any API's or settings that will allow me to access all the rows?
$("#tableId").on("keyup", function () {
var value = $(this).val();
$("table tr").each(function (index) { //?
if (index !== 0) {
$row = $(this);
var id = $row.find("td:first").text();
// some script codes...
I am using an amazing tabulator plugin for managing tabular data, API is very clear and reliable but i cant do a very simple thing: get/select all rows on current page.
Custom row selection can look like this:
table.selectRow(table.getRows().filter(row => <<Custom Selection>>);
Where Custom selection has to respect the current page, but i dont get from where i can take it.
Maybe i am missing something?
There is no way to do that directly form Tabulator, but is should be fairly easy to do yourself with a bit of JavaScript.
First you want to get the rows that are visible on that page:
var pageRows = table.getRows(true);
Then you want to get the selected rows
var selectedRows = table.getSelectedRows();
then you want to find rows that exist in both arrays, these will be the selected rows on that page:
var rows = selectedRows.filter(value => -1 !== pageRows.indexOf(value));
Assuming the column name of your index is 'id' you can do the following:
var selectedData = table.getSelectedData();
jQuery.map(selectedData, function(value, index) {
console.log(value.id);
});
I'm receiving data from a websocket (live stream), and trying to put it into a table. I'm currently using the following code:
var table = document.getElementById("websocket-data");
function writeToScreen(message) {
var new_row = table.insertRow(0);
var cell1 = new_row.insertCell(0);
var cell2 = new_row.insertCell(1);
var obj = JSON.parse(message.data);
console.log(obj.value);
cell1.innerHTML = obj.id;
cell2.innerHTML = obj.value;
}
This works, and creates a new row for every JSON packet. The functionality that I am looking for is: On receipt of a JSON, if the id is not in the table, then create a row with id and value, however, if the id is already in the table, simply update the value. I've come across a few ways of doing this, but I'd like to know what the 'proper' way to do it is. I was thinking that perhaps the data should go into an array, and then the array should populate the table, but that would involve repopulating the entire table every time the array changed... I'm happy to use JQuery or similar if necessary.
You could use an array and repopulate the table every time like you said, and if the table will only ever be small then you may not run into issues with that.
One possible alternative of many is maintaining an object in the background with your ids as keys and then store the value and the table row index as values.
Something like:
var tableStore = {};
function recieveMessage(message) {
var obj = JSON.parse(message);
// if the id is not in the tableStore, add it!
if (tableStore[obj.id] === undefined) {
// insert new row into table and save the index into `newTableRowIndex`
// store a blank value (updated below) and the index in the table where it will be displayed
tableStore[obj.id] = {value: undefined, tableIndex: newTableRowIndex};
}
// if the value recieved is different than the stored value, update the row
if (obj.value !== tableStore[obj.id].value) {
tableStore[obj.id].value = obj.value; // store the new value
var row = getTableRow(tableStore[obj.id].tableIndex); // your own function to get the row based on index
// update the row to display the new information
}
}
This could be improved and made to be more organized but you should get the idea.
This way it would only update anything in the display if the new information recieved is different than the old information already stored.
This way should also perform better than using an array would if the table has the potential to get very large as you would not need to search through the entire array every time to see if the id is already stored or not. You would simply access the tableStore entry directly using the id.
I want to check whether the newly added row appear in first page or not. One way of doing it is get the index, but I wonder why it doesn't work, the index for me is not accurate at all.
function add_row(name, time_taken, attempts) {
var t = $('#dashboard').DataTable();
var node = '';
node = t.row.add([
'',
name,
time_taken,
attempts
]).draw().node();
$(node).attr('id', concatSpaces(name)).hide().fadeIn('slow');
var index = t.row('#' + concatSpaces(name)).index() // doesn't work
any thought? stuck for 2 hours long!
API method row().index() returns internal index which doesn't mean row position in the table based on current sorting column and method.
You need to use the code below instead to locate index of the row based on current sorting column and method:
var index = table.$('tr').index(node);
See this jsFiddle for code and demonstration.
I'm using the latest SlickGrid, with dataView.
I subscribe to the onActiveCellChanged event to react to a user selecting a row, and get the cell contents of the first column with:
grid.onActiveCellChanged.subscribe(function(e, args)
{
var cell = args.cell;
var row = args.row;
vat cell_contents = data[row][grid.getColumns()[0].field];
This works perfectly until I filter the table. Then args.row doesn't match the row in the data table.
How can I map the filtered row number (given in the event), to the actual row of the data that I want to read?
i.e. A filtered grid could yield one row of data, but could actually be row ten of the actual data table. I need to be able to read the data in the visible row selected.
After numerous attempts, I finally managed to do this. For anyone else that comes looking, what I did was:
grid.onActiveCellChanged.subscribe(function(e, args)
{
var cell = args.cell;
var row = args.row;
var row_data = dataView.getItem(row); // Read from dataView not the grid data
var cell_contents = row_data['id'];
This solution compensates for re-ordered columns as well as filtered rows.