I am working on a project with KnockoutJS where we are pulling data in via Ajax calls and storing them in ko.observableArray. Currently, I have the following table in HTML:
`<table id="gpa">
<tbody data-bind="foreach: gpa">
<tr>
<td data-bind="text: LEVEL"></td>
<td data-bind="text: GPA_TYPE"></td>
<td data-bind="text: HOURS_ATTEMPTED"></td>
<td data-bind="text: HOURS_EARNED"></td>
<td data-bind="text: GPA"></td>
</tr>
</tbody>
</table>`
The JavaScript we have for generating the content via DataTables and the associated options is:
var gpaTarget = {
tableId: 'gpa',
options: {
paging: false,
ordering: false,
info: false,
searching: false,
processing: true,
autoWidth: true
},
columns: [
{ title: 'Level', data: 'LEVEL' },
{ title: 'GPA Type', data: 'GPA_TYPE' },
{ title: 'Hours Attempted', data: 'HOURS_ATTEMPTED' },
{ title: 'Hours Earned', data: 'HOURS_EARNED' },
{ title: 'GPA', data: 'GPA' },
]
}
//Add the DT target for Gpa data
dataTableTargets.push(gpaTarget);
//Initialize datatables for the appropriate DOM elements
if (dataTableTargets.length !== 0) {
$(document).ready(function () {
dataTableTargets.forEach(function (target) {
var table = target.tableId;
var options = target.options;
$('#' + table).DataTable(options);
});
Ideally, the idea from the DataTables.net site's description of how the Column.title feature works is that with a <thead> section, the title property for each column should render a simple column header (see https://datatables.net/reference/option/columns.title for reference.)
However, I have no column headers unless I explicitly declare them in my HTML. As their page says the <thead> element could be non-existent, or that the columns.title option can override the existing <thead> content, I am at a loss for why this is not working as expected.
Does anyone have any insight into what I might be doing incorrectly for this scenario? Any guidance is greatly appreciated.
Related
I have tried and searching lot of solution but not solve my problem, even at dataTables website. The problem is how to display nested array in json using DataTables? Fo example below, How if I just want to display l3_id: "1" data only.
I try to understand this link but not really understand. Example
There is no error at console and network tab.
DataTable not appear, including dataTables features such as search box, pagination. (The CDN/library has been imported)
JSON
{
"data": [
{
"project_id": "1",
"l1_task": [
{
"l1_id": "1",
"l2_task": [
{
"l2_id": "1",
"l3_task": [
{
"l3_id": "1",
"l3_name": "My name"
}
]
}
]
}
]
}
]
}
JS (I am applying HTML in JS)
"<table id='Layer3Table' class='table dt-responsive nowrap' style='width:100%'>"+
"<thead>"+
"<tr>"+
"<th class='text-center'>ID</th>"+
"<th class='text-center'>Activity Name</th>"+
"</tr>"+
"</thead>"+
"</table>"+
$('#Layer3Table').DataTable({
ajax: {
url: url_project_detail",
dataSrc : "data"
},
columns: [
{ data : "l1_task.0.l2_task.0.l3_task.0.l3_id" },
{ data : "l1_task.0.l2_task.0.l3_task.0.l3_name" },
],
});
Either define your table, including all tbody content in HTML, then use DataTables to enable the search etc features. If you do it this way you don't need to set the url or columns (although you can still set other options).
$('#Layer3Table').DataTable();
Or if you want to make use of the url and column features, create the basic table structure in HTML
<table id='Layer3Table' class='table dt-responsive nowrap' style='width:100%'>
<thead>
<tr>
<th class='text-center'>Project ID</th>
<th class='text-center'>Project Name</th>
<th class='text-center'>Project Description</th>
<th class='text-center'>Project Status</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
Then set up your DataTable separately in JavaScript.
$('#Layer3Table').DataTable( {
ajax: {
url: url_project_detail,
crossDomain : true,
type : "POST",
cache : false,
dataType : "json",
contentType: "application/json",
dataSrc : "data",
},
columns: [
{ data : "l3_id", "className": "text-center" },
{ data : "l3_name", "className": "text-center" },
{ data : "l3_description", "className": "text-center" },
{ data : "l3_status", "className": "text-center" }
],
});
What you appear to be doing is looping over your results and creating a DataTable for each of them, which is why it doesn't understand.
I have a pretty simple datatables object. I bind it to an array of objects, specify the data fields and it works. The problem is when I try to implement the CSV export. It always only wants to export the first row of the table. Any ideas?
Here's where my code stands at the moment. And to be sure, I've made sure that the button and select libraries are included but that has made no difference.
<table id="tblData" style="display:none;">
<thead>
<tr id="trDataTableHeader">
<th data-s-type="string">Name</th>
<th data-s-type="string">Address</th>
<th data-s-type="string">Phone</th>
<th data-s-type="string">Website</th>
<th data-s-type="string">Types</th>
</tr>
</thead>
</table>
...
table = $('#tblData').DataTable({
dom: 'rtB',
data: tableData,
columns: [
{ "data": "name" },
{ "data": "address" },
{
"data": "phone_number",
defaultContent: ""
},
{
"data": "website",
defaultContent: ""
},
{
"data": "types",
defaultContent: ""
},
],
buttons: [{
extend: "csv",
text: "Export",
exportOptions: {
modifier: { search: "none", selected: false}
}
}],
select: false,
lengthChange: false,
sort: false,
paging: false
});
After a lot of digging, I made an accidental discovery when I removed the column data type specifications. I got an error message that str.replace is not a function.
Turns out that the parseInt and parseFloat base functions were being overridden by another developer on that page and was causing a problem but DataTables was too graceful to tell me.
This is why you don't override base javascript functions unless you absolutely have to.
I don't have any experience in Knockout js but since I have to implement the functionality and struggling to get my hands on this scenario.
JSP files are fetching JSON data and it is passed to HTML template to create dynamic table.But i have to match particular values and give different styling to cells(Need to change color).
I explored and found out if Foreach is used and using if condition to apply css class can work but since table is getting created dynamically so finding it difficult to achieve it.
Providing the code below,i know angular way to do it but since its in knockout JS am struggling.
The above JSON data fetching dynamically from DB, if App Server is responding then map to “Yes” otherwise map to “No”, in additionally I have to set Yes mean green color, No means Red color.
I mapped responding values, it is working fine.
But I am not able to set colors for responding values (Yes means green and No means red color) in Knockout js. Can you please suggest me on this
<table id="monitorTable" summary="Table Data Test" aria-label="Table Data Test"
contextmenu="empty"
data-bind="ojComponent: {component: 'ojTable',
data: testdatasource,
columnsDefault: {sortable: 'disabled'},
columns: tableColumns,
scrollPolicy: scrollPolicy,
scrollPolicyOptions: scrollPolicyOptions}"></table>
Below here is the JSOn data fetched from server and passed to table
{
"label": "App Server",
"collection": [{
"responding": "Yes",
"appserver": "DEFAULT",
"className": "success",
"id": 1
}, {
"responding": "No",
"appserver": "ORACLEQUEUE",
"className": "failed",
"id": 2
}, {
"responding": "No",
"appserver": "SECONDARY",
"className": "failed",
"id": 3
}, {
"responding": "No",
"appserver": "TERTIARY",
"className": "failed",
"id": 4
}],
"serverTimestamp": "2017-07-07T03:51:21.949+0000",
"dataTimestamp": "2017-07-07T03:51:21.949+0000",
"tableColumns": [{
"headerText": "App Server",
"field": "appserver",
"sortable": "disabled"
}, {
"headerText": "Responding",
"field": "responding",
"sortable": "disabled",
"className": ""
}],
"scrollPolicy": "auto",
"scrollPolicyOptions": {
"fetchSize": "15",
"maxCount": "1000"
}
}
Here is the code which fetches data from server by JSP files
function addScalabilityMonitors() {
console.log("moved to scalability");
//App Scalability
monitors.addMonitorPoint(sts.apiBaseUrl() + 'ScalabilityAppServer1.jsp', 'oj-masonrylayout-tile-3x2', true, 15000, 'grid', 'scalability');
//Web Scalability
monitors.addMonitorPoint(sts.apiBaseUrl() + 'ScalabilityWebServer1.jsp', 'oj-masonrylayout-tile-3x2', true, 15000, 'grid', 'scalability');
//Response Time
monitors.addMonitorPoint(sts.apiBaseUrl() + 'Scalability.json', 'oj-masonrylayout-tile-3x2', true, 15000, 'gauge', 'scalability');
//Log files
monitors.addMonitorPoint(sts.apiBaseUrl() + 'logfile.json', 'oj-masonrylayout-tile-3x2', true, 15000, 'grid', 'scalability');
monitors.addMonitorPoint(sts.apiBaseUrl() + 'ProcessSchedules.json', 'oj-masonrylayout-tile-3x2', true, 15000, 'grid', 'scalability');
monitors.addMonitorPoint(sts.apiBaseUrl() + 'BusinessSequence.json', 'oj-masonrylayout-tile-3x2', true, 15000, 'grid', 'scalability');
monitors.addMonitorPoint(sts.apiBaseUrl() + 'DatabaseJobs.json', 'oj-masonrylayout-tile-3x2', true, 15000, 'grid', 'scalability');
//myPostProcessingLogic();
}
I tried to read the documentation for this, also tried various things but failed to implement.
Assuming you have access to the css this is pretty simple. If not, it's only slightly simple. Knockout has a databinding specifically for css. Here's an example.
function Server(data) {
var self = this;
self.Name = ko.observable(data.Name);
self.Status = ko.observable(data.Status);
}
function viewModel() {
var self = this;
self.Servers = ko.observableArray();
self.Load = function() {
self.Servers.push(new Server({
Name: "Email",
Status: "Online"
}));
self.Servers.push(new Server({
Name: "TPS Reports",
Status: "Offline"
}));
};
self.Load();
}
ko.applyBindings(new viewModel());
.red {
background-color: red;
}
.blue {
background-color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<h3> CSS Control</h3>
<table border=1>
<thead>
<tr>
<th> Server Name</th>
<th> Server Status</th>
</tr>
</thead>
<tbody data-bind="foreach: Servers">
<tr>
<td> <span data-bind="text: Name"> </span> </td>
<td data-bind="css: { red: Status() == 'Offline', blue: Status() == 'Online' } "> <span data-bind="text: Status"> </span> </td>
</tr>
</tbody>
</table>
<br><br><br><br>
<h3> No CSS Control</h3>
<table border=1>
<thead>
<tr>
<th> Server Name</th>
<th> Server Status</th>
</tr>
</thead>
<tbody data-bind="foreach: Servers">
<tr>
<td> <span data-bind="text: Name"> </span> </td>
<!-- Note: anything with a hyphen must be surrounded in single quotes -->
<td data-bind="style: { 'background-color': Status() == 'Online' ? 'green' : 'black' } "> <span data-bind="text: Status"> </span> </td>
</tr>
</tbody>
</table>
With your code, you would just make some additions to the data-binding in question.
I'm using datatable plugin and want to refresh table by ajax. I've read here to make my ajax return shows in table but it doesn't work. Here is my html code:
<button type="button" onclick="rld()">test</button>
<table id="sample_1">
<thead>
<tr>
<th> 1 </th>
<th> 2 </th>
<th> 3 </th>
</tr>
</thead>
</table>
My java function:
function rld(){
var table = $('#sample_1').DataTable( {
ajax: '<?php echo site_url('admin/test'); ?>',
deferRender: true,
columns: [
{ data: '1' },
{ data: '2' },
{ data: '3' }
],
rowId: 'extn',
select: true,
dom: 'Bfrtip',
buttons: [
{
text: 'Reload table',
action: function () {
table.ajax.reload();
}
}
]
} );
}
I can't get what the problem is. there in no alerts but in the console i get TypeError: f is undefined
and TypeError: c is undefined
Which i don't know why cause my json return is correct (checked in [JSONLint][3]).
Thanks in advance.
Thank you all for your attention :)
Found that i didn't call where the data goes when returned as json and the json field's name isn't equal to the column data field name. So make this adjustment:
function reload_table(){
var table = $('#sample_1').DataTable();
table.destroy();
var table = $('#sample_1').DataTable( {
"processing": true,
"dataType": 'json',
ajax: '<?php echo site_url('admin/relaod_table'); ?>',
deferRender: true,
columns: [
{ data: 'user_firstname' },
{ data: 'user_lastname' },
{ data: 'user_status' },
{ data: 'user_created_date' },
],
dom: 'Bfrtip',
buttons: [
{
text: 'Reload table',
action: function () {
table.ajax.reload();
}
}
]
} );
}
I want to create a dynamic table in bootstrap/jquery, similar to this one
In this example the data is hardcoded, so I thought about changing it with the data that comes from json. Additionally, each row in table has to have a hyperlink added, so my jquery code is as follows:
$('#dataTables-example').DataTable({
responsive: true
});
var data = '[{"number":"1","id":"2","price":"100.70","date":"2015-10-18 03:00:00","hidden":"21"},
{"number":"2","id":"2","price":"88.20","date":"2015-10-18 04:00:00","hidden":"22"}]';
json = JSON.parse(data);
$.each(json, function(i, v) {
$('<tr/>', {
html: [$('<td/>', {
text: v.number
}), $('<td/>', {
text: v.id
}), $('<td/>', {
text: v.price
}), $('<td/>', {
text: v.date
}), $('<td/>', {
html: [
$('<a/>', {
href: '#',
class: 'show-details',
text: 'show details',
data: { id: v.hidden },
click: function() {
var id = $(this).data('id');
console.log(id);
alert(id);
}
})
]
})]
}).appendTo('#dataTables-example tbody')
})
In my html I hardcoded the header of the table:
<div class="panel-body">
<div class="dataTable_wrapper">
<table class="table table-striped table-bordered table-hover" id="dataTables-example">
<thead>
<tr>
<th>number</th>
<th>id</th>
<th>price</th>
<th>date</th>
<th>show details</th>
<th style="display:none;">hidden identifier</th>
</tr>
</thead>
<tbody></tbody>
</table>
and later on thanks to my script I'm appending rows to the table. Simple as that.
However, as you can see in my fiddle:
http://jsfiddle.net/uo8rc5qL/6/
there is a problem, because since the data is not hardcoded, the table thinks there are no rows and displays the specific message there No data available in table. Also, when I click any column name to sort that data - content disappears, since the table thinks there's nothing to display after sorting...
How can I fix this situation?
This is because you're just adding the data to the table, not the underlying datatable source. The solution is to let datatables handle the loading of the data:
$('#dataTables-example').DataTable({
responsive: true,
"data": JSON.parse(datasrc),
"columns": [
{ data: 'number' },
{data: 'id'},
{data: 'price' },
{ data: "date" },
{
"data": "null",
"defaultContent": "<a>click</a>"
},
{ data: "hidden" }
]
});
Working example: JSFIDDLE
Always go through the API! Insert new rows using table.row.add([..]) instead of the jQuery $('<tr>', {... approach :
$.each(json, function(i, v) {
var row = table.row.add([v.number, v.id, v.price, v.date, '<a>show details</a>']);
table.cells({ row: row.index(), column: 4 }).nodes().to$().find('a')
.attr('href', '#')
.addClass('show-details')
.css('cursor', 'pointer')
.data('id', v.hidden)
.on('click', function() {
var id = $(this).data('id');
console.log(id);
alert(id);
})
table.draw();
})
forked fiddle -> http://jsfiddle.net/2wujw71x/1