Datatables.js issues and questions - json

I have a action in my controller that returns a list of activities and this was rendering to my datatable without issue, however, I did not see the number of records displayed at the bottom of the table rendering properly. I did some digging and it looks like there are some additional properties required to get this to work. I added those properties in my controller and ajax call and now I see 'Showing 1 of 3 of 3 entries' but no data in my datatable.
So here is my controller action when the datatable displays results but 'Showing 0 of 0 ...' is displayed.
Controller
[HttpPost]
public JsonResult GetAllActivities(int UserId)
{
return Json(repository.GetAllActivities(UserId), JsonRequestBehavior.AllowGet);
}
HTML
<div class="panel-body">
<table id="master" class="table table-striped table-hover table-condensed" cellspacing="0">
<thead>
<tr>
<th class="rpt_col_bg_head" style="width: 3%;"></th>
<th class="rpt_col_bg_head" style="width: 20%;">Result</th>
<th class="rpt_col_bg_detail" style="width: 20%;">Work Activity</th>
<th class="rpt_col_bg_detail" style="width: 180px;">Effort(%)</th>
<th class="rpt_col_bg_detail" style="width: 7%;">Status</th>
<th class="rpt_col_bg_detail" style="width: 30%;">Were there any innovations</th>
<th class="rpt_col_bg_detail text-center" style="width: 7%;">Action</th>
</tr>
</thead>
</table>
</div>
JavaScript
var table = $('#master').DataTable( {
"processing": true,
"serverSide": true,
"columnDefs" : [{
"targets" : [0],
"visible" : true,
"searchable" : false
}],
"ajax" : {
"type" : "POST",
"url" : "#Url.Action("GetAllActivities", "Activities")",
"data" : { "UserId" : employeeId },
"dataSrc" : ""
},
"columns": [
{
"className" : "details-control", "orderable" : false, "data": "ActivityHistoryId" },
{ "data" : "ParentName" },
{ "data" : "ActivityName" },
{ "data" : "Effort" },
{ "data" : "Status" },
{ "data" : "Innovation" },
{ "defaultContent" : '<td><div><button class="btn btn-xs btn-primary" title="edit work activity" name="editWork"></button></div></td>' }]
});
According to the documentation below some additional properties are required to get the footer to work.
https://datatables.net/manual/server-side
I modified my controller action and html accordingly.....
[HttpPost]
public JsonResult GetAllActivities(int UserId)
{
int count = 0;
var data = repository.GetAllActivities(UserId);
foreach (var item in results)
{
count++;
}
return Json(new { draw = 1, recordsTotal = count, recordsFiltered = count, data }, JsonRequestBehavior.AllowGet);
}
HTML
var table = $('#master').DataTable({
"processing": true,
"serverSide": true,
"columnDefs" : [{
"targets" : [0],
"visible" : true,
"searchable" : false
}],
"ajax" : {
"type" : "POST",
"url" : "#Url.Action("GetAllActivities", "Activities")",
"data" : { "UserId" : employeeId },
"dataFilter" : function(data) {
var json = jQuery.parseJSON(data);
json.recordsTotal = json.recordsTotal;
json.recordsFiltered = json.recordsFiltered;
json.data = json.data;
return JSON.stringify(json);
},
"dataSrc" : ""
},
"columns": [
{ "className" : "details-control", "orderable" : false, "data": "ActivityHistoryId" },
{ "data" : "ParentName" },
{ "data" : "ActivityName" },
{ "data" : "Effort" },
{ "data" : "Status" },
{ "data" : "Innovation" },
{ "defaultContent" : '<td><button class="btn btn-xs btn-primary" title="edit work activity" name="editWork"></button></div></td>' }]
});
Here is the JSON returned from my controller, which is valid.
{"draw":1,"recordsTotal":3,"recordsFiltered":3,"data":[{"ActivityHistoryId":1,"UserId":91,"WorkFlowId":4,"ActivityName":"Test Activity 1","ActivityDescription":"Description of Test Activity 1","Status":"\u003cspan class=\u0027badge badge-blue\u0027\u003eNot Started\u003c/span\u003e","Effort":10,"Innovation":false,"ParentId":2,"ParentName":"Test Result 1"},{"ActivityHistoryId":2,"UserId":91,"WorkFlowId":4,"ActivityName":"Test Activity 2","ActivityDescription":"Description of Test Activity 2","Status":"\u003cspan class=\u0027badge badge-blue\u0027\u003eNot Started\u003c/span\u003e","Effort":16,"Innovation":false,"ParentId":2,"ParentName":"Test Result 1"},{"ActivityHistoryId":3,"UserId":91,"WorkFlowId":4,"ActivityName":"Test Activity 3","ActivityDescription":"Description of Test Activity 3","Status":"\u003cspan class=\u0027badge badge-lightBlue\u0027\u003eIn Progress\u003c/span\u003e","Effort":25,"Innovation":false,"ParentId":5,"ParentName":"Test Result 2"}]}
And the datatable...
Any idea how to get BOTH the datatable to render data AND show the number of entries in the table? I find the documentation does not work for every scenario I try.
I used the following to see the data returned...
table.on('xhr', function () {
var json = table.ajax.json();
console.log(table.ajax.json());
});

If you remove dataSrc things should start working:
var table = $('#master').DataTable({
"processing": true,
"serverSide": true,
"columnDefs": [{
"targets": [0],
"visible": true,
"searchable": false
}],
"ajax": {
"type": "POST",
"url": "#Url.Action("
GetAllActivities ", "
Activities ")",
"data": {
"UserId": employeeId
},
"dataFilter": function(data) {
var json = jQuery.parseJSON(data);
json.recordsTotal = json.recordsTotal;
json.recordsFiltered = json.recordsFiltered;
json.data = json.data;
return JSON.stringify(json);
}
},
"columns": [{
"className": "details-control",
"orderable": false,
"data": "ActivityHistoryId"
}, {
"data": "ParentName"
}, {
"data": "ActivityName"
}, {
"data": "Effort"
}, {
"data": "Status"
}, {
"data": "Innovation"
}, {
"defaultContent": '<td><button class="btn btn-xs btn-primary" title="edit work activity" name="editWork"></button></div></td>'
}]
});
Glad that helped. :-)

I don't see problem with the data or server side code - it is the way you are assigning data.
I just assigned data without AJAX and it works see the fiddle https://jsfiddle.net/jituce/1naw041z/6/
var table = $('#master').DataTable( {
"processing": true,
"data":[{"ActivityHistoryId":1,"UserId":91,"WorkFlowId":4,"ActivityName":"Test Activity 1","ActivityDescription":"Description of Test Activity 1","Status":"\u003cspan class=\u0027badge badge-blue\u0027\u003eNot Started\u003c/span\u003e","Effort":10,"Innovation":false,"ParentId":2,"ParentName":"Test Result 1"},{"ActivityHistoryId":2,"UserId":91,"WorkFlowId":4,"ActivityName":"Test Activity 2","ActivityDescription":"Description of Test Activity 2","Status":"\u003cspan class=\u0027badge badge-blue\u0027\u003eNot Started\u003c/span\u003e","Effort":16,"Innovation":false,"ParentId":2,"ParentName":"Test Result 1"},{"ActivityHistoryId":3,"UserId":91,"WorkFlowId":4,"ActivityName":"Test Activity 3","ActivityDescription":"Description of Test Activity 3","Status":"\u003cspan class=\u0027badge badge-lightBlue\u0027\u003eIn Progress\u003c/span\u003e","Effort":25,"Innovation":false,"ParentId":5,"ParentName":"Test Result 2"}],
"serverSide": false,
"columnDefs" : [{
"targets" : [0],
"visible" : true,
"searchable" : false
}],
"columns": [
{
"className" : "details-control", "orderable" : false, "data": "ActivityHistoryId" },
{ "data" : "ParentName" },
{ "data" : "ActivityName" },
{ "data" : "Effort" },
{ "data" : "Status" },
{ "data" : "Innovation" },
{ "defaultContent" : '<td><div><button class="btn btn-xs btn-primary" title="edit work activity" name="editWork"></button></div></td>' }]});
I would say remove JSON.stringy or dataFilter from the AJAX and it should work fine.
Let me know if this helps.

Related

SQLSTATE[42S22]: Column not found: 1054 Unknown column 'deposits.Country' in 'where clause'

I am fetching the data accurately in my views. but when i try to search in my datatables it gives me above error.. UNKNOWN COLUMN.. I am not getting this if its working one time then why it gives error on SEARCHING
$deposits2 = DB::connection('mysql')
->table('deposits')
->join('users','users.id','=','deposits.user_id')
->select('deposits.*','users.Country')
->where('deposits.status','Approved');
Here is the error
Here is the code from my views file
<script>
$(document).ready( function () {
var table = $('#myTable2').DataTable( {
processing: true,
"serverSide": true,
"ajax": {
"url": "{{url('dashboard/adeposits/json')}}",
"type": "GET"
},
"deferRender": true,
"columns":
[
{ "data" : "id", "title" : "Portfolio#", "searchable": true,
"render": function ( data, type, row, meta ) {
var itemID = data;
return '<a data-toggle="modal" data-target="#DDetailsModal" href="#" onclick="viewDetailsFunc('+row.id+')">D-'+itemID+'</a>';
}
},
{ "data" : "unique_id", "title" : "UserID", "orderable": true, "searchable": true },
{ "data" : "Country", "title" : "Country", "orderable": true, "searchable": true },
In your datatable you can set field name in your columns.
{ "data" : "Country", name: "users.Country", "title" : "Country", "orderable": true, "searchable": true },
$deposits2 = DB::connection('mysql')
->table('deposits')
->select('deposits.*','users.Country')
->join('users','users.id','=','deposits.user_id')
->where('deposits.status','Approved')
->get();

KendoUI Grid Server Binding Example

I have successfully set up several KendoUI Grids, but I cannot get one using server-side paging to work.
I modified my rest service so I will return a total value (hard coded right now).
I also modified my javascript source. [see below].
Usually I just get a blank screen.
Would be very grateful for any assistance.
Script:
$(document).ready(function(){
// Setup Rest Service
var loc = ( location.href );
var url = loc.substring( 0, loc.lastIndexOf( "/" ) ) + "/xpRest.xsp/test/";
dataSource = new kendo.data.DataSource({
pageSize: 20,
serverPaging: true,
serverFiltering: true,
serverSorting: true, transport : {
read : {
url : url + "READ",
dataType : "json"
},
type : "READ"
},
schema : {
total: "total",
model : {
id : "unid",
fields : {
unid : {
type : "string",
nullable : false
},
tckNbr : {
type : "string",
editable : false
},
tckSts : {
type : "string",
editable : false
}
}
}
}
});
grid = $("#grid-databound-dataItem").kendoGrid({
dataSource : dataSource,
height: 550,
filterable: true,
sortable: true,
pageable: true,
columns : [
{field : "tckNbr", title : "Number", type: "string"},
{field : "tckSts", title : "Status", type: "string"}
]
}).data("kendoGrid");
});
JSON feed:
[
{
"total":100,
"data":
[
{
"tckNbr":"3031",
"tckSts":"1 Not Assigned",
"unid":"0014DA9095BF6D638625810700597A36",
"tckReqs":"Bryan S Schmiedeler",
"tckNts":
[
"Bryan DeBaun"
],
"tckBUs":
[
"NAP\/IFI"
],
"tckApps":"GTM",
"tckType":"Issue",
"tckPriority":"Medium"
},
{
"tckNbr":"3031",
"tckSts":"1 Not Assigned",
"unid":"00598976D88226D2862581070059AD25",
"tckReqs":"Bryan S Schmiedeler",
"tckNts":
[
"Bryan DeBaun"
],
"tckBUs":
[
"NAP\/IFI"
],
"tckApps":"GTM",
"tckType":"Issue",
"tckPriority":"Medium"
}
]
}
]
Correct your JSON feed, you need to return object not array:
{
"total": 10,
"data": []
}
After that say what is data and what is total in you schema:
schema : {
total: "total",
data: "data",
.
.
}
Note: if you mock data like in your case (total: 100, data -> size is 2) your paginatio will be created by total parameter not data itself. You will see 5 pages with same data (that is ok).

ExtJS Create Multiple Rows in Gird When Using Nested JSON

I am using Ext JS 6, trying to get a grid to have a row for each area, country, and city. I have no control over my backend and the format of my JSON (see below). I think I have my store correct (see below). I am wondering what I need to do in order to display a record for each nested item in the grid. Ext JS is determined to only have one record in this grid. My real question is what should my model look like?
JSON
{
"locations" : [
{
"type" : "area",
"name" : "Middle East",
"country" : [
{
"type" : "country",
"name" : "Afghanistan",
"city": [
{
"type" : "city",
"name" : "Bagram",
"data" : [
{
"data1" : 5,
"data2" : 10
},
{
"data1" : 2,
"data2" : 9
}
]
},
{
"type" : "city",
"name" : "Kabul",
"data" : [
{
"data1" : 3,
"data2" : 7
},
{
"data1" : 6,
"data2" : 2
}
]
}
]
}
]
}
]
}
Store
Ext.define('App.store.Locations', {
extend: 'Ext.data.Store',
model: 'App.model.Location',
proxy: {
type: 'ajax',
url: 'data/location.json',
reader: {
type: 'json',
rootProperty: 'locations'
}
},
autoLoad: true
});
I think you have to use Ext.data.reader.Reader.transform(), like this:
Ext.define('App.store.Locations', {
extend: 'Ext.data.Store',
model: 'App.model.Location',
proxy: {
type: 'ajax',
url: 'data/location.json',
reader: {
type: 'json',
rootProperty: 'locations',
transform: {
fn: function(rawData) {
//Your parse data logic here
var data = [],
locationTypes = ['area', 'country', 'city'],
parseData = function(dataPart) {
data.push({
type: dataPart['type'],
name: dataPart['name']
});
for(var i = 0; i < locationTypes.length; ++i) {
if(Object.prototype.hasOwnProperty.call(dataPart, locationTypes[i])) {
for(var j = 0; j < dataPart[locationTypes[i]].length; ++j) {
parseData(dataPart[locationTypes[i]][j]);
}
}
}
};
for(var i = 0; i < rawData.length; ++i) {
parseData(rawData['locations'][i]);
}
return (data);
}
}
}
},
autoLoad: true
});
Check this working fiddle

jsTree populated with JSON string

i got this jsTree:
$(function () {
$("#tree").jstree({
"json_data" : {
"data" : [
{
"data" : "<?php echo $db_obj->getValue('article_group_name') ?>",
"metadata" : { id : 23 },
"children" : [ "Child 1", "A Child 2" ]
}
]
},
"plugins" : ["themes","json_data", "ui" ]
});
});
I would like to populate it with DB data. The Childs should be line from the database.
I json_encoded the table data, it looks something like this:
[Object { article_id=
"4949"
, article_name_internal=
"Nachtlampe Lumilove Barbapapa"
}, Object { article_id=
"4947"
, article_name_internal=
"Wanduhr Silk von Koziol"
},
Whene i click one of the childs it should go to that page. Not sure how i can populate the tree with this data. Any instructions?
Each node for jsTree have a list of attributes that you can set to it.
just use the attr property in your JSON and add an array of property-value pairs that represent the data you want.
one of these properties should be an href containing the URL for the page you want to opent once someone clicks the node for your jsTree.
now your server should return the data like this.
{
"data": "Root",
"attr": {
"id": "1",
"rel": "Root",
"type": 0
},
"children": [{
"data": "Test 1",
"attr": {
"id": "2",
"href": "http://www.google.com"
"rel": "OrganizationalUnit",
"type": 1
},
"children": [],
"state": "open"
}],
"state": "open"
}
and your JSTree inint function should do something like that:
k_OrgTree = $("#OrgTree").jstree({
json_data: {
ajax: {
url: "/Administration/PopulateTree",
type: "POST",
dataType: "json",
contentType: "application/json charset=utf-8",
success: function (data) { }
}
},
themes: currentTheme,
types: {
valid_children: [k_Root],
types: {
Root: {
valid_children: [k_OrganizationalUnit, k_Calendar],
icon: { image: "/Content/Administration/Images/Root/Root_32x32.png" },
delete_node: false,
},
OrganizationalUnit: {
valid_children: [k_OrganizationalUnit, k_Calendar, k_User],
icon: { image: "/Content/Administration/Images/OrganizationalUnit/OrganizationalUnit_32x32.png" },
},
Calendar: {
valid_children: ["none"],
icon: { image: "/Content/Administration/Images/Calendar/Calendar_32x32.png" },
create_node: false
},
User: {
valid_children: ["none"],
icon: { image: "/Content/Administration/Images/User/User_32x32.png" },
create_node: false
}
}
},
plugins: ["themes", "json_data", "types", "ui"]
});

Datatables columns and JSON Format

I have setup a datatables based on the following html
<script>
$('#tableListing').dataTable({
"bAutoWidth" : true,
"bProcessing" : true,
"bServerSide" : true,
"sAjaxSource" : '${actionUrl}',
"aoColumns":[
{ "sTitle": "ID", "mData": "id" },
{ "sTitle": "Username", "mData": "userName" },
{ "sTitle": "Password", "mData": "password" }
]
}
});
</script>
<table id="tableListing" class="display datatable">
<thead>
<tr>
<th><spring:message code="columnLabel.id" /></th>
<th><spring:message code="columnLabel.username" /></th>
<th><spring:message code="columnLabel.enabled" /></th>
</tr>
</thead>
</table>
And the JSON response from server is [1,"abiieez",true] and it works nicely. However I have changed the response from server into something like:
*Edit (updated JSON response) *
{
"iTotalDisplayRecords": 11,
"iTotalRecords": 11,
"aaData": "[{\"creationTime\":0,\"enabled\":true,\"id\":1,\"loginDuration\":0,\"online\":false,\"password\":\"asdasd\",\"userName\":\"abiieez\"},{\"creationTime\":0,\"enabled\":false,\"id\":105,\"loginDuration\":0,\"online\":false,\"password\":\"asdasd\",\"userName\":\"asd1212123\"},{\"creationTime\":0,\"enabled\":false,\"id\":106,\"loginDuration\":0,\"online\":false,\"password\":\"asdsdasd\",\"userName\":\"asdasd23123\"},{\"creationTime\":0,\"enabled\":false,\"id\":107,\"loginDuration\":0,\"online\":false,\"password\":\"asdsdasd\",\"userName\":\"asdasd23123\"},{\"creationTime\":0,\"enabled\":false,\"id\":108,\"loginDuration\":0,\"online\":false,\"password\":\"anak jalanan\",\"userName\":\"alibaba90\"},{\"creationTime\":1351338218227,\"enabled\":false,\"id\":109,\"loginDuration\":0,\"online\":false,\"password\":\"asdasdasda\",\"userName\":\"asdasdasda\"},{\"creationTime\":1351338263527,\"enabled\":false,\"id\":110,\"loginDuration\":0,\"online\":false,\"password\":\"asdasdasda\",\"userName\":\"asdasdasda\"},{\"creationTime\":1351338265078,\"enabled\":false,\"id\":111,\"loginDuration\":0,\"online\":false,\"password\":\"asdasdasda\",\"userName\":\"asdasdasda\"},{\"creationTime\":1351338266329,\"enabled\":false,\"id\":112,\"loginDuration\":0,\"online\":false,\"password\":\"asdasdasda\",\"userName\":\"asdasdasda\"},{\"creationTime\":1351338267247,\"enabled\":false,\"id\":113,\"loginDuration\":0,\"online\":false,\"password\":\"asdasdasda\",\"userName\":\"asdasdasda\"}]",
"sEcho": "1"
}
The above json is not accepted by the datatables, I believe because the number of columns do not match.
Is there a way for me to retrieve this json object and pick which columns I would like to show on the tables on the client side ?
You can use mData property in aoColumns like this:
$(document).ready(function() {
$('#tableListing').dataTable({
"aoColumns":[
{ "sTitle": "user", "mData": "userName" },
{ "sTitle": "pass", "mData": "password" },
...
]
"bAutoWidth" : true,
"bProcessing" : true,
"bServerSide" : true,
"sAjaxSource" : '${actionUrl}'
});
});