I am using jQuery DataTables 1.10.3 to create a table with JSON data fetched from a web service. The data is linked to other elements on the page of my application such that when a user selects data points in one element, the DataTable should update and 'select' the complimentary rows (simply by adding the active class to the rows <tr> tag). Given the documentation, it would appear that this could be easily accomplished with something like this:
var table = $("#my-table").DataTable();
table.rows().each(function(r){
if (r.data().category == 'XYZ'){
r.node().to$().addClass("active");
}
});
But this does not work, since .rows() returns an array of row indexes instead of row objects. Instead, I have implemented this:
var table = $("#my-table").DataTable();
table.rows().indexes().each(function(i){
var r = table.row(i);
if (r.data().category == 'XYZ'){
r.node().to$().addClass("active");
}
});
This works, but is incredibly slow, considering the relatively small number of records in the table (~3 seconds for 3000 rows). Is there a better way to iterate through DataTable rows that I am missing? Or is it possible to make a row selection based on data values? Are the documents incorrect about .rows() returning API objects?
Well, I found an answer to my second question:
Or is it possible to make a row selection based on data values?
var table = $("#my-table").DataTable();
table.rows(function(idx, data, node){
return data.category == 'XYZ' ? true: false;
}).nodes().to$().addClass("active");
This run almost instantly, so it handles my use case, but I'd still like to know what the best way is to iterate through rows in a more general way.
Related
I am using tabulator package 4.3.0 to work on a webpage. The table generated by the package is going to be the control element of a few other plots. In order to achieve this, I have been adding a dataFiltered function when defining the table variable. But instead of getting the order of the rows in my data object, I want to figure a way to get the index of the rows in the filtered table.
Currently, I searched the manual a little bit and have written the code analogue to this:
dataFiltered: function(filters,rows){
console.log(rows[0]._row.data)
console.log(rows[0].getPosition(true));
}
But the getPosition always returned -1, which refers to that the row is not found in the filtered table. I also generated a demo to show the real situ when running the function. with this link: https://jsfiddle.net/Binny92/3kbn8zet/53/.
I would really appreciate it if someone could help me explain a little bit of how could I get the real index of the row in the filtered data so that I could update the plot accordingly and why I am always getting -1 when running the code written in this way.
In addition, I wonder whether there is a way to retrieve the data also when the user is sorting the table. It's a pity that code using the following strategy is not working in the way I am expecting since it is not reacting to the sort action and will not show the information when loading the page for the first time.
$('#trialTable').on('change',function(x){console.log("Yes")})
Thank you for your help in advance.
The reason this is happening is because the dataFiltered callback is triggered after the rows are filtered but before they have been laid out on the table, so they wont necessarily be ready by the time you call the getPosition function on them.
You might do better to use the renderComplete callback, which will also handle the scenario when the table is sorted, which would change the row positions.
You could then use the getRows function passing in the value "active" as the first augment return only rows that have passed the filter:
renderComplete: function(){
var rows = table.getRows("active");
console.log(rows[0].getPosition(true));
}
On a side note i notice you are trying to access the _row property to access the row data. By convention underscore properties are considered private in JavaScript and should not be accessed as it can result in unstable system behaviour.
Tabulator has an extensive set of functions on the Row Component to allow you to access anything you need. In the case of accessing a rows data, there is the getData function
var data = row.getData();
I'm only grouping rows on certain values. Here's a simplified version of my database structure:
item
id
parent ID (if this is a child item)
item type (parent, child, normal)
I am grouping when the row's item type is parent. I do a database fetch for that row's children, and populate them in the row group.
I end up with a very strange rendering problem:
(GIF) https://imgur.com/a/8lFVjLn
Here is my code. It's CoffeeScript but should be self-explanatory for those familiar with JS. "?" is just a null check, "#" is "this"
....
# the user has expanded a group, so check that we have parent node data...
else if params.parentNode? and params.parentNode.data? and params.parentNode.expanded
parentId = params.parentNode.data.id
if #editionsDict[parentId]?
params.successCallback(#editionsDict[parentId], #editionsDict[parentId].length)
else
# database call that returns a promise for when data is retrieved
#gridLoadChildren(parentId).then((res) =>
setTimeout(()=>
#editionsDict[parentId] = #childWorks
params.successCallback(#editionsDict[parentId], #editionsDict[parentId].length)
,0)
)
#childWorks is populated in #gridLoadChildren. Other than that, #gridLoadChildren is just a database call that performs a select using the parent ID.
Unfortunately for what I want I could not use Ag Grid's row grouping. The whole time I was working on this feature it felt like I was wrestling with the grid and trying to make it do something it wasn't meant to do. Thankfully, I came across the master/detail documentation and will be going that route instead. So far it works exactly for what I need (server side data and only expanding groups for certain rows).
I am deleting the records from a JqGrid using the Multiselect option.
grid.jqGrid('getGridParam', 'selarrrow')
Using the above line I get the user selected row ID's and make an ajax call, pass the ID's, and delete them from the DB.
My doubt is after deleting should I re form the grid or what is the best way to handle this?
Any working example would be great.
You could reload the grid, but that will cause another round-trip the server.
Alternatively, since you already have the ID's the rows you want to delete, you can just loop over that list and use delRowData method to delete them. This will provide a more responsive solution:
var rows = grid.jqGrid('getGridParam', 'selarrrow');
rows = rows.slice(); // Create a copy of the array since it
// is indirectly modified below
for (var i = 0; i < rows.length; i++){
jQuery('#mygrid').jqGrid('delRowData', rows[i]);
}
Due to the fact that as changes happen in the db the grid will be stale you may actually want to reload the grid in order to keep the data from going stale.
I have one table where I have 2 columns that get hidden by the dataTables api. From which when I delete a row from the table I need to pass the data in these columns via ajax so that it gets removed from the database as well..
I have been deleting my rows prior that didn't have data I need in them directly, without any issue. Now I need to change it up for this need and catch those values. Problem is no matter how I have tried to spin it one thing or another breaks.
delete_row = $(this).closest("tr").get(0);
This is what I used to catch the row I want to delete to pass it along when confirmation of deleting the row is made. And that works fine. Now I need to match the logic in creating two new vars that can be read if confirmation is made to pass through my ajax call.
Which I have tried:
var aPos = throttleTable.fnGetPosition($('td:eq(0)', delete_row));
var aData = throttleTable.fnGetData(aPos[0]);
Along with a few different spins to catch the column I want to get the data from. The above breaks the script altogether. The thought came from
var aPos = throttleTable.fnGetPosition(throttle_delete_row);
var aData = throttleTable.fnGetData(aPos[0]);
Which does work but only in returning every column in that row as a string. Which isn't desired. I would run a loop over it but that is problematic as a loop can be expensive, and also there is no distinct method of splitting the data up, as one of the values in one of the hidden columns is a CSV in it of itself. So the loop would be invalid for the need there as well if I split and delimited it by ,
So my ultimate question is, how can I break it down to get column specific?
Well, alright then. Apparently the problem was I was attempting to do to much when all I needed was the fnGetData() bit.
Turns out after playing around with whats actually going on and dumping it all into the console.log() I was able to sort out that all I truly needed to do was throttleTable.fnGetData(throttle_delete_row, 0) for sake of example, to get the hidden column(s) I seek.
$(document).ready(function() {
$('#example tbody td').click( function () {
// Get the position of the current data from the node
var aPos = oTable.fnGetPosition( this );
// Get the data array for this row
var aData = oTable.fnGetData( aPos[0] );
});
返回的都是数组,获取数组对应的下标就可以了!
Deletion operations seems to be the slowest in a YUI datatable. I have a datatable with > 300 rows. I need to delete selected rows. I tried removing the selected records from the recordset and then calling table.render() .. While this is okay, can it be made better?
Have a look at the API docs on the "deleteRow" method for the datatable widget (at http://developer.yahoo.com/yui/docs/YAHOO.widget.DataTable.html#method_deleteRow). This looks to me like this is what you'd want. Perhaps something like:
var selected = theDataTable.getSelectedRows();
var rset = theDataTable.getRecordSet();
for (var x = 0; x < selected.length; x++) {
theDataTable.deleteRow(rset.getRecordIndex(rset.getRecord(selected[x]))
}
No. This is slower than what I wrote.
Here you delete row by row and each time datatable has to be re-rendered.
What I did was remove these records from he recordset and then render the datable once.
Thats faster, but not a whole lot.
To my knowledge that is the fastest way to delete a row from a yui datatable. However, for your user's sake, unless 300 rows is necessary, you should consider pagination which is improved in version 2.6.0 (and has been split out and can now be used on other objects and not just DataTable).