How to seed data from AJAX response when Datatables is already initialized? - javascript

I have a mix of Select2JS and Datatables and here is the code involved in the issue:
$(function() {
var form_id = $('#form_id'),
form_results = $('#form_results');
form_results.DataTable();
$.ajax({
type: 'POST',
dataType: 'json',
contentType: 'json',
url: '/ajax/forms/get/',
data: JSON.stringify({
form_id: null,
show_archived: !!$('#show_archived').is(':checked'),
get_first: false,
format: 'select2',
}),
cache: false,
success: function(data) {
form_id.removeAttr('disabled');
form_id.select2({
data: data,
closeOnSelect: true,
matcher,
sorter,
}).on('select2:select', function(e) {
var selected_element = $(e.currentTarget);
$.ajax({
type: 'POST',
dataType: 'json',
contentType: 'json',
url: '/ajax/manage_forms/getFormData/',
data: JSON.stringify({
form_id: selected_element.val(),
get_first: true,
}),
cache: false,
success: function(response) {
form_results.DataTable({
data: response.data,
retrieve: true,
stateSave: true,
responsive: true,
columnDefs: [
{
className: 'select-checkbox',
orderable: false,
searchable: false,
targets: 0,
},
],
select: {
style: 'multiple',
selector: 'td:first-child',
},
});
},
error: function(xhr, ajaxOptions, thrownError) {
console.error(xhr.responseText);
},
});
});
},
error: function(xhr, ajaxOptions, thrownError) {
console.error(xhr.responseText);
},
});
});
On the PHP side there is a function building the data and send it back to the browser:
public function getFormData()
{
$inputJSON = file_get_contents('php://input');
$outputJSON = json_decode($inputJSON, true);
$arguments = array(
'Id' => $outputJSON['form_id'],
'FormName' => null,
'FormFileName' => null,
'FormTypeId' => 1
);
$form = $this->forms_model->get($arguments, $outputJSON['get_first'], self::$folders);
$result[] = array(
'',
'DT_RowId' => $form->Id,
$form->FormName,
$form->FaxNumber,
end(explode('/', $form->form_filepath))
);
return $this->output->set_content_type('application/json')->set_output(json_encode(array('data' => $result)));
}
The result from the above function looks like:
{
"data" : [
{
"0" : "",
"DT_RowId" : 3387,
"1" : "form",
"2" : "8772399284",
"3" : "form1.pdf"
}
]
}
For some reason the table is showing all the time "No data available in table" and I can't find where is the issue, can any find out what is wrong in my code?
I have spent the last two hours trying to figure this out but I can't.
Updates:
#charlietfl: the following didn't work at first complaining about the k not being defined so I modified a little bit however it didn't do the trick
response.data.map(function(k, o) {
return Object.keys(k).map(function(k) { return o[k];});
});
#CFP Support: your solution is not working either for some reason the table doesn't get updated with data.
In both cases I am not getting any Javascript error or nothing weird in the console it just does not work.

You need to add the "columns" and define them.
...stuff...
columnDefs: [
{
className: 'select-checkbox',
orderable: false,
searchable: false,
targets: 0,
},
],
columns: [
{data: "0"},
{data: "DT_RowId"},
{data: "1"},
{data: "2"},
{data: "3"}
], ....etc...
This tells the table what column to match with the incoming data (so you will need a table with 5 columns in the HTML - or build it with JS {not sure what you are using, but if you need help...}
This should get you past the immediate issue though.
EDIT: JSFiddle - https://jsfiddle.net/CFPSupport/5utwh4v3/6/
EDIT2: I see the issue - you are initializing then wanting to put more data.... OK.....
You should get the data IN the datatable init, not init+AJAX.... https://datatables.net/reference/option/ajax

Related

Using JSON data to filll "columns" in datatable

I am getting JSON data via AJAX and my data are in a result object. The fields of which can be accessed as in success: function(result)
result.map.count[0].name
result.map.count[0].count
I would like to show name and count as two columns of my datatable.
My ajax request is written as
table = $('#_table').dataTable({
searching: false,
paging: true,
ajax: function (data, callback, settings) {
$.ajax({
type: "post",
url: '/test/getvalues',
dataType: "json",
success: function (result) {
I am able to get data as "result" here
result.map.count[0].name
result.map.count[0].count
}
});
},
columns: []
})
what should I put in columns[] to show these fields?
columns: []
In your datatable configuration,add the following
data: [[result.map.count.name,result.map.count.count]], // make it as array of values
columns: [
{
"sClass": "center",
"name": "Name"
},
{
"sClass": "center",
"name": "Count"
},
]
Please check here for more details
https://datatables.net/examples/data_sources/js_array.html
I've found my answer.
I need to write a callback function that returns the data (array) which is found from my object.
Code:
table = $('#_table').dataTable({
searching: false,
paging: true,
ajax: function (data, callback, settings) {
$.ajax({
type: "post",
url: '/test/getvalues',
dataType: "json",
success: function (result) {
var dataToUse = {};
dataToUse.data = result.map.count;
callback(dataToUse);
}
});
},
columns: [
"data": "name",
"data": "count"
]
})
}
Please try this.
table = $('#_table').dataTable({
searching: false,
paging: true,
ajax: function (data, callback, settings) {
$.ajax({
type: "post",
url: '/test/getvalues',
dataType: "json",
success: function (result) {
callback(result.map.count);
}
});
},
// Columns
columns: [{
title: "Name",
name: "name",
}, {
title: "Count",
name: "count"
}]
});

JQuery Datatable initialization

I'm getting this error while trying to supply JSON into my DataTable:
DataTables warning: table id=myTable - Requested unknown parameter 'a' for row 0, column 0. For more information about this error, please see http://datatables.net/tn/4
This is what my JSON looks like:
[{
"a": "asdsaddas",
"b": "asdasda",
"c": "0000000001",
"d": "name"
}]
When user clicks button I'm generating and showing the table with an AJAX callback:
$('#find_button').click(function() {
event.preventDefault();
if (validateAll()) {
$("#myTable").DataTable({
"lengthChange": false,
"pageLength": 20,
autoWidth: false,
serverSide: true,
processing: true,
"dataSrc": "",
"ajax": function(data, callback, settings) {
var $form = $("#my_form_id");
var jsonData = getFormData($form, data.start, data.length);
var request = $.ajax({
type: "POST",
url: "api",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(jsonData),
dataType: "json"
});
request.then(function(response) {
console.log(JSON.stringify(response.data));
callback({
data: [JSON.stringify(response.data)],
recordsTotal: response.total,
recordsFiltered: response.total
})
}, failCallback);
},
columns: [{
"data": "a"
}, {
"data": "b"
}, {
"data": "c"
}, {
"data": "d"
}],
filter: false,
info: false,
ordering: false
});
$('#htmlTable').show();
}
});
I've read a lot of related questions with same bug, but still cannot make it work in my case. Maybe there is problem that DataTable is initialized before it gets response from server?

Jquery Datatables get row data as string or object on button click

I'm attempting to get a row of data based on button click event. I can manage to find the row and read the results as text, but I want the data cast as a string or an object. Below is my current code:
$.ajax({
url: "SympsService.asmx/GetSymptoms",
method: "post",
dataType: "json",
data: JSON.stringify({
organ_name: "toes"
}),
contentType: "application/json",
success: function(data) {
var sympList = 'GetSymptoms' ? JSON.parse(data.d) : data.d;
createDataTable('#symptomsTable', sympList);
function createDataTable(target, data) {
$(target).DataTable({
destroy: true,
paging: false,
searching: false,
info: false,
data: data,
columnDefs: [{
targets: [-1],
render: function() {
return "<button type='button'>" + ('Choose') + "</button>"
}
}],
columns: [{
'data': 'Sympt',
'title': 'toes Symptoms'
}, {
'data': null,
'title': 'Action'
}]
});
}
$('#symptomsTable').on("click", "tbody button", function() {
var id = $(this).closest("tr").find("td:nth-child(1)").text(); //this show perfectly
var id = $(this).closest("tr").find("td:nth-child(1)").data(); //this show undefined
var id = $(this).closest("tr").find("td:nth-child(1)").toString(); //this show {object Object}
console.log(id);
})
},
});
Any kind of help is appreciated.
To find the data object for the whole row:
$("#symptomsTable').DataTable().rows($(this).closest("tr")).data()
to find it for the particular cell:
$("#symptomsTable").DataTable().cells($(this).closest("td").siblings().eq(0)).data()

jsGrid won't render JSON data

I'm trying to use jsGrid in my MVC project as the client would like inline editing and filtering.
However, I cannot get it to load my JSON source into the table.
My js to load the table looks like so:
$("#jsGrid").jsGrid({
height: "50%",
width: "100%",
filtering: true,
inserting: true,
editing: true,
sorting: true,
paging: true,
autoload: true,
pageSize: 10,
pageButtonCount: 5,
deleteConfirm: "Do you really want to delete client?",
controller: {
loadData: function (filter) {
return $.ajax({
type: "GET",
url: "RICInstrumentCode/GetData",
data: filter,
dataType: "json"
});
},
insertItem: function (item) {
return $.ajax({
type: "CREATE",
url: "/api/RICInsrumentCodeTable",
data: item,
dataType: "json"
});
},
updateItem: function (item) {
return $.ajax({
type: "UPDATE",
url: "/api/RICInsrumentCodeTable/" + item.ID,
data: item,
dataType: "json"
});
},
deleteItem: $.noop
//deleteItem: function (item) {
// return $.ajax({
// type: "DELETE",
// url: "/api/data/" + item.ID,
// dataType: "json"
// });
//}
},
fields: [
{ name: "Code", type: "text", title: "RIC Instrument Code", width: 150 },
{ name: "Descr", type: "text", title:"RIC Instrument Code Description", width: 200 },
{ name: "RICInstrumentGroupId", type: "select", title: "RIC Instrument Group", items: countries, valueField: "Id", textField: "Name" },
{ name: "Active", type: "checkbox", title: "Is Active", sorting: true },
{ type: "control" }
]
});
});
The loadData is what I've been working on.
and the JSON the is returned from get data looks like so:
[{"Id":1,"Code":"test1","Descr":"first code test","RICInstrumentGroupId":2,"Active":true},{"Id":2,"Code":"APP","Descr":"Apples and bananas","RICInstrumentGroupId":4,"Active":true},{"Id":3,"Code":"1","Descr":"1","RICInstrumentGroupId":1,"Active":true},{"Id":4,"Code":"3","Descr":"3","RICInstrumentGroupId":3,"Active":false}]
So far I have confirmed that the ajax is firing, changed my array titles to match those of the call, and ensured the return is in valid JSON, what else can I do? Why isn't this working?
I was being stupid,
The bit that sets the table height was set to a 100% in a div that had no height, this was causing the table body to render with a height of 0px, changing the height property to auto fixed it because the data was there all along.
Thanks for the advice though!
I don't know if it is required, but when I look on demo examples (OData Service).
The grid loadData function looks bit different than yours.
loadData: function() {
var d = $.Deferred();
$.ajax({
url: "http://services.odata.org/V3/(S(3mnweai3qldmghnzfshavfok))/OData/OData.svc/Products",
dataType: "json"
}).done(function(response) {
d.resolve(response.value);
});
return d.promise();
}
is accept promise rather than ajax function. so that my be the problem
Demo here: http://js-grid.com/demos/

Pass complex javascript object configuration(data and functions) from json string

I have a javascript that has a bunch of parameters and functions inside of it.
ctrl.kendoGrid({
dataSource: {
type: "odata",
transport: {
read: {
url: "odata/CodeView",
dataType: "json",
contentType: "application/json"
},
update: {
url: function (data) {
return "api/CodeMapUpdate/" + data.CODE_MAP_ID;
},
dataType: "json",
type: "post",
complete: function (e) {
ctrl.data("kendoGrid").dataSource.read();
if (e.status == 201) {
logger.log("Record Updated: Record ID = " + e.responseJSON, null, null, true);
} else {
logger.logError(" Save failed " + e.responseJSON.ExceptionMessage, null, null, true);
}
}
},
destroy: {
url: function (data) {
return "api/CodeMapDelete/" + data.CODE_MAP_ID;
},
dataType: "json",
complete: function () {
ctrl.data("kendoGrid").dataSource.read();
}
},
create: {
url: "api/CodeMapCreate",
dataType: "json",
complete: function (e) {
ctrl.data("kendoGrid").dataSource.sort({
field: "CODE_MAP_ID",
dir: "desc"
});
ctrl.data("kendoGrid").dataSource.filter({});
if (e.status == 201) {
logger.log("Record Created: Record ID = " + e.responseJSON, null, null, true);
} else {
logger.logError(" Save failed " + e.responseJSON.ExceptionMessage, null, null, true);
}
}
},
},
schema: {
data: function (data) {
return data.value;
},
total: function (data) {
return data["odata.count"];
},
model: {
id: "CODE_MAP_ID",
fields: {
CODE_MAP_ID: {
editable: false,
type: "number"
},
CODE_NAME: {
type: "string",
validation: {
title: "Required Field",
required: true
}
},
L_NAME: {
type: "string",
validation: {
required: true
}
},
CODE_DATE: {
field: "CODE_DATE",
type: "date",
format: "{0:MM/dd/yyyy}",
validation: {
required: true
}
},
}
}
},
change: function () {
},
//batch: true,
pageSize: 20,
serverPaging: true,
serverFiltering: true,
serverSorting: true,
sort: {
field: "CODE_MAP_ID",
dir: "desc"
}
//autoSync: true
} })
I am trying to save the entire "dataSource" object as a variable and retrieve it at runtime with ajax.
I am able to do this with eval ("(" + dataSource + ")") but any included functions are no longer executing.
Any idea on a strategy to store/retrieve this type of an object to/from JSON?
here is a simple demo of how to use the 2nd param to JSON.parse to recover stored functions:
var ob={a:1, b:false, c: function(a){ return a * a;} };//a sample object
Function.prototype.toJSON=Function.toString; //extend JSON to cover Functions
var str=JSON.stringify(ob, null, "\t"); //turn sample object into a string:
/* str =={
"a": 1,
"b": false,
"c": "function (a){return a*a;}"
} */
//now turn the string back into an object, using a reviver to re-parse methods:
var ob2=JSON.parse(str, function(a,b){
if(b.match && b.match(/^function[\w\W]+\}$/)){ b=eval("b=0||"+b); }
return b;
});
var n=5; //let's try the method using a number
var n2=ob2.c(5); //apply the method to the number
alert(n2); // shows: 25, the number times itself, verifying that the function works
You might want to be a litle stricter about what you send to eval, maybe use a key schema in addition to matching properties that simply look like functions. you can beef-up the regexp to be a little stricter, but for this quick demo of the JSON.parse() parameter, it all works just fine.
In this case, since you are collecting the properties of the JSON, there's no chance of running into the security issues that eval() use can facilitate. Those problems stem from sending one user's input to another user without filtering, not when you jump-start code the client itself produced last time...

Categories

Resources