Changing datatables.net structure dynamically - javascript

I'm using Datatables grid to show data from different datasources dynamically at server-side through AJAX.
These datasources have different column names and quantities.
Whats the better way to change datatables configuration on the fly.

Actually I am doing what you've suggested now to populate the table header dynamically which are returned from server response prior to initialise the data table using datatables grid.
The possible pseudo-code can be:
function initDataTable() {
var theadSetup = loadColumnSetup(); // load thead setup from server
// construct thead which are required to initialise a datatable
constructTableHead(theadSetup); // manipulate TH elements here
$('.dataTable').dataTable( {
aaData: dataSrc, // may also be retrieved from server
// other settings...
} );
}

Related

DataTables and columnDefs Rendering Data

I am using datatables 1.10.19 and I would like to filter data based on the contents of a table cell.
I am using the columnDefs option to alter the contents of the returned data.
I am using this php script to retrieve data.
My code is;
$('#example').DataTable({
processing : true,
serverSide : true,
ajax: url": '/server_processing.php',
columnDefs: [{
targets: 5, // row 6 in the html table
"render": function(data, type, row) {
if (row[5] == 0) {
data = 'rejected';
}
return data;
},
}]
});
This successfully displays a table, and rejected in column 6 when 0 is returned from the database. However datatables won't allows me to filter on the word rejected. I get No matching records found, however I can filter on the integer 0.
I thought datatables was supposed to filter what was displayed in the table?
Any advice is appreciated.
You have server-side processing mode enabled (serverSide: true) which means that you have to perform search yourself on the server-side. This could be done manually or by using helper classes/libraries.
For example, for PHP use SSP helper class (ssp.class.php) available in DataTables distribution. For Laravel framework, there is Laravel DataTables.
DataTables plug-in performs the search for you only in client-side processing mode.
Simple, all I had to do was set this;
serverSide: false

Use the same data for multiple tables with tabulator

I'm using jQuery and tabulator to create a fairly simple webpage showing the progress of various live events. I have three table elements on the page showing events in different states. Broadly speaking I have a table for events that are 'Live', 'Finished' and 'Upcoming'.
The tabulator code for each table looks a bit like this:
var eventTable = {
layout:"fitColumns",
columns:[
{title:"Event ID", field:"eventID"},
{title:"Event name", field:"eventName"},
{title:"Event status", field:"eventStatus"}
]
};
I can then generate and populate the tables using data retrieved from the server using an AJAX call:
$('#live-events-table').tabulator(eventTable);
$('#live-events-table').tabulator("setData", "/cgi-bin/getevents.py");
$('#live-events-table').tabulator("setFilter", "status", "in", ["intermission", "mid-event"]);
Then similar code for the finished and upcoming tables.
This creates three requests for getevents.py every time the page is updated. This is undesirable because the data is pulled from another API and I want to avoid sending multiple identical requests. Also, there's a (small) chance the data could change between requests.
Is there a way of using the same data to populate all three tables?
Learnt something today. Never heard of Tabulator. I've been using DataTables for this sort of advanced tabular layout in the form of a jQuery plugin. Tabulator looks promising. Will have to explore more in the future.
In the docs I see Tabulator - Set Table Data, lots of alternative options available to set the data.
Hope I am understanding the problem correctly.
My thoughts/flow for tacking this problem would be:
Assuming your doing this already: Prep server side (getevents.py) needs to return all 'Live', 'Finished' and 'Upcoming' rows in JSON together in 1 response. How do I make a JSON object with multiple arrays?.
Client side on doc ready(), makes a jQuery ajax call to fetch this data before 3 x tabulators are built/called.
You can use a loading indicator. So the client sees something is happening in the 3 x before replaced by jQuery tabulator once the data is returned and you built with tabulator.
In the ajax success callback function you can iterate over the returned json object (containing the 3 x eventTypes). You might have to JSON.parse() if you store it in a JavaScript variable to iterate over.
Now get your specific array of event types nested objects arrays/json.
Then call your tabulator creation methods using the setData pointing to each specific JavaScript array containing the relevant data.
Not sure if this falls under "premature optimization", but I would proceed as the problem itself is rather fun to solve, but you know the requirements/needs better than I.
Good luck.
I fixed this fairly simply, using suggestions from #RoryGS.
Define the table options in a variable, as before:
var eventTable = {
layout:"fitColumns",
columns:[
{title:"Event ID", field:"eventID"},
{title:"Event name", field:"eventName"},
{title:"Event status", field:"eventStatus"}
]
};
Then make a jQuery ajax call to fetch the data, and build the table(s) in the success option of the function:
$(function() {
$.ajax({
dataType: "json",
url: "/cgi-bin/getevents.py",
success: function(data, status){
$('#live-events-table').tabulator(eventTable);
$('#finished-events-table').tabulator(eventTable);
$('#live-events-table').tabulator("setData", data);
$('#live-events-table').tabulator("setFilter", "status", "in", ["intermission", "mid-event"]);
$('#finished-events-table').tabulator("setData", data);
$('#finished-events-table').tabulator("setFilter", "status", "in", ["post-event"]);
}
})})
It seems to be necessary to set the data individually for each table. I would like to specify the data in the constructor, but this doesn't seem to work. I will continue to try to refine this.
If you are getting the data from a URL you can pass it into the ajaxURL property in the table constructor and tabulator will make the request for you:
$("#example-table").tabulator({
ajaxURL:"/cgi-bin/getevents.pyw", //ajax URL
columns:[...] //define columns etc
});

How to update selected row in jquery data tables

Could you please tell me how to update the selected row in the jquery data tables?
In the below code I am trying to set a cell. Looks like it is set but not reflecting in the table.
var datatable = $('#table').DataTable();
datatable.row('.selected').cell(':eq(1)').data("1234");
alert(datatable.row('.selected').cell(':eq(1)').data());
Here able to alert the changed value but the same is not reflecting in the data table UI. Can you help me?
Official documentation
draw() Since: DataTables 1.10 Redraw the table.
Description When you perform an action such as adding or deleting a
row, changing the sorting, filtering or paging characteristics of the
table you'll want DataTables to update the display to reflect these
changes. This function is provided for that purpose.
your code is correct but datatables won't apply changes automatically, just call the draw() function.
datatable.row('.selected').cell(':eq(1)').data('123').draw();
You have to redraw the table using .draw() method as mentioned in the documentation of cell().data() method:
Note that when used as a setter, this method sets the data to apply to the table, storing it in the data source array or object for the row, but does not update the table's internal caches of the data (i.e. the search and order cache) until the draw() method is called.
datatable.row('.selected').cell(':eq(1)').data("1234").draw();
Check the documentation
For me, this was the solution:
var t = $('#myTable').DataTable();
t.cell('.selectedRow', ':eq(0)').data('something data');
t.cell('.selectedRow', ':eq(1)').data('something data');
t.cell('.selectedRow', ':eq(2)').data('something data');
t.draw();
// selectedRowIndex should be global
var selectedRowIndex = oTable.row(this).index();
// At the time of updating data in the selected row, do this
oTable.cell(selectedRowIndex,2).data("xyz"); // where 2 is the cell index
// it will reflect the data in the grid. :)
https://datatables.net/reference/api/row().index()

JQuery Datatable add new row,if the row is already present remove it and insert new row for that ID

Tried to remove rows using following method
table.DataTable().row().remove().draw();
I tried add using the following methods
1) table.dataTable().fnAddData(jsonObject);
2) table.DataTable().row.add(jsonObject).draw();
Add is not working, it is removing the old data and again after redraw it is showing old data in that row.
At first i am making ajax call and fetching data from database after that i need to add data in client side without making ajax call.
this.updateTableandMap=function(jsonObject){
if(jsonObject!=null){
var curTimeStamp=$('tr#'+jsonObject.trackeeId+'>td:eq(0)>a').attr('data-date-time-stamp');
if(jsonObject.dateAndTime>curTimeStamp){
$('#records-short').DataTable().row( $('#records-short>tbody>tr#'+jsonObject.trackeeId+'')).remove().draw();
// $('#records-short').DataTable().row.data(jsonObject).draw();
// $('#records-short').dataTable().fnAddData(jsonObject);
}else if(curTimeStamp==undefined){
$('#records-short').DataTable().row( $('#records-short>tbody>tr#'+jsonObject.trackeeId+'')).remove().draw();
$('#records-short>tbody>tr#'+jsonObject.trackeeId+'').remove();
$('#records-short').DataTable().row.add(jsonObject).draw();
}
}
};
you can try this way in your script
var row = $(this).closest('tr');
$('.dataTable').dataTable().fnDeleteRow(row);

How to bind Knockout.js to existing table grid?

I'm a newbie to Knockout.js. I implemented the Knockout.js by loading data from ajax source and use foreach loop to create a table of the data. The tutorial i followed is here
http://www.dotnetcurry.com/ShowArticle.aspx?ID=933
My issue here is, due to the nature of my application, I find that the first load is better served from the server side using a grid component and I only want Knockout.js to take care of "Add" row, "Update" a row and "delete" a row.
My question is,
1) how do I replace the "first" load and populate the lookupCollection :ko.observableArray() in the article with the default data in the html table?
2) Related to #1. If the first load, the table layout with data is constructed from the server side, then how do I bind "foreach" to the grid so "add" can be performed on lookupCollection?
Thanks and again, I'm a newbie, I must be missing some key concepts here.
One way would be to pass your initial data into your view model. Since you are using asp.net it would look something like this:
//Dump raw data into javascript variable
var data = #Html.Raw(ViewBag.Data);
function ViewModel(data) {
var self = this;
//Unpack raw data
self.lookupCollection = ko.observableArray(data.lookupCollection);
}
//initialize view model
var viewModel = new ViewModel(data);
ko.applyBindings(viewModel);

Categories

Resources