I was tried to use these approaches:
Using api().draw(false) function, but it resets scroll offset.
Using api().ajax.reload(null, false). It resets scroll offset too.
Using dataTable._fnDraw() function. It doesn't work too. There is a bug when you are trying a bit scroll and after _fnDraw() call it scrolls to previous position. When you are scrolling a lot - it works well.
My TypeScript code:
var dataTableOptions = {
serverSide: true,
ordering: true,
searching: true,
columns: [
{ "data": "id" },
{ "data": "workflowId" },
{ "data": "discovery" },
{ "data": "title" },
{ "data": "createdBy" },
{ "data": "createDate" },
{ "data": "status" }
],
ajax: (data, callback, settings) => {
// server side service call
},
dom: 'rtiS',
scrollY: 400,
scroller: {
rowHeight: 35,
loadingIndicator: true
},
initComplete: function () {
forceRefresh = _.throttle(() => {
//this.api().ajax.reload(false);
this._fnDraw();
}, 1000);
setInterval(() => {
forceRefresh();
}, 5000);
}
}
I didn't find any other way as get scrollTop of scroller before ajax call and after table refresh (api().ajax.reload) assign it again. It's works for me.
Datatable automatically refresh (with updated data) on server side operation, no need to force refresh.
$(document).ready(function() {
var dataTableOptions = {
serverSide: true,
ordering: true,
searching: true,
columns: [
{ "data": "id" },
{ "data": "workflowId" },
{ "data": "discovery" },
{ "data": "title" },
{ "data": "createdBy" },
{ "data": "createDate" },
{ "data": "status" }
],
ajax: (data, callback, settings) => {
// server side service call
},
dom: "frtiS",
scrollY: 400,
deferRender: true,
scroller: {
rowHeight: 35,
loadingIndicator: true
}
}
A live example can be found here
Related
I have a datatable for report. When i tried to show my datas, My browser freezed or crashed. My js code on below
Reporting_Report.DTReport = $('#Report-ReportTable').DataTable({
"ajax": {
"url": "/Ajax/JsonProvider?Method=HardwareHostScreenUsage&GenericObject=true&Json=" + JSON.stringify(json),
"dataSrc": ""
},
"columns": [
{
"data": "BranchName",
"sTitle": "BranchName"
},
{
"data": "HardwareHostFriendlyName",
"sTitle": "Hardware Host Friendly Name"
},
{
"data": "HardwareHostScreenUsageScreenState",
"defaultContent": "N/A",
"sTitle": "Hardware Host Screen Name"
"render": function(data, type, full) {
if (data && Util.Check.IsInteger(data)) {
if (data == 1) {
return "Sorry Screen";
} else if (data == 2) {
return "Welcome Screen";
} else if (data == 3) {
return "Progress Screen";
}
}
}
},
{
"data": "HardwareHostScreenUsageSecondOnScreen",
"sTitle": "Elapsed Time On Hardware Host Screen"
},
{
"data": "HardwareHostScreenUsageRecordDate",
"sTitle": "Hardware Host Screen Usage Record Date"
"render": function (data, type, full) {
return Util.JsonDateToDate(data).format("dd.mm.yyyy HH:MM:ss");
}
}
],
"pageLength": 20,
"lengthMenu": [
[20, 50, 100, -1],
[20, 50, 100, "All"]
],
"info": false,
bFilter: true,
bInfo: false,
"order": [[0, "asc"]],
"scrollX": true,
dom: 'Bfrtip',
buttons: [
{
extend: 'copy'
},
{
extend: 'csv'
},
{
extend: 'excel'
},
{
extend: 'pdf',
title: "Detailed Ticket Report"
message: startDate + " " + startTime + " - " + endDate + " " + endTime + "\t" + datetime,
pageSize: 'LEGAL'
},
{
extend: 'print'
}
]
});
I have more than 100.000 datas.
I thinked maybe i can just get showing page datas and total data number(for manage page numbers) and when clicked another page number send new query and get new datas. But i couldn't find how to do that to.(maybe it cause some another problems (shorting, searching vs.)
Have you got any ideas and solutions.(or this problem has already a solution)
footnote:json has some filters for query(time, branch, etc.)
HardwareHostScreenUsage method gets my datas on c# side.
you can use client side data source also-
var mydata = [];
$('#example').DataTable({
data: data,
deferRender: true,
scrollY: 200,
scrollCollapse: true,
scroller: true
});
fetch all data at once from server and show it while scrolling the table .
You Need these library -
https://cdn.datatables.net/1.10.16/js/jquery.dataTables.min.js
https://cdn.datatables.net/scroller/1.4.3/js/dataTables.scroller.min.js
I am reloading my datatable on 10 second intervals. When a user clicks on a row, that row will highlight. But when the datatable reloads, the highlight is gone.
Here is the shortened code for my datable:
$(document).ready(function()
{
// set datatable
$('#example1').DataTable({
"ajax": {
"url": "api/process.php",
"type": "POST",
"dataSrc": ''
},
"columns": [
{ "data": "" },
{ "data": "column1" },
{ "data": "column2" },
{ "data": "column3" }
],
"iDisplayLength": 25,
"order": [[ 6, "desc" ]],
"scrollY": 600,
"scrollX": true,
"bDestroy": true,
"stateSave": true
});
// reload datatable every 30 seconds
setInterval(function()
{
var table = $('#example1').DataTable();
table.ajax.reload();
}, 30000);
// highlight row
$('#example1 tbody').on('click', 'tr', function()
{
$('#example1 tbody > tr').removeClass('selected');
$(this).addClass('selected');
});
});
All of the above works exactly how it's supposed to work. I just need to retain the row highlight after the datatable reloads.
Also, I attempted the answer from this post, but I scrapped it as the row no longer highlights.
Kindly update js file with below changes. Below code will save row clicked in global parameter and then focus the clicked row after ajax call.
var gblIndex = 0; //this will save row clicked index
function setFocus(){
$($('#example1 tbody > tr')[gblIndex]).addClass('selected');
}
$(document).ready(function()
{
// set datatable
$('#example1').DataTable({
"ajax": {
"url": "api/process.php",
"type": "POST",
"dataSrc": ''
},
"columns": [
{ "data": "" },
{ "data": "column1" },
{ "data": "column2" },
{ "data": "column3" }
],
"iDisplayLength": 25,
"order": [[ 6, "desc" ]],
"scrollY": 600,
"scrollX": true,
"bDestroy": true,
"stateSave": true
});
// reload datatable every 30 seconds
setInterval(function()
{
var table = $('#example1').DataTable();
table.ajax.reload();
setFocus(); // this will set focus/highlight row
}, 30000);
// highlight row
$('#example1 tbody').on('click', 'tr', function()
{
$('#example1 tbody > tr').removeClass('selected');
$(this).addClass('selected');
gblIndex = $(this).index(); // this will save the index clicked
});
});
You should review their actual selection documentation to manipulate this. This feature is already built in and setup so on ajax.reload() it will keep your selections.
You can apply classes/styling with their methods as well.
https://datatables.net/reference/option/#select
I'm using jQuery DataTables with ajax sourced data.
I have to keep the data up to date every 30 seconds without refreshing the page, and ajax.reload() is the function that I need.
I put ajax.reload() inside a setInterval function.
And all works right (if you stay on page 1). But when you surf the table on page 2 or 3, when setInterval is fired, it gets you back to the page 1.
So ...
Looking to docs at this url: http://datatables.net/reference/api/ajax.reload()
if I pass "false" as second parameter it holds the current paging position, and paging is not reset on reload. BINGO!
It works! BUT ... I have a new problem that a tried to solve the all day and now I'm stuck. That's why I post this question.
It keeps paging but if you are not on page 1, every time that ajax.reload() is fired, the page scrolls (jump directly) to the bottom.
It's very unfriendly, unreadable, unusable.
I don't know WHY the page scrolls to the end-bottom.
I post a link to my simple datatable js that I use on my page.
jsfiddle
var url = table.data('url');
var filterType = table.data('filtertype');
var options = {
"ajax": {
"url": url,
"type": "GET",
"data": function (d) {
d.contact_type = filterType
// this variable will set by server when page load. It should be "lead", "prospect", "client". Leave empty to get all.
}
},
"columns": [
{"data": "html_is_company"},
{"data": "name"},
{"data": "html_type_label"},
{"data": "created"},
{"data": "last_update"},
{"data": "html_actions"},
{"data": "tsu"},
{"data": "business_name"}
],
"bLengthChange": false,
"pageLength": 20,
"lengthMenu": [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]],
"columnDefs": [
{
"targets": [ 7 ],
"visible": false,
"searchable": true,
},
{
"targets": [ 6, 7 ],
"searchable": false,
"visible": false
},
{
"targets": [0, 5],
"searchable": false,
"orderable": false
},
{
"targets": [ 4 ],
"render": function (data, type, row) {
return moment(data, IN_DATE_TIME_FORMAT, 'it').fromNow();//.format(DATE_TIME_FORMAT);////;
}
},
{
// Sort column 4 (formatted date) by column 6 (hidden seconds)
"orderData":[ 6 ],
"targets": [ 4 ]
}],
"order": [[4, "desc"]],
"search": "_INPUT_",
"language": {
"sSearchPlaceholder": "Cerca...",
"paginate": {
"previous": '<i class="icon wb-chevron-left-mini"></i>',
"next": '<i class="icon wb-chevron-right-mini"></i>'
},
//"url": "//cdn.datatables.net/plug-ins/1.10.9/i18n/Italian.json"
}
};
var datatable = table.DataTable(options);
this.setDataTable(datatable);
setInterval(function(){
datatable.ajax.reload(null, false);
}, 5000);
My solution:
"fnDrawCallback": function(data) {
$(".paginate_button > a").on("focus", function() {
$(this).blur();
});
}
jacopo.galli's solution was very clunky when I implemented for my table, but it's probably because my code was a mess. The idea of adding blur() is great thou.
I rewrite his code a bit:
$(window).scroll(function(){
$(".paginate_button > a").blur();
});
The buttons on the pagination bar will be "unfocused" once the page scrolls.
So your final code should look like this:
var url = table.data('url');
var filterType = table.data('filtertype');
var options = {
"ajax": {
"url": url,
"type": "GET",
"data": function (d) {
d.contact_type = filterType
// this variable will set by server when page load. It should be "lead", "prospect", "client". Leave empty to get all.
}
},
"columns": [
{"data": "html_is_company"},
{"data": "name"},
{"data": "html_type_label"},
{"data": "created"},
{"data": "last_update"},
{"data": "html_actions"},
{"data": "tsu"},
{"data": "business_name"}
],
"bLengthChange": false,
"pageLength": 20,
"lengthMenu": [[10, 25, 50, 100, -1], [10, 25, 50, 100, "All"]],
"columnDefs": [
{
"targets": [ 7 ],
"visible": false,
"searchable": true,
},
{
"targets": [ 6, 7 ],
"searchable": false,
"visible": false
},
{
"targets": [0, 5],
"searchable": false,
"orderable": false
},
{
"targets": [ 4 ],
"render": function (data, type, row) {
return moment(data, IN_DATE_TIME_FORMAT, 'it').fromNow();//.format(DATE_TIME_FORMAT);////;
}
},
{
// Sort column 4 (formatted date) by column 6 (hidden seconds)
"orderData":[ 6 ],
"targets": [ 4 ]
}],
"order": [[4, "desc"]],
"search": "_INPUT_",
"language": {
"sSearchPlaceholder": "Cerca...",
"paginate": {
"previous": '<i class="icon wb-chevron-left-mini"></i>',
"next": '<i class="icon wb-chevron-right-mini"></i>'
},
//"url": "//cdn.datatables.net/plug-ins/1.10.9/i18n/Italian.json"
}
};
var datatable = table.DataTable(options);
this.setDataTable(datatable);
$(window).scroll(function(){
$(".paginate_button > a").blur();
});
setInterval(function(){
datatable.ajax.reload(null, false);
}, 5000);
I've found a solution that works for me.
The problem was the "focus" on DataTables pagination links.
When user clicks on a link page, it sets a focus on that link and when ajax.reload() is fired the browser gets you where the focused element is. My table is the last element of the page so the page scrolls to the bottom.
I got it when I clicked on another area of the page after clicked on page 2 link. The "jumping" problem was gone.
So, I solved firing a blur() when DataTables has complete its initialization and when ajax.reload() has finished (thanks to the first parameter that allows you to define a function).
In DataTables options I added this:
"initComplete": function(settings, json) {
$(".paginate_button > a").on("focus", function(){
$(this).blur();
});
},
and then, in setInterval:
setInterval(function(){
datatable.ajax.reload(function(){
$(".paginate_button > a").on("focus", function(){
$(this).blur();
});
}, false);
}, 30000);
Don't know if this is the "best solution" ... but it works and could helps someone.
I'm trying to get my javascript to use a dynamic value for "displayStart". I'm getting the data from a php script that returns JSON.
Here is my js:
balance.list = function () {
$('#balance').dataTable({
processing: true,
ajax: {
url: 'php/list.php',
dataSrc: 'data'
},
dom: '<"top"flp<"clear">>rt<"bottom"ip<"clear">>',
pageLength: 50,
autoWidth: false,
displayStart: '100',
columns: [
{
width: "10%",
data: "date"
}, {
width: "5%",
data: "checknum"
}, {
width: "75%",
data: "description"
}, {
width: "5%",
data: "debit"
}, {
width: "5%",
data: "credit"
}, {
width: "5%",
data: "balance"
}]
});
};
instead of
displayStart: '100',
I want it be something like:
displayStart: displayStart.displayStart,
But I'm setting the dataSrc to data, which is another branch of the JSON
And here is the JSON data:
{
"displayStart":"100",
"data": [
{
"date":"2015-03-27",
"checknum":null,
"description":null,
"debit":"50.00",
"credit":"0.00",
"balance":"500.00"
},
{
"date":"2015-03-28",
"checknum":null,
"description":null,
"debit":"0.00",
"credit":"250.00",
"balance":"750.00"
}
]
}
I've messed around with the ajax portion using a success/error function, but then it doesn't continue on to finish the table.
How do I set the value?
You can change the page after the data has been loaded by adding two event handlers after you DataTables initialization code as shown below.
// Handles DataTables AJAX request completion event
$('#balance').on('xhr.dt', function( e, settings, json){
$(this).data('is-loaded', true);
});
// Handles DataTables table draw event
$('#balance').on('draw.dt', function (){
if($(this).data('is-loaded')){
$(this).data('is-loaded', false);
var api = $(this).DataTable();
var json = api.ajax.json();
var page_start = json['displayStart'];
// Calculate page number
var page = Math.min(Math.max(0, Math.round(page_start / api.page.len())), api.page.info().pages);
// Set page
api.page(page).draw(false);
}
});
want to add HTML.actionlink to Jquery Datatable.
Am wokrking on this existing site made by someone else. For adding data they used Jquery Datatable with is new to me.
This is the data table:
this.oUserList = $('#UserList').dataTable({
"bLengthChange": false,
"bSort": true,
"bRetreive": true,
"bDestroy": true,
"aaSorting": [[0, "asc"]],
"bProcessing": true,
"sAjaxSource": "#Url.Action("GetUsers","Users")",
"sAjaxDataProp": "Result",
"aoColumns": [
{ "mDataProp": function(source, type, val) {
return source.FirstName + ' ' + source.LastName;
}, "bSortable": true },
{ (1st column },
{ 2ndcolumn},
{
3rd column
}, "bSortable": false },
{
4th column
}, "bSortable": false
},
{
5th column
}, "bSortable": false
},
Here is where i want to change it to action link
{ (6th)
"mDataProp": function (source, type, val) {
return M2.JsonDateToString(source.DateLastLogin);
}, "bSortable": false
},
My 6th column is a duplicate of the 5th, but what i need here is an action link, like this: (How i normally implement them):
<td>#Html.ActionLink("Edit Roles", "Edit", "Users", new { userName = "User\\" + u.UserName }, new { #class = "action" }) </td>
So what I want to no is how do you add a html actionLink to a Jquery Datatable.
Use the source json object to build the anchor:
this should work
{
"mDataProp": function (source, type, val) {
return 'Edit Roles'
}, "bSortable": false
},
Use this article www.codeproject.com/Articles/155422/jQuery-DataTables-and-ASP-NET-MVC-Integration-Part