For some very funny reason, I am unable to add multiple rows to a simple table using dataTables. Here is the thing,
I am adding 4 rows to an html table using datatable, specifically using the table.rows.add method (link).
Below is the simple html code for it with a sample row already present in it.
<table id="items-table" cellspacing="0" cellpadding="0">
<thead>
<tr>
<th>ID</th>
<th>Item Name</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>Sample Object</td>
</tr>
</tbody>
</table>
And here is the javascript code for it.
// create a dataTable
var itemsTable = $("#items-table").DataTable({
paging: false,
searching: false
});
// add data as rows. Make sure to call the ```.draw``` method.
itemsTable.rows.add([{
"id": "1",
"item": "Aardvark"
}, {
"id": "2",
"item": "Red Bull"
}, {
"id": "3",
"item": "Jack in the Box"
}, {
"id": "4",
"item": "Chair"
}]).draw();
Error says:
DataTable warning: table id=items-table -Requested unknown parameter
'0' for row 1, column 0. For more information see this error.
Using
DataTables 1.10.12
jQuery v3.1.1
What is going wrong here?
You need to specify the columns.
// create a dataTable
var itemsTable = $("#items-table").DataTable({
paging: false,
searching: false,
columns: [{data: 'id'}, {data: 'item'}]
});
One workaround is to put all the data in a regular table and then initialize it as a dataTable, instead of adding individual rows.
You may want to add "fnDrawCallback": function in your Datatable initialization if you are using underscore.js templates or similar, and use function to bind events to rows after the table is redrawn. Another possible way to do this would be to use, order.dt or search.dt or page.dt events provided by Datatables to do this. Possibly like:
function bind_feedback_behavior(){
$('table.program-status')
.on( 'order.dt', function () { enable_feedback_behavior(); } )
.on( 'search.dt', function () { enable_feedback_behavior(); } )
.on( 'page.dt', function () { enable_feedback_behavior(); } );
}
Related
After following the examples in https://datatables.net/reference/api/row().child(), I got this working in one project. Now im working on a new one, and everything was fine until the .show() came up with the error 'Property 'show()' does not exist on type Api' I followed the example and my imports seem to be up to date (this function has been in datatables since 1.10) so I dont know what could be wrong. This is in a typescript file, but as far as im aware everything still works like javascript. The function doesnt get upset if I do row.child().show(), but when I put the format function in it doesnt like that. Im still new to programming, so any help is super welcome :)
My HTML Table:
<table id="duckTable" class="display" cellspacing="0" width="80%">
<thead>
<tr>
<th>Select</th>
<th>Id</th>
<th>Name</th>
<th>Type</th>
</tr>
</thead>
</table>
My JS table:
var duckTable = $('#duckTable').DataTable({
"ajax": {
"url": "/Ducks/getDucks",
"type": "GET",
"dataSrc":""
},
paging: false,
ordering: false,
info: false,
"columns": [
{
className: 'dropdown',
orderable: false,
data: null,
defaultContent: '',
},
{ "data": "id" },
{ "data": "name" },
{ "data": "type" }
],
order: [[1, 'asc']],
"columnDefs": [
{
"render": function (data, type, row) {
var status = row.status;
var editButton = "<i name=" + row.id + " class=\"open-table\" style=\"padding-left:27px; padding-top:10px;\">↓</i> ";
if (status == null || status === 'D') {
return editButton;
} else {
return "";
}
},
"targets": 0
},
{"width": "10%", "targets":0},
]
});
My function:
function format(d) {
return ('<div>Still doesnt work</div>');
}
$('#duckTable tbody').on('click', 'td.dropdown', function () {
var tr = $(this).closest('tr');
var row = duckTable.row(tr);
if (row.child.isShown()) {
// This row is already open - close it
row.child.hide();
tr.removeClass('shown');
}
else {
// Open this row (the format() function would return the data to be shown)
row.child(format(row.data())).show();//this throws the error
tr.addClass('shown');
}
});
You mentioned that you're using TypeScript - the error that you're receiving sounds like a TypeScript compilation error.
This is because by the Typescript API definition that DataTables publishes, calling row.child(data) returns a union type of RowChildMethods<T> | Api<T>. Because the .show() method is not defined on the Api type, the Typescript compiler throws an error.
You should be able to get around this by splitting up your code into two statements:
row.child(format(row.data()));
row.show();
I have been trying to use lazy loading feature of datatable, but it's loading all the data at once, I'm not able to figure it out, what's going wrong.
var dataTable = dataTable || {};
dataTable = (function(namespace) {
var api = "https://jsonplaceholder.typicode.com/photos";
namespace.drawDataTable = function() {
try {
$('#table').DataTable({
"processing": true,
"serverSide": true,
"ajax": {
"url": api,
"dataSrc": ""
},
"columns": [{
"mData": "thumbnailUrl"
},
{
"mData": "albumId"
},
{
"mData": "id"
},
{
"mData": "title"
},
// { "mData": "url" }
],
"scrollY": 200,
"scroller": {
loadingIndicator: true
}
});
} catch (e) {
console.error(e.message);
}
}
return namespace;
}(dataTable = dataTable || {}));
$(document).ready(function() {
dataTable.drawDataTable()
})
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
<script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<table id="table">
<thead>
<tr>
<th>thumbnailUrl</th>
<th>albumId</th>
<th>id</th>
<th>title</th>
<!-- <th>url</th> -->
</tr>
</thead>
</table>
I have Tried these question already.
Lazy loading of table rows in Jquery datatables 1.10.10?
DataTables: Cannot read property 'length' of undefined
For loading data in chunks you need to write server-side script preferably using helper class SSP (ssp.class.php) available in DataTables distribution. That way data will be returned in chunks and consumed by front-end DataTables plug-in.
Your link https://jsonplaceholder.typicode.com/photos returns all records at once and DataTables front-end plug-in is unable to extract portion of it and still have to download the whole JSON file.
See Server-side processing for more details on what data needs to be returned in order for lazy loading to work.
Im currently trying to get Datatables and the Sparklines packages to work together kind of like below:
(This stuff is all written in R however)
I realize my issue is similar to this one... However, even after looking at some of the code and adapting it to my own, I was only able to render one or the other.. either the data from my server on the chart or the sparklines rendered with all data missing - never both together...
Here's the code
<table id="table_id" class="display">
<thead>
<tr>
<th>Table Name</th>
<th>Column Name</th>
<th>Rule</th>
<th>Current</th>
<th>Minimum</th>
<th>Maximun</th>
<th>Median</th>
<th>Mean</th>
<th>Sparkline</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
The HTML above and the JS below..
<script>
$SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
CURRENT_JOB = "{{ job_requested }}";
data = {{ data|safe}}
$(function() {
$('.js-typeahead').typeahead({
order: "asc",
source: {
groupName: {
// Array of Objects / Strings
data: {{jobs|safe}}
}
},
callback: {
onInit: function() {
$('#table_id').DataTable({
data:{{ data|safe}},
columns: [
{data: 'table_name'},
{data: 'col_name'},
{data: 'rule'},
{data: 'current'},
{data: 'min'},
{data: 'max'},
{data: 'median'},
{data: 'mean'},
],
"aoColumnDefs": [
{
"aTargets": [8],
"mRender": function (data, type, full) {
// since data is an array of values [1,2,3,4]
data = data.toString()
return '<span class="spark">' + data + '</span>'
}
}
],
"drawCallback": (oSettings) => {
console.log('callback')
$('.spark:not(:has(canvas))').sparkline('html', {
type: 'line',
minSpotColor: 'red',
maxSpotColor: 'green',
spotColor: false
});
}
});
}
}
});
});
Does anyone know what I am doing wrong? I need the columns: [] to point my JSON data to the right columns in the table but I also need to point one of the keys in my data object to the sparkline itself and then call the .sparkline()
Also my data object structure that im getting from the server kinda looks like this:
data = {
'table_name': cow,
'col_name' : cow_col,
'rule' : cow_col,
..etc, etc..
'data4spark: [1,2,3,4]
}
I really appreciate anyones feedback/help! Thanks! ❤️
Got it. This always happen every time I post a stackoverflow question, but I think i'd be stuck for a few days if I didn't post so..
Anyways, after reading the docs for a few hours -- The aoColumnDefs is a selector that can select an entire row in the table (if it's already created in the HTML) and that was wrong in my code above.. The aTargets is the parameter that you pass in the index of the column and the mRender is the call back function that you call right before it spits out whatever to the screen (it can modify the data beforehand for that specific col)
The diff is that I sent the code to the HTML using the columns and then I targeted the whole col to attatch the tags on and sent them over
Posting my code in hopes this saves someone time
$('#table_id').DataTable({
data:{{ data|safe}},
columns: [
{data: 'table_name'},
{data: 'col_name'},
{data: 'rule'},
{data: 'current'},
{data: 'min'},
{data: 'max'},
{data: 'median'},
{data: 'mean'},
{data: 'data'},
],
"aoColumnDefs": [
{
"aTargets": [8],
"mRender": function (data, type, full) {
// since data is an array of values [1,2,3,4]
return '<span class="spark">' + data + '</span>'
}
}
],
"drawCallback": (oSettings) => {
console.log('callback');
console.log($('.spark:not(:has(canvas))'))
$('.spark:not(:has(canvas))').sparkline('html', {
type: 'line',
minSpotColor: 'red',
maxSpotColor: 'green',
spotColor: false
});
}
});
How to populate a HTML5 table if you receive data in JSON format in jQuery Ajax and based on a specific column on a row color that row on a table (Using bootstrap 4 CSS styles?)
For example if i receive a dataset in JSON format like this:
{ "name":"John", "age":31, "city":"New York" };
The column city is New York so the table row should be colored green so the finished product should be like this:
<tr class="success">
<td>John</td>
<td>31</td>
<td>New York</td>
</tr>
I'm fairly new at jQuery can anyone guide me through how this can be achieved?
I'm using datatables library at the moment and what i have done is this:
function btnSearch_Click() {
$.ajax({
type: "POST",
url: "index.aspx/GetJobs",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(data) {
$('.table-sortable').dataTable({
destroy: true,
data: data,
columns: [
{
'd': 'Name'
},
{
'd': 'Age'
},
{
'd': 'City'
}]
});
}
});
};
Current HTML5 code is displayed bellow
<table class="table table-hover thead-inverse table-bordered table-sortable">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>City</th>
</tr>
</thead>
</table>
But when I click the button no data rows are returned by the browser (SQL Server does return data). Also as i mentioned i do not know how to accomplish that if specific data is returned in a row i need to color it...
Thank you for your help in advance...
Try this :
$('.table-sortable').dataTable({
destroy: true,
data: data,
columns: [
{ "data": "name" },
{ "data": "age" },
{ "data": "city" },
]
});
For using DataTables with ajax you usually have something like this:
$(document).ready(function () {
$('.table-sortable').dataTable({
"ajax": {
"url": "index.aspx/GetJobs",
"type": "POST"
},
"columns": [
{ "data": "name" },
{ "data": "age" },
{ "data": "city" },
]
});
});
As you can see the plugin itself has the functionality to use ajax.
So by default your returned data from server should contain a property data which contains the elements that are about to be rendered. You can actually specifiy this by using the dataSrc (reference) prop of ajax, you can set it to other name or remove it if you use plain collection:
"ajax": {
"url": "index.aspx/GetJobs",
"type": "POST"
"dataSrc": ""
},
This however does not change the data name in columns declaration so don't change it there.
You can read more about accepted formats and see examples in the official documentation.
Now regarding your question about row styling, there are a lot of callbacks and declarations which you can use to achieve that. I personally prefer using the createdRow callback (reference):
"createdRow": function( row, data, dataIndex ) {
if ( parseInt(data[1]) >= 18 ) {
$(row).addClass( 'success' );
}
}
So in this case if the age (second column based on 0-start-indexing) of the current row is above 18 it will add the desired class.
I hope this helps resolving your issues, if there still are problems you can try making a working jsfiddle so we can try debugging it in a "real-like" situation.
This is just to get an idea, i will add button click code
$("button").click(function(){
var obj = JSON.parse('[{ "name":"John", "age":30, "city":"New York"},{ "name":"John1", "age":30, "city":"New York"}]');
var t = $('#example');
for (i = 0; i < obj.length; i++) // iterate data from json
{
var name = obj[i].name;
var age = obj[i].age;
var classStyle = 'yellow'
if(name=='John')
{
classStyle = 'green';
}
$('#example').append('<tr style=background:'+classStyle+'><td>'+name+'</td><td>'+age+'</td></tr>');
}
});
i am working on pagination and i am using DataTables plugin ,
on some tables it's work but on some tables it gives error:
Uncaught TypeError: Cannot read property 'aDataSort' of undefined
my page script looks like:
$(document).ready(function() {
$('.datatable').dataTable( {
"scrollY": "200px",
"scrollCollapse": true,
"info": true,
"paging": true
} );
} );
//HTML code
<table class="table table-striped table-bordered datatable">
<thead>
<tr>
<th><?php echo lang('date_label')?></th>
<th><?php echo lang('paid_label')?></th>
<th><?php echo lang('comments_label');?></th>
</tr>
</thead>
<tbody>
<?php foreach ($payments as $pay): ?>
<tr>
<td><?php echo dateformat($pay['time_stamp'], TRUE);?></td>
<td><?php echo format_price($pay['amount']);?></td>
<td><?php echo $pay['note'];?></td>
</tr>
<?php endforeach?>
</tbody>
</table>
no idea how the problem comes ,i know this is very common error but i search and found nothing supporting my problem .
does anyone knows the solution ?
use something like the following in your code to disable sorting on DataTables (adapted from a project of mine which uses latest DataTables)
$(document).ready(function() {
$('.datatable').dataTable( {
'bSort': false,
'aoColumns': [
{ sWidth: "45%", bSearchable: false, bSortable: false },
{ sWidth: "45%", bSearchable: false, bSortable: false },
{ sWidth: "10%", bSearchable: false, bSortable: false }
],
"scrollY": "200px",
"scrollCollapse": true,
"info": true,
"paging": true
} );
} );
the aoColumns array describes the width of each column and its sortable properties, adjust as needed for your own table (number of) columns.
I faced same issue and later found a typing mistake in "targets" property under columnDefs. See below example,
WRONG code below,
{
"name": "firstName",
"target": [1],
"visible": false
}
Correction - missed 's' in targets :(
{
"name": "firstName",
"targets": [1],
"visible": false
}
Looks like this error occurs when something causing columns not getting initialized. I checked that event 'preInit.dt' is not fired in this case.
Hope this helps someone.
I ran into this issue using KnockoutJS because the columns were not yet defined when the javascript was trying to apply the DataTable to it. My approach with knockoutJS was to move my data-bind code into a knockout template and use the afterRender event to apply the DataTable to the table.
Here is a link to the knockoutJS docs for the template afterRender event.
Here is what my data-bind looks like:
<div data-bind="template: { name: 'schedule-table', data: $data, afterRender: setupDataTable }"></div>
There was one more trick. In the setupDataTable function, the table still isn't setup completely, (I was trying to get the fixedHeaders and the widths weren't setup yet). So I called setTimeout with a 0 millisecond delay to get the code to run on the first idle cycle.
Here is my setupDataTable:
function setupDataTable() {
setTimeout(function() {
$("#schedule").DataTable({fixedHeader: true});
}, 0);
}
Hope this helps somebody else looking for a knockoutJS solution and running into the same problem I ran into.
This error showed up for me, I believe because my "mData" and "sTitle" were undefined.
I had faced a similar issue when binding data table to a .Net GridView if grid view did not have any data and no header values defined then it was throwing:
Uncaught TypeError: Cannot read property 'aDataSort' of undefined
Below was the code for the same.
$("#GridView1").prepend($("<thead</thead>").append($("#GridView1").find("tr:first"))).dataTable();
$("#GridView1").dataTable();
I guess you are also facing the same issue, as you are also getting the table header names dynamically and if the result for it is null or empty then you are getting the mentioned error. Therefore, either you try giving column names when binding it to data table or make sure that your PHP code always returns some data for the table header.