I have implemented Serverside processing for the jquery datatable. There is a functionality which is working fine for the "ClientSide Processing" but not working when implemented using "Serverside Processing".
My issue is, while navigating from one page to another page in the jquery datatable, if any changes exists(in textbox/dropdown in any cell), then display error message and don't navigate to the next page.
I am able to achieve this above scenario, using client side. But unable to do in server side.
In client side i have implemented like this
(document).ready(function () {
var isSuperUser = '@isUserSuperAdmin';
var oTable = $('#tblnotreportingdetails').dataTable(
{
dom: 'Bfrtip',
oLanguage: {
sSearch: '<i class="fa fa-search"> </i>'
},
iDisplayLength: 7,
buttons: [
{
extend: 'copy',
text: '<i class="fa fa-files-o fa-2x" style="color: green;"></i>',
titleAttr: 'Copy',
exportOptions: {
columns: "thead th:not(.noExport)"
}
},
{
extend: 'excel',
text: '<i class="fa fa-file-excel-o fa-2x" style="color: green;"></i>',
titleAttr: 'Excel',
exportOptions: {
columns: "thead th:not(.noExport)"
}
},
{
extend: 'csv',
text: '<i class="fa fa-file-text-o fa-2x" style="color: green;"></i>',
titleAttr: 'CSV',
exportOptions: {
columns: "thead th:not(.noExport)"
}
},
{
extend: 'pdf',
text: '<i class="fa fa-file-pdf-o fa-2x" style="color: green;"></i>',
titleAttr: 'PDF',
exportOptions: {
columns: "thead th:not(.noExport)"
}
},
{
extend: 'print',
text: '<i class="fa fa-print fa-2x" style="color: green;"></i>',
titleAttr: 'Print',
exportOptions: {
columns: "thead th:not(.noExport)"
}
}]
});
//Function to alert the user to save information on navigating to the next page through Pagination
$('#tblnotreportingdetails').on('page.dt', function () {
var selectedReasonKeyArr = [];
//Getting the current page visible rows (10 rows/20 rows/50 rows/100 rows - default is 10 rows)
var rows = $("#tblnotreportingdetails tbody tr");
for (var index = 0; index < rows.length; index++) {
//Getting each row
var singleRow = $(rows[index]);
//Get the Reason Dropdown selected value
var selectedReasonKey = singleRow.find(":selected").val();
var selectedReasonText = singleRow.find(":selected").text();
var existingReasonText = $.trim(singleRow.find('td').eq(9).html());
//If the selected value is not empty (is empty only when the text is "--Select--")
if (selectedReasonKey != "") {
existingReasonText = decodeEntities(existingReasonText);
if (selectedReasonText != existingReasonText) { //Add to the Array
//alert("existingReasonText : " + existingReasonText + "selectedReasonText : " + selectedReasonText);
selectedReasonKeyArr.push(selectedReasonKey);
}
}
}
//Check if the Array length is more than 0 then display message
if (selectedReasonKeyArr.length > 0) {
// alert("Please save unsaved Data before Navigating to the next Page.");
var existingErrMessage = $('#divNrpErrorMessage').text();
if (existingErrMessage.indexOf("Please save unsaved Data before Navigating to the next Page.") == -1) {
var newErrorMessage = existingErrMessage + " Please save unsaved Data before Navigating to the next Page.";
$('#divNrpErrorMessage').text(newErrorMessage);
}
//Finding the first row of the selected page and staying on the same page by using the below extension method
oTable.fnGetPageOfRow(rows[0]);
}
else {
$('#divNrpErrorMessage').text('');
$('#divNrpSuccessMessage').text('');
}
});
});
In client side, i am able to do it easily by using the extension method oTable.fnGetPageOfRow(rows[0]);
For Server side processing my code like below
[HttpPost, OutputCache(Duration = 0, NoStore = true)]
public JsonResult LoadNotReportingDataTable()
{
var draw = Request.Form.GetValues("draw").FirstOrDefault();
var start = Request.Form.GetValues("start").FirstOrDefault();
var length = Request.Form.GetValues("length").FirstOrDefault();
var sortColumn = Request.Form.GetValues("columns[" + Request.Form.GetValues("order[0][column]").FirstOrDefault() + "][name]").FirstOrDefault();
var sortColumnDir = Request.Form.GetValues("order[0][dir]").FirstOrDefault();
var search = Request.Form.GetValues("search[value]").FirstOrDefault().ToLower();
int pageSize = length != null ? Convert.ToInt32(length) : 0;
int skip = start != null ? Convert.ToInt32(start) : 0;
int totalRecord = 0;
int filteredRecord = 0;
var assetsNotReportingModelList = new List<AssetsNotReportingModel>();
var result = GetAssetsByNotReportingReasonWiseCountDts(15, "0", "0", "0", "0", "0", "0", "0", "0", "NR").ToList();
assetsNotReportingModelList.AddRange(result);
//Assign the totalrecord for jquery datatable - server side processing
totalRecord = assetsNotReportingModelList != null ? assetsNotReportingModelList.Count() : totalRecord;
var v = (from item in assetsNotReportingModelList select item);
if (!(string.IsNullOrEmpty(sortColumn) && !(string.IsNullOrEmpty(sortColumnDir))))
{
v = v.OrderBy(sortColumn + " " + sortColumnDir);
}
filteredRecord = v.ToList().Count();
var data = pageSize == -1 ? v.ToList() : v.Skip(skip).Take(pageSize).ToList();
JsonResult json = Json(new
{
draw = draw,
recordsFilterd = filteredRecord,
recordsTotal = totalRecord,
iTotalRecords = totalRecord,
iTotalDisplayRecords = filteredRecord,
data = data
}, JsonRequestBehavior.AllowGet);
json.MaxJsonLength = int.MaxValue;
return json;
}
ServerSide Processing - Javascript code here
var prestart = 0;
var prepaginationval = 1;
$(document).ready(function () {
var isSuperUser = '@isUserSuperAdmin';
var notReportingPaginationArr = [];
var oTable = $('#tblnotreportingdetails').dataTable({
"ajax": {
"url": "@Url.Action("LoadNotReportingDataTable", "Home")",
"type": "POST",
"datatype": "json",
"headers": headers,
"beforeSend": function (xhr, opts) {
//debugger;
//if any changes available in the current page(reason/remark) tnen get the current page number and assign to the global variable
if (notReportingPaginationArr.length > 0) {
prepaginationval = $('#tblnotreportingdetails_wrapper').find('.dataTables_paginate').find('ul.pagination').find('li.active a').attr("data-dt-idx");
//alert('pervious page no : ' + prepaginationval);
}
},
"data": function (d) {
d.nrp = JSON.stringify(notReportingPaginationArr);
d.prestart = prestart;
return d;
},
},
"dom": 'Bftrip',
"oLanguage": {
"sSearch": '<i class="fa fa-search"> </i>'
},
"paging": true,
"pagingType": "full_numbers",
"pageLength": 7,
"serverSide": true,
"processing": true,
"language": {
"loadingRecords": " ",
'processing': "<i id='processingIcon' class='fa fa-cog fa-spin fa-2x'></i>"
},
"columns": [
{
"title": "Asset Code", "data": "Asset_ID", "name": "Asset_ID", "visible": true, "searchable": true, "sortable": true, "class": "text-left-align",
"render": function (data, type, full, meta) {
var oemkeycontrol = '<input type="hidden" name="OEM_Key" id="hdnOEM_Key" value="' + full.OEM_Key + '" />';
var assetidcontrol = '<input type="hidden" name="Asset_ID" id="hdnAsset_ID" value="' + data + '" />';
var companycodecontrol = '<input type="hidden" name="CompanyCode" id="hdnCompanyCode" value="' + full.CompanyCode + '" />';
var notreportingreasontypecontrol = '<input type="hidden" name="NotReportingReasonType" value="' + full.NotReportingReasonType + '" />';
var assetoverviewcontrol = full.IsForAssetOverview == "Y" ? '<a title="Click to view Asset Overview" style="cursor: pointer;font-size: 14px;font-weight: bold;color:#3884c7 !important" data_toggle="tooltip" id="' + data
+ '" onclick=moveToAssetOverviewFromNotReporting("' + data + '","' + full.CompanyCode + '","' + full.OEM_Key + '","' + full.NotReportingReasonType + '")>' + data + '</a>'
: '<a title="EMS Asset" data_toggle="tooltip" id="' + data + '" class="disabled">' + data + '</a>';
return oemkeycontrol + assetidcontrol + companycodecontrol + notreportingreasontypecontrol + assetoverviewcontrol;
}
},
{
"title": "Asset Description", "data": "Asset_Name", "name": "Asset_Name", "visible": true, "searchable": true, "sortable": true, "class": "text-left-align"
},
{
"title": "IC", "data": "ICShortCode", "name": "ICShortCode", "visible": true, "searchable": true, "sortable": true, "class": "text-center"
},
{
"title": "Job Code", "data": "Job_Code", "name": "Job_Code", "visible": true, "searchable": true, "sortable": true, "class": "text-left-align"
},
{
"title": "Job Description", "data": "Job_Desc", "name": "Job_Desc", "visible": true, "searchable": true, "sortable": true, "class": "text-left-align"
},
{
"title": "Last Reported Time", "data": "Date", "name": "Date", "visible": true, "searchable": true, "sortable": true, "class": "text-left-align"
},
{
"title": "Days Not Reported", "data": "NotReportingAge", "name": "NotReportingAge", "visible": true, "searchable": true, "sortable": true, "class": "text-center",
"render": function (data, type, full, meta) {
if (data != null) {
var notreportingagecontrol = '<a title="Click to view History" style="cursor: pointer;font-size: 14px;font-weight: bold;color:#3884c7 !important" data_toggle="tooltip" ' +
'id="ancNotReportingAge" onclick="displayNotReportingReasonHistoryPopUp(\'' + full.Asset_ID + '\',\'' + full.Asset_Name + '\',\'' + full.CompanyCode + '\',\'' + full.OEM_Key + '\');">' + data + '</a>';
return notreportingagecontrol;
}
}
},
{
"title": "Days Not Reported with Current Reason", "data": "CurrentNotReportingReasonAge", "name": "CurrentNotReportingReasonAge", "visible": true, "searchable": true, "sortable": true, "class": "text-center"
},
{
"title": "Reason", "data": "_ReasonKey", "name": "_ReasonKey", "visible": true, "searchable": false, "sortable": false, "className": "noExport",
"render": function (data, type, full, meta) {
var $select = $("<select class = 'form-control', style = 'font-size:11px;width: 150px;'></select>", { "id": "drpReason", "value": data });
var $defaultoption = $("<option></option>", { "text": "--Select--", "value": "" });
$select.append($defaultoption);
$.each(full.NotReportingReason, function (k, v) {
var $option = $("<option></option>", { "text": v.Text, "value": v.Value });
if (data == v.Value) { $option.attr("selected", "selected") }
$select.append($option);
});
return $select.prop("outerHTML");
}
},
{
"title": "_Reason", "data": "_Reason", "name": "_Reason", "visible": false, "searchable": true, "sortable": false, "class": "text-left-align"
},
{
"title": "Reason Created By", "data": "ReasonCreatedBy", "name": "ReasonCreatedBy", "visible": true, "searchable": true, "sortable": true, "class": "text-left-align"
},
{
"title": "Reason Updated By", "data": "ReasonUpdatedBy", "name": "ReasonUpdatedBy", "visible": true, "searchable": true, "sortable": true, "class": "text-left-align"
},
{
"title": "Remarks", "data": "Remarks", "name": "Remark", "visible": true, "searchable": true, "sortable": true, "data-orderable": false, "class": "text-center",
"render": function (data, type, full, meta) {
var remarkcontrol = '<textarea id="txtRemarks" class="form-control" style="font-size:11px;width: 150px;" title="' + full.RemarkEnteredOnDate + '">' + data + '</textarea>';
return remarkcontrol;
}
},
//{
// "data": "Remarks", "name": "Remarks", "visible": false, "searchable": false, "sortable": false, "class": "text-left-align"
//},
{
"title": "Reason & Remark History", "data": "", "name": "Reason&RemarkHistory", "visible": true, "searchable": false, "sortable": false, "data-orderable":false, "class": "text-center noExport",
"render": function (data, type, full, meta) {
if (full._ReasonKey && full._ReasonKey != -1) {
return '<a class="btn btn-xs mybtn-info cursorpointer display-mode" onclick="displayNrReasonAndRemarkHistoryPopUp(\'' + full.Asset_ID + '\',\'' + full.Asset_Name + '\',\'' + full.CompanyCode + '\',\'' + full.OEM_Key + '\')" '
+ 'data-title="Click to view Reason & Remarks History" title="Click to view Reason & Remarks History" data-toggle="tooltip">'
+ '<i class="fa fa-history" title="Click to view Reason & Remarks History" style="padding:5px; font-size:17px;"></i></a>';
} else {
return '<a class="btn btn-xs mybtn-info cursorpointer display-mode" title="No Reason & Remarks History Available" data-toggle="tooltip" disabled>'
+ '<i class="fa fa-history" title="No Reason & Remarks History Available" style="padding:5px; font-size:17px;"></i></a>';
}
}
},
{
"title": "Source/OEM Provider", "data": "OEM_Provider", "name": "OEM_Provider", "visible": true, "searchable": true, "sortable": true, "class": "text-center"
},
{
"title": "Location Details", "data": "", "searchable": false, "sortable": false, "class": "text-center noExport",
"render": function (data, type, full, meta) {
return '<a class="cursorpointer mapmarkercolor dialog" id="btnMap" onclick="getAssetMap(this,\'' + full.Asset_ID + '\',\'' + full.Asset_Name + '\',\'' + full.CompanyCode + '\',\'' + full.OEM_Key + '\',\'Last\')" '
+ 'data-toggle="tooltip" title="Last known location" name="' + full.Asset_Name + '" style="font-size:2.5em;color:deepskyblue;"> <span class="icon-Map-Marker"></span></a>';
}
}
],
"columnDefs": [
{
"targets": 5,
render: function (data) {
if (data != null)
return moment(data).format('DD-MMM-YYYY HH:mm:ss A');
else
return '';
}
}
],
"fnDrawCallback": function (oSettings) {
},
"initComplete": function (settings, json) {
}
});
//Function to alert the user to save information on navigating to the next page through Pagination
oTable.on('page.dt', function (e, oSettings) {
e.preventDefault();
var selectedReasonKeyArr = [];
notReportingPaginationArr.length = 0;
//Getting the current page visible rows (10 rows/20 rows/50 rows/100 rows - default is 10 rows)
var rows = $("#tblnotreportingdetails tbody tr");
for (var index = 0; index < rows.length; index++) {
//Getting each row
var singleRow = $(rows[index]);
//Get the Reason Dropdown selected value
var selectedAssetId = singleRow.find("#hdnAsset_ID").val();
var selectedCompanyCode = singleRow.find("#hdnCompanyCode").val();
var selectedOemKey = singleRow.find("#hdnOEM_Key").val();
var selectedReasonKey = singleRow.find(":selected").val();
var selectedReasonText = singleRow.find(":selected").text();
var selectedRemarkText = singleRow.find("#txtRemarks").text();
var data = oTable.api().row(singleRow).data();
var existingReasonText = $.trim(data["_Reason"]);
//If the selected value is not empty (is empty only when the text is "--Select--")
if (selectedReasonKey != "") {
existingReasonText = decodeEntities(existingReasonText);
if (selectedReasonText != existingReasonText) { //Add to the Array
//alert("existingReasonText : " + existingReasonText + "selectedReasonText : " + selectedReasonText);
selectedReasonKeyArr.push(selectedReasonKey);
notReportingPaginationArr.push(
{
"Asset_ID": selectedAssetId,
"CompanyCode": selectedCompanyCode,
"OEM_Key": selectedOemKey,
"NewReasonKey": selectedReasonKey,
"NewReasonText": selectedReasonText,
"NewRemarkText": selectedRemarkText
});
}
}
}
//Check if the Array length is more than 0 then display message
if (selectedReasonKeyArr.length > 0) {
// alert("Please save unsaved Data before Navigating to the next Page.");
var existingErrMessage = $('#divNrpErrorMessage').text();
if (existingErrMessage.indexOf("Please save unsaved Data before Navigating to the next Page.") == -1) {
var newErrorMessage = existingErrMessage + " Please save unsaved Data before Navigating to the next Page.";
$('#divNrpErrorMessage').text(newErrorMessage);
}
debugger;
var p = oTable.api().page.info();
prestart = p.start > 6 ? (p.start - p.length) : p.start;
oTable.api().draw(false);
//var data = oTable.row(rows[0]).data();
//Finding the first row of the selected page and staying on the same page by using the below extention method
//oTable.fnGetPageOfRow(rows[0]);
//oTable.row(rows[0]).data(data).draw(false);
//var p = oTable.api().page.info();
//oTable.fnClearTable();
//for (var i = 0; i < rows.length; i++) {
// oTable.fnAddData($(rows[i]));
//}
//oTable.page(p.page).draw('page');
//oTable.ajax.reload(null, false);
//oTable.draw(false);
//oTable.fnPageChange(0, true);
//oTable.settings()[0].oFeatures.bServerSide = false;
//oTable.settings()[0].ajax = false;
}
else {
$('#divNrpErrorMessage').text('');
$('#divNrpSuccessMessage').text('');
}
});
});
But server side, how to do ?
Please help.