In short, I'm loading a list of clients (as JSON) from an MVC controller. I've verified that the data is structured properly, as well that it does get to the client. The only disconnect is that once the data is loaded, DataTables never displays it.
Here's the JavaScript that initializes the table. I'm almost positive it's configured correctly.
I use the dataSrc parameter to execute some extra code before the data is drawn. Note that it is being executed. I've stepped through just about every piece of this.
I also confirmed that $("clients table") finds the correct element.
$clientsTable = $("#clients table").DataTable({
deferRenderer: true,
info:true,
lengthChange: true,
lengthMenu: [25, 50, 75, 100],
processing: true,
saveState: true,
serverSide: true,
ajax: {
url: "LeadScatter/Clients",
type: "GET",
data: function (d) {
$.extend(d, { byPartner: $("#byPartner").val(), byEnabledDisabled: $("[name=byEnabledDisabled]:checked").val() });
},
dataSrc: function (data) {
getTabState("clients").isLoaded = true;
$("#clients .tab-content").fadeIn(_fadeTimeInMs);
$("#clients .dataTables_filter [type=search]").focus();
return data;
},
error: function (response) {
getTabState("clients").isLoaded = false;
selectedClient = undefined;
$("#tabs").tabs({ disabled: defaultDisabledTabs }).tabs("option", "active", 0);
updateSelectedClient();
showTabLoadError("clients", response.statusText);
if (response.status == 403) {
alert(response.statusText, response.status);
$("#clients").find(".dataTables_empty").text("Sorry, but you do not have permission to view Clients.");
}
}
},
columns: [
{ data: "cakeName", className: "button-cell client" },
{ data: "rpls", className: "number-cell" },
{ data: "forcePayoutIncrease", className: "number-cell" },
{ data: "allocation", className: "number-cell" },
{ data: "inMonthCap", className: "number-cell" },
{ data: "inMonthCapType", className: "number-cell" },
{ data: "toggle", className: "button-cell" },
{ data: "pushToDemo", className: "button-cell" }
]
});
Here's the object that DataTables is picking up. I removed extra array elements to save space. Trust that they're constructed correctly:
{
"draw": 1,
"recordsTotal": 784,
"recordsFiltered": 0,
"data": [
{
"id": 7689,
"cakeName": "<input type='radio' name='selected-client' value='7689' data-id='7689' data-cake-name='aa_test1' data-grouping-id='6666' id='selected-client-aa_test1' class='' /><label for='selected-client-aa_test1' class='disabled'>aa_test1</label>",
"rpls": 40,
"forcePayoutIncrease": 0,
"allocation": 0,
"inMonthCap": 0,
"inMonthCapType": "None",
"enabled": true,
"toggle": "<button type='button' class='button toggle' onclick='toggleClientEnabled(7689);'>Disable</button>",
"pushToDemo": "<button type='button' class='button' onclick='pushClientToDemo('aa_test1');'>Push To Demo</button>"
},
....
]
}
DataTables correctly updates the draw parameter with each subsequent request. Everything behind-the-scenes seems to work fine. Here's the HTML table where the data should be rendered:
<table border="1">
<thead>
<tr>
<th>CakeName</th>
<th>RPLS</th>
<th>ForcePayoutIncrease</th>
<th>Allocation</th>
<th>In-Month Cap</th>
<th>In-Month Cap Type</th>
<th></th>
<th></th>
</tr>
</thead>
</table>
And finally, a screenshot of the table. It's initialized but no data is rendered. You can even see that it's getting the "recordsTotal" variable from the returned object and setting it in the footer.
Am I missing something obvious?
Well, this was frustrating to discover, but it turns out that the dataSrc function was causing it.
I missed in the documentation that when using that parameter as a function, you must return the collection of data that's being displayed, not the JSON object as a whole.
So this:
dataSrc: function (data) {
return data;
}
becomes this:
dataSrc: function (data) {
return data.data; //access the data variable from the returned JSON
}
Voila.
Related
i have C# function That Return Me Json Formated Data , function is below
void DisplayProjectMasterList()
{
string JSONString = "";
DataTable Dt = DB.GetDataTable("Sp_GetProjectMasterList");
if (Dt.Rows.Count > 0)
{
JSONString = JsonConvert.SerializeObject(Dt);
}
Context.Response.Write(JSONString);
}
and I am Calling This Function Via Ajax .in console i am getting json data But i dont know how to pass it to Jquery data table to display.. below is the javascript function... please help Me
function DisplayProjectMasterList() {
$.ajax({
url: 'project-master.ashx',
type: "POST",
dataType: 'json',
data: {
'fun': 'DisplayProjectMasterList'
},
success: function (data) {
console.log(data);
if (Chk_Res(data.errorMessage) == false) {
$('#tbl').dataTable({
paging: true,
sort: true,
searching: true,
scrollY: 200,
data: data,
columns: [
{ 'data':data.Prj_Id },
{ 'data':data.Prj_No },
{ 'data':data.Prj_Name },
{ 'data':data.Cus_Company_Name },
{ 'data':data.Prj_StartDate },
{ 'data':data.Prj_CompletionDate },
]
});
}
}
});
}
i am Getting FOllowing error while doing So:
DataTables warning: table id=tbl - Requested unknown parameter '0' for row 0, column 0. For more information about this error, please see http://datatables.net/tn/4
Hi make sure the data you are being returned is in the following format:
{
"data": [
{
"Prj_Id": 1,
"Prj_No": 1,
"Prj_Name": "name",
"Cus_Company_Name": "company",
"Prj_StartDate": "2011/04/25",
"Prj_CompletionDate": "2011/04/25"
},
{
"Prj_Id": 1,
"Prj_No": 1,
"Prj_Name": "name",
"Cus_Company_Name": "company",
"Prj_StartDate": "2011/04/25",
"Prj_CompletionDate": "2011/04/25"
}
]
}
jquery Datatables by default looks for data property for the array of objects
https://datatables.net/reference/option/ajax.dataSrc
https://datatables.net/examples/ajax/objects.html
My problem is I'm making an ajax sever-side call to retrieve an show information, I get a JSON that is an Object with an ArrayList of Objects inside, but when I try to make the call I get the table with a label saying Processing... all the time and this error in the browser log.
Does anyone knows why is this happening?
Here it's my HTML:
<table id="table_newsletterlist" class="display table">
<thead>
<tr>
<!-- Newsletters attributes -->
<th>Id</th>
<th>Asunto</th>
<th>Para</th>
</tr>
</thead>
<tfoot>
<tr>
<!-- Newsletters attributes -->
<td>Id</td>
<td>Asunto</td>
<td>Para</td>
</tr>
</tfoot>
</table>
Here my JS:
$('#table_newsletterlist').DataTable({
"processing": true,
"serverSide": true,
"ajax": newsletterUrl,
"columns": [
{
"data": "newsletters",
render: function (data){
return (data.id) ? data.id : "-";
}
},
{"data": "newsletters",
render: function (data){
return (data.target) ? data.target : "-";
}},
{"data": "newsletters",
render: function (data){
return (data.subject) ? data.subject : "-";
}},
]
});
And here the JSON I get:
{"total":188,"newsletters":[{"id":1,"subject":"Prueba","target":"groups","html":"<html>\r\n<head>\r\n\t<title></title>\r\n</head>\r\n<body>Probando</body>\r\n</html>\r\n","sender_id":1,"campaign_folder_id":null,"segment_id":null,"group_ids":[],"preview_text":null,"editor_type":"html","url_token":false,"analytics_utm_campaign":"","use_premailer":false}, {more objects like the first...}],"perPage":10,"page":1}
I made the following changes:
Because your JSON's row data array has the name newsletters, you need to refer to this name in the ajax section of your datatable: "dataSrc": "newsletters". This tells DataTables where to look in your JSON for the starting-point of its row iterator.
Following on from point 1, now you can refer to the specific fields in each array object, inside your columns section - for example: data: 'id'.
To simplify the use of - when there is no data, I recommend using defaultContent: "-". You can use a render function - but that is more complicated than you need here, for your specific example.
The end result is as follows:
$(document).ready(function() {
$('#table_newsletterlist')
.DataTable({
"processing": true,
"serverSide": true,
"ajax": {
"url": "http://localhost:7000/newsletters",
"type": "POST",
"dataSrc": "newsletters"
},
"columns": [{
data: 'id',
defaultContent: "-"
}, {
data: 'subject',
defaultContent: "-"
}, {
data: 'target',
defaultContent: "-"
}, {
data: 'preview_text',
defaultContent: "-"
}]
});
});
I have a jQuery datatable that is initially populated using ajax call, and when i click anywhere on the table like pagination number or display length dropdown list, the whole page is reloaded indefinetely. Here is how i populate the datatable.
let table = $('#data-table').DataTable();
function populateTable(){
table = $('#data-table').DataTable({
destroy: true,
responsive: true,
serverSide: false,
autoWidth: false,
paging: true,
filter: true,
searching: true,
stateSave: true,
scrollX: true,
lengthMenu: [10, 25, 50, 75, 100],
language: {
"search": "Filtrer: "
},
ajax: {
url: '/Observer/GetActiveClientsByFloor',
type: 'POST',
data: {
FloorId: floorId,
Type: type
},
dataSrc: ''
},
columns: [
{
title: 'Zone',
data: 'LastKnownZone',
},
{
title: 'HiƩrarchie Map',
data: 'MapInfo.mapHierarchyString',
},
{
title: 'Addresse MAC',
data: 'macAddress',
},
{
title: 'SSID',
data: 'ssId',
},
],
createdRow: (row, data, dataIndex, cells) => {
const selectedRowProfileId = $('#selectedRowProfileId', window.parent.document).val();
if (selectedRowProfileId !== '') {
if (data['ProfileId'] === selectedRowProfileId) {
$(row).addClass('selectedCustom');
}
}
},
initComplete: function (settings, json)
{
const response = json;
//Show the respone on other part of the page
}
}).order([[1, 'asc']]).draw(false);
}
I would like to know what could be causing page re-load and also know how to make pagination works.
You don't need to call order([[1, 'asc']]).draw(false) after table initialization, just add
order: [[1, 'asc']]
to your table properties, like this
$(document).ready(function(){
let table = $('#data-table').DataTable({
order: [[1, 'asc']],
//Other properties
});
As you are not using server-side DataTables will make pagination automatically when you click pagination buttons, considering that all data has already been loaded in the first Ajax call, but when serverSide is set to true every time you change the pagination a new Ajax call will be made by datatables sending aditional parameters for pagination, ordering etc and you will need to change you backend query, filters and pagination logic based on that params.
Edit:
Also destroy: true is not needed in your case, as Documentation says:
"Destroy any existing table matching the selector and replace with the new options."
You are not re-creating or replacing your table, so you can just remove it
I have a jquery autocomplete that once a value is selected it loads a datatable with checkbox from an ajax call. Then while submitting the form I need to access the datatable variable to iterate each row to get the selected ones, but the datatable variable appears as undefined.
I'm doing the same as in this example, only difference is the data is coming from an Ajax request.
Can you please help me understand why is that happening?
$(document).ready(function() {
var campId;
var t_OmnitureCode;
// Campaign input autocomplete
$("#campaign").autocomplete({
source: function(request, response) {
$.ajax({
url: "promotion",
type: "GET",
data: {
term: request.term,
action: "searchCampaign"
},
dataType: "json",
success: function(data) {
if (!data.length) {
var result = [{
label: "no match found",
value: "-1"
}];
response(result);
} else {
response($.map(data, function(item) {
return {
label: item.name,
value: item.campaignId
}
}));
}
}
});
},
select: function(event, ui) {
event.preventDefault();
campId = ui.item.value;
if (campId != "-1") {
this.value = ui.item.label;
// This will apply datatables getting the content from an Ajax call
t_OmnitureCode = applyDataTableOmnitureCode(campId);
}
},
focus: function(event, ui) {
event.preventDefault();
this.value = ui.item.label;
}
});
// Handling form submission
$("#frm_promotion").on("submit", function(e) {
var form = this;
// Variable for datatable "t_OmnitureCode" is undefined below
var rows_selected = t_OmnitureCode.column(0).checkboxes.selected();
EDIT:
Just realized that even while assigning the variable (t_OmnitureCode = applyDataTableOmnitureCode(campId);) it is undefined, not sure why.
Here is the applyDataTableOmnitureCode code:
function applyDataTableOmnitureCode(campId) {
$("#tbl_omnitureCode").DataTable({
destroy: true,
scrollX: true,
fixedColumns: {
leftColumns: 1
},
"ajax": {
"url": "promotion",
"type": "GET",
"data": {
action: "searchOmnitureCodesByCampaignId",
campaignId: campId
},
"dataSrc": ""
},
"columns": [
{ "data": "key" },
{ "data": "omnitureCode" },
{ "data": "urlAppName" },
{ "data": "language" },
{ "data": "channel" },
{ "data": "createDateTime", "defaultContent": "" },
{ "data": "updateDateTime", "defaultContent": "" }
],
"columnDefs": [
{ "targets": 0, "checkboxes": { "selectRow": true } }
],
"select": {
"style": "multi"
},
"order": [[1, "asc"]],
"fnInitComplete": function() {
$("#omnitureCodeSection").show();
}
});
};
You may need to grab your DataTables object into a variable before using that:
var t_OmnitureCode = $("#tbl_omnitureCode").DataTable();
var rows_selected = t_OmnitureCode.column(0).checkboxes.selected();
And, by the way, your method of populating DataTable with external ajax-call is suboptimal. There's an ajax option for that purpose where you can specify all the necessary parameters and get better integration with DataTables API and better performance (as you don't really need to destroy and create your DataTable upon each refresh).
You would simply need to trigger .ajax.reload() whenever you need to refresh your table data.
It's a matter of scope : You declare the variable table inside $(document).ready function.
You may want to put it outside in the global scope :
var table;
$(document).ready(function() {
table = $('#example').DataTable({
...
});
How could I perform If else like method in datatable? The variable 'data' returns the value of the variable, which is correct, but if it is blank, it would return the word "from1", "from2" which is supposed to be the value of the variable "from1". Am I doing the right approach or do you have any suggestion as workaround in this problem? thank you for your answers. here is my code:
var table = $('#records').DataTable({
type: 'post',
"ajax": "getHumanTrainings",
"bPaginate": true,
"bProcessing": true,
"pageLength": 10,
"columns": [{
mData: 'tdesc'
}, {
data: "fdDateFrom2",
defaultContent: 'from1'
}, {
data: "fdDateTo2",
defaultContent: 'from2'
}, {
data: "fcTrainor2",
defaultContent: 'train1'
}, {
mData: 'dur'
}]
});
I'd use the render option for the column data that you have, its much more flexible in terms of wanting something to be displayed by default.
var table = $('#records').DataTable({
type: 'post',
"ajax": "getHumanTrainings",
"bPaginate": true,
"bProcessing": true,
"pageLength": 10,
"columns": [{
mData: 'tdesc'
}, {
data: "fdDateFrom2",
render: function(data, type, row) {
// Check if blank
if (data === "") {
return row[<index for from1>]; // Just use the index for from1
}
// If not blank display data normally
return data;
}
}, {
data: "fdDateTo2",
render: function(data, type, row) {
// Check if blank
if (data === "") {
return row[<index for from2>]; // Just use the index for from2
}
// If not blank display data normally
return data;
}
}, {
data: "fcTrainor2",
render: function(data, type, row) {
// Check if blank
if (data === "") {
return row[<index for train1>]; // Just use the index for train1
}
// If not blank display data normally
return data;
}
}, {
mData: 'dur'
}]
});
I've left comments to give you a guide since I'm not familiar with your data, I would suggest printing out your row first over at render so you'd know which index to use.