DataTables plug-in for jQuery changing data set? - javascript

I got a JQuery DataTable initialized with an empty dataset like this:
oTable = $('#accountsDefaultList').DataTable({
"bStateSave": true,
"aaData": accountsDefaultList(),
"aoColumns": [
{
"mData": "id",
"mRender": function (data) {
return '<button class="edit"><i class="fa fa-pencil-square-o"></i></button><button class="delete"><i class="fa fa-trash-o"></i></button>';
}
},
{ "mData": "title" }
],
"sDom": "<'dt-toolbar'<'col-xs-12 col-sm-6 hidden-xs'f><'col-sm-6 col-xs-12 hidden-xs'T<'toolbar'C>>r>" +
"Rt" +
"<'dt-toolbar-footer'<'col-sm-6 col-xs-12 hidden-xs'i><'col-xs-12 col-sm-6'p>>",
"autoWidth": false,
"oTableTools": {
"aButtons": [
"copy",
"xls",
{
"sExtends": "print",
"sMessage": "Generated by Procoor <i>(press Esc to close)</i>"
}
],
"sSwfPath": "javaScript/smartAdmin/plugin/datatables/swf/copy_csv_xls_pdf.swf"
},
"fnStateSave": function (oSettings, oData) {
localStorage.setItem('accountsDefaultList', JSON.stringify(oData));
},
"fnStateLoad": function (oSettings) {
return JSON.parse(localStorage.getItem('accountsDefaultList'));
},
"sPaginationType": "full_numbers",
"preDrawCallback": function () {
// Initialize the responsive datatables helper once.
if (!responsiveHelperaccountsDefaultList) {
responsiveHelperaccountsDefaultList = new ResponsiveDatatablesHelper($('#accountsDefaultList'), breakpointDefinition);
}
},
"rowCallback": function (nRow) {
responsiveHelperaccountsDefaultList.createExpandIcon(nRow);
},
"drawCallback": function (oSettings) {
responsiveHelperaccountsDefaultList.respond();
}
});
I use this to update the dataset with the new data but it doesn't seem to work at all
accountsDefaultList.subscribe(function () {
var data = accountsDefaultList();
oTable.data(data);
});
I tested whether the data is returned and every thing is fine except for the dataset update, i saw suggestions like using fnClearTable and fnAddData but those do not even exist in the datatables api.

Related

scraping a table with node.js doesnt show any result

I am trying to scrape data from here with Node.js, however, nothing is showing up when I run js file with node.js.
I tried using this code with the Wikipedia table and it worked.
When I am using the same function in the console, I do get the list I need, but it doesn't work in node.
Here is my code:
const request = require("request-promise");
const cheerio = require("cheerio");
async function main() {
const result = await request.get("https://www.electionguide.org/elections/?inst=&cont=&yr=2021");
const $ = cheerio.load(result);
$("#datagrid > tbody > tr > td > a").each((index, element) => {
console.log($(element).text());
});
}
main();
The data table body is filled by the javascript which run after loading the page, So Either you have to use selenium which loads the page first and then after certain timeout period, did the scraping or instead of scraping the data from html, try executing the javascript code in some way.
<script>
$('#datagrid').dataTable({
"aaSorting": [[ 3, "desc" ]],
"sPaginationType": "full_numbers",
"aLengthMenu": [10, 30, 50, 100, 200, 300],
"iDisplayLength": 30,
"bPaginate": true,
"bProcessing": true,
"bServerSide": true,
"sDom": '<"top"lfip>rt<"bottom"ip<"clear">',
"oSearch": {"sSearch": "2021"},
"sAjaxSource": '/ajax/election/',
"aoColumns": [
{ "bSortable": false, "sClass": "my_class",
"mRender": function ( data, type, full ) {
if(data.match(/<img/g))
{
return data;
}
else
{
return '<img src="'+data+'" style="width:30px;">';
}
}},
{ "sClass": "my_class",
"mRender": function ( data, type, full ) {
try {
if(data.match(/href/g))
return data;
} catch (err) {
return ''+data[0]+'';
}
}},
{ "bSortable": false,
"mRender": function ( data, type, full ) {
try {
if(data.match(/href/g))
return data;
} catch (err) {
if(data[0]==null)
{
return 'Referendum';
}
else
{
return ''+data[0]+'';
}
}
}},
{ "asSorting": [ "desc", "asc" ], "sClass": "my_class" },
{ "sClass": "my_class" }
]});
$('.dataTables_filter input').attr("placeholder", "Search Elections...");
</script>

How can I get the current page from within the $().DataTable() function?

I am working on an ASP.Net Core 2.1 MVC web application and I am using DataTables.Net datatable v1.10.19 for my lists.
I am creating master/detail drill downs where the first list (DataTable) of job activity provides a link on each row to the respective detail record. I am using pagination as well.
On the detail record, I want to have a breadcrumb that takes me back to the job activity list, and to the correct page number where I was at then I clicked on the detail link.
What I am doing is passing the query properties I am using on the Job Activity DataTable as query string parameters to the detail page so I can correctly populate the breadcrumb URL back to the job activity page.
I can see on the DataTable.Net API reference that I can use page.info() from the API to get the current page using something like this;
var table = $('#example').DataTable();
var info = table.page.info();
$('#tableInfo').html(
'Currently showing page '+(info.page+1)+' of '+info.pages+' pages.'
);
The problem is that I initialize the DataTable as part of the table setup and in the body of that function is where I am populating the link data for the detail page. I can't seem to do two .DataTable() calls, such as doing the call to the DataTable function to get the page info to initialize a pageNumber variable and then call the main .DataTable function as it causes the init of the main DataTable function to fail.
So, I need a way to get the current page from within the main .Datatable() function, if possible.
Here is my main DataTable() function;
jQuery(document).ready(function($) {
//Get the Timezone offset between local time and UTC
var d = new Date();
var m = d.getTimezoneOffset();
var minutesToOffset = parseInt(m, 10);
var companyId = $('#company-filter').val();
var siteId = $('#site-filter').val();
var aging = $('#aging-filter').val();
console.log(`companyId: [${companyId}], siteId: [${siteId}], Aging Days: [${aging}]`);
var table = $("#ssflist").DataTable({
//"dom": "lrtip",
"initComplete": function() {
$('#spinner1').hide();
$('#spinner2').hide();
},
"processing": true,
"serverSide": true,
"filter": true,
"orderMulti": false,
"order": [[6, "desc"]],
"ajax": {
"url": `/JobActivity/LoadData?companyId=${companyId}&siteId=${siteId}&agingDays=${aging}`,
"type": "POST",
"datatype": "json"
},
"oLanguage": {
"sSearch": "Filter"
},
"columnDefs": [
{ "orderable": false, "targets": [9, 10] },
{ "className": "text-center", "targets": [0, 9, 10] },
{
"targets": [6, 7],
"render": function(data) {
if (data != null) {
return moment(data).subtract(minutesToOffset, 'minutes').format('M/D/YYYY h:mm a');
}
}
}
],
"columns": [
{
"render": function(data, type, full, meta) {
if (full.ManifestStatus === 0) {
return '<i class="far fa-clock text-primary" title="Not started"></i>';
} else if (full.ManifestStatus === 1) {
return '<i class="fas fa-sync-alt text-primary" title="Pending"></i>';
} else if (full.ManifestStatus === 2) {
return '<i class="far fa-file-alt text-primary" title="Manifested"></i>';
} else if (full.ManifestStatus === 3) {
return '<i class="far fa-times-circle text-danger" title="Failed"></i>';
} else if (full.ManifestStatus === 4) {
return '<i class="far fa-check-circle text-primary" title="Uploaded"></i>';
} else return '<i class="far fa-question-circle text-primary" title="Unknown status"></i>';
},
"name": "ManifestStatus"
},
{
"render": function(data, type, full, meta) {
if (type === 'display' && data != null) {
data =
`<a href="/shippingServicesFileDetail/detail?id=${full.Id
}&returnTitle=Job Activity List&companyId=${companyId}&siteId=${siteId}&agingDays=${
aging}">
<button type="button" class="btn btn-outline-primary btn-sm">` +
data +
`</button></a>`;
}
return data;
},
"data": "Id",
"name": "Id"
},
{ "data": "TransactionId", "name": "TransactionId", "autoWidth": true, "defaultContent": "" },
{ "data": "CompanyName", "name": "CompanyName", "autoWidth": true, "defaultContent": "" },
{ "data": "SiteName", "name": "SiteName", "autoWidth": true, "defaultContent": "" },
{ "data": "ReferenceId", "name": "ReferenceId", "autoWidth": true, "defaultContent": "" },
{ "data": "CreatedDate", "name": "CreatedDate", "autoWidth": true, "defaultContent": "" },
{ "data": "UploadDate", "name": "UploadDate", "autoWidth": true, "defaultContent": "" },
{ "data": "Environment", "name": "Environment", "autoWidth": true, "defaultContent": "" },
{
"render": function(data, type, full, meta) {
data = full.H1RecordCount + full.D1RecordCount + full.C1RecordCount;
return data;
},
"name": "Count"
},
{
"render": function(data, type, full, meta) {
if (full.AzureFileUrl != null) {
data =
`<a href="/JobActivity/getManifest?azureFileUrl=${full.AzureFileUrl
}&azureFileName=${full.AzureFileName}">
<i class="far fa-arrow-alt-circle-down text-primary" title="Download Manifest"></a>`;
return data;
} else {
return null;
}
},
"name": "AzureFileUrl"
}
],
// From StackOverflow http://stackoverflow.com/a/33377633/1988326 - hides pagination if only 1 page
"preDrawCallback":
function(settings) {
var api = new $.fn.dataTable.Api(settings);
var pagination = $(this)
.closest('.dataTables_wrapper')
.find('.dataTables_paginate');
pagination.toggle(api.page.info().pages > 1);
},
});
$('#companyId').on('change',
function() {
table.search(this.text).draw();
});
});
The relevant link code is...
data = `<a href="/shippingServicesFileDetail/detail?id=${full.Id
}&returnTitle=Job Activity
List&companyId=${companyId}&siteId=${siteId}&agingDays=${
aging}">
I want to add a parameter to this link that represents the current page of the Datatable so that I can pass it back in the breadcrumb link on the detail page and have the datatable go to the correct page.
So I need a way to get the current page from within the
var table = $("#ssflist").DataTable({
function itself so I can pass that value in the link to the detail page.
Is there a property or method from within the Datatable function that will get me the current page value?

Send jquery datatable column value to Javascript Function (Asp.Net MVC)

I am binding data to jquery datatable in asp.net mvc, i have an anchor tag in one of the columns of the grid where i am accessing / reading row data and sending that data to a javascript function. The problem which i am facing is, i am able read and send row values to the function which are numbers for example ProductID="1" or CategoryID="3" , but if i try to send ProductName="Chai" to the javscript function i get an error in the console, and if i remove the parameter "ProductName" everything works fine and the javascript function also gets triggered.
Following the console error:
"Index:1 Uncaught ReferenceError: Chai is not defined
at HTMLAnchorElement.onclick (Index:1)"
Following is my Code:
var BindDataTable = function (response) {
$("#tbProduct").DataTable({
"aaData": response,
"aoColumns": [
{ "mData": "ProductID" },
{ "mData": "ProductName" },
{ "mData": "SupplierID" },
{ "mData": "SupplierName" },
{ "mData": "SupplierCountry" },
{ "mData": "CategoryID" },
{ "mData": "CategoryName" },
{ "mData": "QuantityPerUnit" },
{ "mData": "UnitPrice" },
{
"render": function (data, type, full, meta) {
return '<i class="glyphicon glyphicon-pencil"></i>'
}
}
],
"columnDefs": [
{
"targets": [2],
"visible": false,
"searchable": false
},
{
"targets": [5],
"visible": false,
"searchable": false
}
],
"aaSorting": []
});
}
var EditProduct = function (ProductID, SuppID, CatID,PrdName) {
var url = "/Product/EditProduct?ProductID=" + ProductID + "&SuppID=" + SuppID + "&CatID=" + CatID;
$("#myModalBodyDiv1").load(url, function () {
$("#myModal1").modal("show");
})
}
Error:
My suggestion is that instead of playing around with that much string concatenations, what you can do is pass single object to your function and then use the required fields which needs to be passed as ajax call:
"render": function (data, type, full, meta) {
return '<i class="glyphicon glyphicon-pencil"></i>'
}
and in your js function use it :
var EditProduct = function (product) {
var url = "/Product/EditProduct?ProductID=" + product.ProductID+ "&SuppID=" + product.SupplierID + "&CatID=" + productCategoryID + "&ProdName=" + product.Prooductname ;
You can use the following approach in for passing string arguments to a JavaScript function:
<a onclick="javaScriptFunction(#p.ID, '#p.FileName');">#p.FileName</a>
function javaScriptFunction(id, fileName) {
...
}

Format currencies when dataTable is created

var oTable = $('#table').dataTable({
"bJQueryUI": true,
"aaData": jsonList,
"bPaginate": true,
"aoColumns": [
{
"mDataProp": null,
"sClass": "control center",
"sDefaultContent": '<img src="http://i.imgur.com/SD7Dz.png">'
},
{ "mDataProp": "ente" },
{ "mDataProp": "cup" },
{ "mDataProp": "decreto" },
{ "mDataProp": "data" },
{ "mDataProp": "importoImpegno" }, //this is a currency
{ "mDataProp": "finanziato" }, //this is a currency
{ "mDataProp": "importoPagato" }, //this is a currency
{ "mDataProp": "importoInPagamento" } //this is a currency
],
"aoColumnDefs": [
{ "sClass": "currency", "aTargets": [ 5, 6, 7, 8 ]}
],
"oLanguage": {
"sInfo": "_TOTAL_ entries"
},
"aaSorting": [[1, 'asc']]
});
As you can see, I add .currency class only to the column where is a currency.
I need to format this currencies (3235 to 3.235,00 for example) and I have already the function to do that.
function currencyFormatIT(num) {
if(num != null && num != "") {
num = parseFloat(num);
num = num
.toFixed(2)
.replace(".", ",")
.replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1.");
}
else {
num = "";
}
return num;
}
I tried to use this method so:
$("table.myTable > tbody td.currency").each(function(){
$(this).html(currencyFormatIT($(this).html()));
$(this).css("text-align", "right");
});
But, it's work only with the row that appears in the first page of datatable:
From the second page to onwards not:
If I add this code:
$(document).on("click", "td.currency", function(){
alert($(this).html());
});
works for all td of all page!!
1) Why?
2) If I want to call the currencyFormatIT() function like callback function (maybe in the code where I create the dataTable .dataTable({.. how could I do?
You can use the fnDrawCallback function.
var oTable = $('#table').dataTable({
"fnDrawCallback": function (oSettings) {
// Format Currency here
}
}
You can check the documentation for more details about possible callback functions.

JS dataTable plugin: handling json format other than standard datatable format

I am new to Datatables and trying to figure out this problem.
I have a server which oupts json in certain format(see below).I cant change that on server side.
**Note: I am using link http://www.json-generator.com/j/cftupHnpbC?indent=4 to emulate my server response just for checking.
I have 2 problems
Since My json response doesn't have aaData: thing required by dataTable, I cant seem to initiliaze it.
Even if I add aaData: by hand to json just for checking, dataTable cant count total records.How I can set that manually ?Since I cant change output from server.
JSBIN LINK:
http://live.datatables.net/dasuyaf/1/edit
HTML:
<table id="example" class="display" width="100%">
<thead>
<tr>
<th> </th>
<th>ID</th>
<th>Name</th>
<th>Text</th>
</tr>
</thead>
<tbody></tbody>
</table>
JS:
$(document).ready( function () {
var table = $('#example').dataTable({
"sAjaxSource": "http://www.json-generator.com/j/cftupHnpbC?indent=4",
"aoColumns": [{
"mData": "id",
"mRender": function (data, type, full) {
return '<input type="checkbox" name="chkids[]" value="' + data + '">';
}
}, {
"mData": "id"
}, {
"mData": "name"
}, {
"mData": "text"
}],
"bProcessing": true,
"bServerSide": true,
"sServerMethod": "GET",
"aoColumnDefs": [{
'bSortable': false,
'aTargets': [0]
}],
"fnDrawCallback": function (oSettings) {
console.log(this.fnSettings().fnRecordsTotal());
}
});
});
My Server Output: (cant change this)
[
{
"text": "Some text",
"name": "somedata",
"id": "89"
},
{
"text": "Some text",
"name": "somedata",
"id": "2"
},
{
"text": "Some text",
"name": "somedata",
"id": "12"
}
]
I suppose you could just request that JSON yourself, make an object out of it and pass it to your dataTable.
var aaData;
var table;
$(document).ready( function () {
$.ajax({
url: 'http://www.json-generator.com/j/cftupHnpbC?indent=4'
}).done(function(data){
aaData = data;
table = $('#example').dataTable({
"aaData": aaData,
"aoColumns": [{
"mData": "id",
"mRender": function (data, type, full) {
return '<input type="checkbox" name="chkids[]" value="' + data + '">';
}
}, {
"mData": "id"
}, {
"mData": "name"
}, {
"mData": "text"
}],
"bProcessing": true,
"aoColumnDefs": [{
'bSortable': false,
'aTargets': [0]
}],
"fnDrawCallback": function (oSettings) {
console.log(this.fnSettings().fnRecordsTotal());
}
});
});
} );
I removed bServerSide - I don't think there's any way you can make use of it if you can't change your server response. Also removed sServerMethod.

Categories