I am using jQuery DataTable to display huge amount of data in a table. I am getting data page wise on Ajax request like this:
var pageNo = 1;
$('#propertyTable').dataTable( {
"processing": true,
"serverSide": true,
"ajax": "${contextPath}/admin/getNextPageData/"+pageNo+"/"+10,
"columns": [
{ "data": "propertyId" },
{ "data": "propertyname" },
{ "data": "propertyType" },
{ "data": "hotProperties" },
{ "data": "address" },
{ "data": "state" },
{ "data": "beds" },
{ "data": "city" },
{ "data": "zipCode" }
],
"fnDrawCallback": function () {
pageNo = this.fnPagingInfo().iPage+1;
alert(pageNo); // this alerts correct page
}
} );
and here is the spring controller:
#RequestMapping(value="/getNextPageData/{pageNo}/{propertyPerPage}")
public #ResponseBody PropertyDatatableDto getNextPageData(#PathVariable Integer pageNo, #PathVariable Integer propertyPerPage) {
System.out.println("called");
System.out.println(pageNo); // this always prints 1, what i need is current pageNo here
PropertyDatatableDto datatableDto = new PropertyDatatableDto();
//datatableDto.setDraw(1);
datatableDto.setRecordsTotal(100);
datatableDto.setRecordsFiltered(100);
datatableDto.setData(adminService.getAllPropertyList());
return datatableDto;
}
The problem is that when I change page in table it alerts correct pageNo on page (in JavaScript), but in spring controller I am always getting the initial value assigned to the variable pageNo and not the current page number.
How do I pass pageNo dynamically to spring controller? Any help is appreciated.
Edit:
I updated JavaScript like this:
var oSettings = $('#propertyTable').dataTable().fnSettings();
var currentPageIndex = Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength) + 1;
$('#propertyTable').dataTable({
"processing": true,
"serverSide": true,
"ajax": "${contextPath}/admin/getNextPageData/"+currentPageIndex+"/"+10,
"columns": [
{ "data": "propertyId" },
{ "data": "propertyname" },
{ "data": "propertyType" },
{ "data": "hotProperties" },
{ "data": "address" },
{ "data": "state" },
{ "data": "beds" },
{ "data": "city" },
{ "data": "zipCode" }
]
});
But it's giving me an error:
DataTables warning: table id=propertyTable - Cannot reinitialise DataTable.
DataTables already sends parameters start and length in the request that you can use to calculate page number, see Server-side processing.
If you still need to have the URL structure with the page number, you can use the code below:
"ajax": {
"data": function(){
var info = $('#propertyTable').DataTable().page.info();
$('#propertyTable').DataTable().ajax.url(
"${contextPath}/admin/getNextPageData/"+(info.page + 1)+"/"+10
);
}
},
"Untested"
Edit: Added "retrieve": true in options to retrieve the table instance (v1.10), checked if table exists. Changed fnSettings to setting() for datatable v1.10.
You can try to read from the datatable settings and then from settings read _iDisplayStart and _iDisplayLength , then calculate current page index as follows:
var currentPageIndex = 1;
//Is datatable already initialized?
if ( $.fn.DataTable.isDataTable( '#propertyTable' ) ) {
//Get the current settings and calculate current page index
var oSettings = $('#propertyTable').dataTable({"retrieve": true}).settings();
currentPageIndex = Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength) + 1;
}
then in ajax call pass currentPageIndex:
"ajax": "${contextPath}/admin/getNextPageData/"+currentPageIndex +"/"+10,
use this code gives a better result
fnRowCallback: function (nRow, aData, iDisplayIndex) {
var info = table.page.info();
if (
i < info.start ||
i >= info.end
) {
i = info.start;
}
$("td:first", nRow).html(i + 1);
i += 1;
return nRow;
},
Instead reload the datatable using $("YourDataTableId").DataTable().ajax.reload() , we can use below code to send current page number at server side to load data of that page number.
var currentDataTable = $("YourDataTableId").DataTable();
let currentPage = currentDataTable.page() >= 0 ? currentDataTable.page() : 0;
currentDataTable.page(currentPage).draw(false);
along with this code we have to use the below setting in datatable -
$("YourDataTableId").DataTable({
"stateSave": true, // to save the current page
});`
Related
I've been try to send current page number to server by overwrite a variable called pgno
here is my code :
function fill_datatable(status='',pgno='')
{
var pgno = 0;
table = $('.tb_scoin_available').DataTable({
"processing": true,
"serverSide": true,
"ordering" : false,
"infoCallback": function( settings, start, end, max, total, pre ) {
var api = this.api();
var pageInfo = api.page.info();
pgno = pageInfo.page+1;
return pgno;
},
"ajax":{
"url": base_url+'/adminPath/management_scoin/ajaxGetScoinAvailable',
"type": "POST",
"data":{ _token: csrf_token, status : status,pgno : pgno}
},
"columnDefs": [ { orderable: false} ],
"columns": [
{ "data": "no" },
{ "data": "created_at" },
{ "data": "serial_scoin" },
{ "data": "unit_scoin" },
{ "data": "unit_scoin_desc" },
{ "data": "unit_scoin_sc" },
{ "data": "unit_scoin_idr" },
],
});
}
when I try to alert on infoCallback :
alert(pgno) the variable already overwrited, but when I try to dump the request on backend the pgno POST give me null result like this :
Anyone can help me out ?
You can get the table page with the page() function, no need for the whole "page.info". It's better explained in Datatable's API: https://datatables.net/reference/api/page()
The method you're trying to access is only to get the information, not to set it. That is probably why it isn't working. Check their docs for better understanding of their API: https://datatables.net/reference/api/page.info()
EDIT:
You can get the current page through a simple calculation. Since you're using serverSide processing, you already have start and length. You just need to do start/length + 1 and you will get the current page number.
I have some code to display data using Datatables and it works fine. How do I get a value from column id?
I want to call window.open() to print the content of data on the datatables. I expect the data shown to be taken from array { "data": "id" } to passing on window.open(url)
$(document).ready(function() {
var table = $('#load_data').DataTable({
"ajax": {
"url": "data.php",
"dataSrc": ""
},
"columns": [{
"dataId": "id" // I want to get this value
}, {
"data": "tgl"
}, {
"data": "name"
}, {
"data": "company"
}, {
"data": "status"
}, {
"data": null,
"defaultContent": "<a href='javascript:void(0)' id='btn-print' class='btn btn-primary btn-sm'>print</a>",
}]
});
setInterval(function() {
table.ajax.reload(null, false);
}, 5000);
$('#load_data').on('click', 'tbody #btn-print', function() {
var getID = table.cell(this).data(); //try to catch id value variable
var url = "print.php?id=" + getID; //i want to pass getID variable to this variable
window.open(url, "_blank", "dialog=yes,minimizable=no,scrollbars=no,resizable=no,top=400,left=400,width=350,height=450");
console.log(getID);
});
});
There are many ways you can get data from the table.
cell.data()
columns.data()
rows.data()
Here is an example:
var ids = table.columns( 0 ).data(); //Get all Ids in to an array
I have an ASP.Net Core 2.1 API that serves as the backend data store for my web site. The API endpoints that return a list of records accepts the PageNumber and PageSize parameters and it then returns the specified page of records.
Now, in my ASP.Net 2.1 MVC website, I am trying to use a Datatables.net datatable to present the list of records to the user. I have everything working OK except I can't figure out how to get the page number from the datatable when a user clicks on a page number in the pagination control. In the examples I have looked at, the Controller has a loaddata action and it is retrieving values from the HttpContext.Request.Form but I can't see that there is an actual PageNumber property available.
Here is the javascript that is in my View;
<script>
jQuery(document).ready(function ($) {
var table = $("#companylist").DataTable({
"processing": true,
"serverSide": true,
"filter": true,
"orderMulti": false,
"ajax": {
"url": "/Companies/LoadData",
"type": "POST",
"datatype": "json"
},
"columnDefs": [
{ "orderable": false, "targets": 7 },
{ "className": "text-center", "targets": [6] },
{
"targets": [2],
"createdCell": function(td, cellData, rowData, row, col) {
if (cellData) {
$(td).html('<i class="far fa-check-circle text-primary""></i>');
} else {
$(td).html('<i class="far fa-times-circle text-danger""></i>');
}
}
}
],
"columns": [
{ "data": "Id", "name": "Id", "autoWidth": true },
{ "data": "CompanyName", "name": "CompanyName", "autoWidth": true },
{ "data": "PrimaryContactName", "name": "PrimaryContactName", "autoWidth": true },
{ "data": "PrimaryContactTitle", "name": "PrimaryContactTitle", "autoWidth": true },
{ "data": "PrimaryContactPhone", "name": "PrimaryContactPhone", "autoWidth": true },
{ "data": "PrimaryContactEmail", "name": "PrimaryContactEmail", "autoWidth": true },
{ "data": "IsEnabled", "name": "IsEnabled", "autoWidth": true },
{
"render": function (data, type, full, meta) { return `<i class="far fa-edit text-primary" title="Edit">`; }
}
],
// 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);
}
});
});
And here is my LoadData controller action;
public async Task<IActionResult> LoadData()
{
try
{
await SetCurrentUser();
ViewData["Role"] = _currentRole;
var draw = HttpContext.Request.Form["draw"].FirstOrDefault();
var start = Request.Form["start"].FirstOrDefault();
var length = Request.Form["length"].FirstOrDefault();
var sortColumn = Request.Form["columns[" + Request.Form["order[0][column]"].FirstOrDefault() + "][name]"].FirstOrDefault();
var sortColumnDirection = Request.Form["order[0][dir]"].FirstOrDefault();
var searchValue = Request.Form["search[value]"].FirstOrDefault();
var pageSize = length != null ? Convert.ToInt32(length) : 0;
var request = new CompaniesGetListRequest
{
OrderBy = SetOrderBy(sortColumn, sortColumnDirection),
Filter = SetFilter(searchValue),
PageNumber = ???, //<--- Where do I get tis value?
PageSize = pageSize,
};
var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
var companyData = await _client.GetCompanyListAsync(request, "api/companies/filtered", token);
var recordsTotal = companyData.Paging.TotalCount;
var data = companyData.Companies.ToList();
return Json(new
{
draw = draw,
recordsFiltered = companyData.Paging.TotalCount,
recordsTotal = companyData.Paging.TotalCount,
data = companyData.Companies.ToList()
});
}
catch (Exception ex)
{
const string message = "An exception has occurred trying to get the list of Company records.";
_logger.LogError(ex, message);
throw;
}
}
It looks like I only have the Start value, which is the next record number in the list and the length, which is the page size. I need to determine the PageNumber as I do not want to return the entire data set from the backend data store dues to the size of the data set. I just want to grab one page at a time.
This is probably a simple issue but I am just not having any luck finding an answer.
I got this answer from Datatables forum.
var page = Math.ceil(oSettings._iDisplayStart / oSettings._iDisplayLength) + 1;
Hope this helps.
PS: Link to Forum
On document.ready, my Datatable loads accordingly.
What I need to do is build a feature that reloads the Datatable if the user conducts a search.
So the Datatable loads like this:
$(document).ready(function()
{
$('#searchSubmit').on('click', function() // used for searching
{
var searchbooking = $('#searchbooking').val();
var searchquote = $('#searchquote').val();
var searchtli = $('#searchtli').val();
if(searchbooking == "" && searchquote == "" && searchtli == "")
{
$('.message').text('You did not enter any search criteria.');
return false; // making sure they enter something
}
else
{
$.post('api/searchAll.php', {searchbooking:searchbooking, searchquote:searchquote, searchtli:searchtli}, function(data)
{
// what do i do here???
// how do I get the return results to load
});
}
});
// if the user does not enter any search parameters, load everything
$('#example1').DataTable({
"ajax": {
"url": "api/displayQnams.php",
"type": "POST",
"dataSrc": ''
},
"columns": [
{ "data": "" },
{ "data": "column1" },
{ "data": "column2" },
{ "data": "column3" }
],
"iDisplayLength": 25,
"order": [[ 6, "desc" ]],
// and so on
});
});
As you will see in the above code, when the document is ready, if the user does not conduct a search, I load all of the data from the process called 'displayQnams.php'.
But if the user conducts a search, the parameters are sent to another process called 'qnamsSearch.php'.
How do I reload the datatable with the search results from 'qnamsSearch.php'?
I tried to create a variable from inside the post:
var dataUrl = data;
And I tried to call that variable in the ajax call:
"ajax": {
"url": dataUrl,
"type": "POST",
"dataSrc": ''
}
But the Datatable will not display anything and there are no console errors.
How can I make this work?
You can try using this.
After user click search button, below is the flow:
Clear datatables - datatables clear()
Add new data to the table - datatables rows.add()
Adjust column size (optional) - datatables adjust.columns()
Redraw back datatable with new data - datatables draw()
$(document).ready(function(){
var datatable = $('#example1').DataTable({
"ajax": {
"url": "api/displayQnams.php",
"type": "POST",
"dataSrc": ''
},
"columns": [
{ "data": "" },
{ "data": "column1" },
{ "data": "column2" },
{ "data": "column3" }
],
"iDisplayLength": 25,
"order": [[ 6, "desc" ]]
});
$('#searchSubmit').on('click', function(){
var searchbooking = $('#searchbooking').val();
var searchquote = $('#searchquote').val();
var searchtli = $('#searchtli').val();
if(searchbooking == "" && searchquote == "" && searchtli == ""){
$('.message').text('You did not enter any search criteria.');
return false; // making sure they enter something
} else {
$.post(
'api/searchAll.php',
{ searchbooking:searchbooking, searchquote:searchquote, searchtli:searchtli },
function(data) {
var newData = data;
datatable.clear().draw();
datatable.rows.add(newData); // Add new data
datatable.columns.adjust().draw(); // Redraw the DataTable
});
}
});
});
I have a set of JSON data that are displayed using datatables. In one of the columns, I add a button and a text box only if the value in that column and another column meets a certain condition. this is the bit of code I used to do this:
$(document).ready(function (){
var alertTable = $('#alert-table').DataTable({
"jQueryUI": true,
"order": [ 3, 'desc' ],
"columns": [
{ "data": "source", "visible": false },
{ "data": "host" },
{ "data": "priority" },
{ "data": "ack", "render": function( data, type, row ) {
if (row.ack == "0" && row.priority > "2") {
return '<form><input class="ackname" type="text" value="Enter your name"><input class="ackbutton" type="button" value="Ack Alert" onclick="<get all items for that row and POST to a URL>"></form>';
}
return data;
}
},
],
"language": {
"emptyTable": "No Alerts Available in Table"
}
});
});
This works fine by adding a button and text in the cell. What I am looking to achieve is, when any of the button is been clicked, it should POST all the values for that row including what is typed in the text box to a URL which has another function that would extract those details and update the database and send back the refreshed data. I am new to datatables and jquery, any guide would be highly appreciated.
Have made some changes to the code, instead of form you can use div.
$(document).ready(function (){
var alertTable = $('#alert-table').DataTable({
"jQueryUI": true,
"order": [ 3, 'desc' ],
"columns": [
{ "data": "source", "visible": false },
{ "data": "host" },
{ "data": "priority" },
{ "data": "ack", "render": function( data, type, row ) {
if (row.ack == "0" && row.priority > "2") {
return '<div><input class="ackname" type="text" value="Enter your name"><input class="ackbutton" type="button" value="Ack Alert"></div>';
}
return data;
}
},
],
"language": {
"emptyTable": "No Alerts Available in Table"
}
});
$(document).on("click",".ackbutton",function() {
var currentIndex = $(this).parent().parent().index();
var rowData = alertTable.row( index ).data();
//extract the textbox value
var TextboxValue = $(this).siblings(".ackname").val();
var objToSave = {}; //Create the object as per the requirement
//Add the textbox value also to same object and send to server
objToSave["TextValue"] = TextboxValue;
$.ajax({
url: "url to another page"
data: JSON.stringify({dataForSave : objToSave}),
type: "POST",dataType: "json",
contentType: "application/json; charset=utf-8",
success: function(datas) {
//Your success Code
},
error: function(error) {
alert(error.responseText);
}
});
});
});
Since both the pages are in same project, you can also do it using single ajax, passing all the values to server at once and then calling the other page internally from server and passing in the values using query string.
This is not a running code, rather to give you a basic idea on how to proceed.
Hope this helps :)