I want to show my record data into table enhanced by jQuery DataTables plugin using server-side processing mode. I followed the docs Datatables Server side but in my table I can't show the record data.
Here's my Ajax response:
{
"draw": 0,
"recordsTotal": 4,
"recordsFiltered": 4,
"data": [
[
27,
"Brokoli Segar",
"25000"
],
[
28,
"Tomat Super",
"2000"
],
[
29,
"Oreo Roll",
"9400"
],
[
30,
"Close Up Toothpaste Fire Freeze",
"7000"
]
],
"queries": [
{
"query": "select count(*) as aggregate from (select '1' as row_count from `product` where `product`.`deleted_at` is null) count_row_table",
"bindings": [],
"time": 0.79
},
{
"query": "select `id`, `name`, `price` from `product` where `product`.`deleted_at` is null",
"bindings": [],
"time": 0.68
}
],
"input": []
}
My HTML table:
<table class="table table-bordered" id="tabelStokBarang">
<thead>
<tr>
<th>ID</th>
<th>Nama Barang</th>
<th>Harga Barang</th>
</tr>
</thead>
</table>
My JavaScript:
$('#tabelStokBarang').DataTable({
processing: true,
serverSide: true,
ajax: '{!! route('admin.product.stock.getAll') !!}',
columns: [
{ data: 'id', name: 'id' },
{ data: 'name', name: 'name' },
{ data: 'price', name: 'price' }
]
});
My result in table is still "No data available". I don't know what I've missed.
Remove columns to match your data because you're returning rows as arrays but with columns property expecting rows to be objects with properties id, name and price. See the code below:
$('#tabelStokBarang').DataTable({
processing: true,
serverSide: true,
ajax: '{!! route('admin.product.stock.getAll') !!}'
});
Another potential problem is that your draw parameter is 0. Your script should return draw parameter with the same value of the draw parameter in the request. I believe it starts at 1 and then increments with every request.
From the manual:
draw
The draw counter that this object is a response to - from the draw parameter sent as part of the data request. Note that it is strongly recommended for security reasons that you cast this parameter to an integer, rather than simply echoing back to the client what it sent in the draw parameter, in order to prevent Cross Site Scripting (XSS) attacks.
Related
I have a datatable that retrieves json data from an api. The first column of the table should only contain a checkbox. However, when retrieving the data it populates the first column as well.
$.getJSON('https://api.myjson.com/bins/o44x', function(json) {
$('#parametrictable').DataTable({
data : json.data,
columns : json.columns,
columnDefs: [ {
orderable: false,
className: 'select-checkbox',
targets: 0
} ],
select: {
style: 'os',
selector: 'td:first-child'
},
order: [[ 1, 'asc' ]]
})
});
Is there any way that I can set that the data should only populate starting from the second column, leaving the first column to only contain the checkbox?
You can fix this issue by updating the api or in your js code just updating the data key value to null for first object in the json.columns array like:
$.getJSON('https://api.myjson.com/bins/o44x', function(json) {
json.columns[0].data = null;
json.columns[0].defaultContent = '';
$('#parametrictable').DataTable({
data: json.data,
columns: json.columns,
.... your rest of code
})
});
EDIT:
I meant what your suggestion only did was hide the data that was overlapping with the checkbox. I don't want it hidden. I want the first column to be, by default, only checkboxes. and the overlapping data should be on the 2nd column.
You can update your API like this to achieve that:
"columns": [
{
"data": null,
"defaultContent": ""
},
{
"data": "DT_RowId",
"title": "Id"
},
{
"data": "supplier",
"title": "supplier"
},
{
"data": "color",
"title": "color"
}
],
Or, you can update your code without modifying your API like:
$.getJSON('https://api.myjson.com/bins/o44x', function(json) {
// Add object for checkbox at first position
json.columns.unshift({"data": null, "defaultContent": ""});
$('#parametrictable').DataTable({
data: json.data,
columns: json.columns,
....your rest of code
})
});
I have a pretty simple datatables object. I bind it to an array of objects, specify the data fields and it works. The problem is when I try to implement the CSV export. It always only wants to export the first row of the table. Any ideas?
Here's where my code stands at the moment. And to be sure, I've made sure that the button and select libraries are included but that has made no difference.
<table id="tblData" style="display:none;">
<thead>
<tr id="trDataTableHeader">
<th data-s-type="string">Name</th>
<th data-s-type="string">Address</th>
<th data-s-type="string">Phone</th>
<th data-s-type="string">Website</th>
<th data-s-type="string">Types</th>
</tr>
</thead>
</table>
...
table = $('#tblData').DataTable({
dom: 'rtB',
data: tableData,
columns: [
{ "data": "name" },
{ "data": "address" },
{
"data": "phone_number",
defaultContent: ""
},
{
"data": "website",
defaultContent: ""
},
{
"data": "types",
defaultContent: ""
},
],
buttons: [{
extend: "csv",
text: "Export",
exportOptions: {
modifier: { search: "none", selected: false}
}
}],
select: false,
lengthChange: false,
sort: false,
paging: false
});
After a lot of digging, I made an accidental discovery when I removed the column data type specifications. I got an error message that str.replace is not a function.
Turns out that the parseInt and parseFloat base functions were being overridden by another developer on that page and was causing a problem but DataTables was too graceful to tell me.
This is why you don't override base javascript functions unless you absolutely have to.
I am using Jquery Data-table and binding the Large unsorted object data to datatable. My code is below:
var ExpenceDataTableElement = $('#ExpenceDataTable').DataTable({
data: Data,
pageLength: 10,
"bSort": false,
"autoWidth": false,
columns: [{
"className":"clsAction",
"data": "TimesheetUID",
"title": "Action",
"render": (data, type, row) => '<input class="checkbox" type="checkbox" />',
"width": "4%",
"visible":true
},
{
"className":"clsPeriodName",
"data": "PeriodName",
"title": "Timesheet Name",
"visible":true
},
{
"className":"clsTSPeriodStatus",
"data": "Open",
"title": "Timesheet Period <br> Status",
"render":function(data,type,row){ if(data == 1){return " Open"}else{return " close"}},
"width": "10%",
"visible":true
}
],
"oLanguage": {
"sEmptyTable": "No Records found."
}
});
The data contains more than 15 thousands of records, it contains the flag like 'Open' OR 'Close'. Currently I am using the for loop to sort the data and bind it to the data - table. Means if data have 15 thousand of records and it contains 7 thousands of 'Open' flag records, it takes long time to sort & bind the data to Datatable. Hence Is there any way to check the condition in 'columns:' if flag is not 'Open' then continue to the next iteration??
You could use the filter method to first filter the objects with 'open' status in the array.
someObject.columns.filter(x => x.data == 'open')
This will filter out only those with the flag 'open'. You can cache it into a variable for further work.
I have a DataTable which I fill with data from the server side. The table is being filled the right way. When I use pagination, the server side is called again and produces the JSON data for the next page. The data is right. But the table isn't refreshing. According to the Datatables documentation I know that I should use the draw() function somehow, but I don't know where to call it.
This is my html table:
<table id="table-esemenyLista" class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>Id</th>
<th>Dátum</th>
<th>Esemény</th>
</tr>
</thead>
<tbody id="esemenyListBody" class="text-primary">
</tbody>
</table>
This is the Jquery-datatable code connected to it:
$( document ).ready(function() {
esemenyListaTable = $("#table-esemenyLista").DataTable({
"processing" : true,
"serverSide" : true,
"paging" : true,
"searching" : false,
"lengthChange" : false,
"drawCallback": function( settings ) {
console.log('redrawn');
},
"ajax" : contextPath + "/historyContent.do"
});
});
This is the JSON object I get from the server-sid for the first time (appears right):
{
"draw":1,
"recordsTotal":16,
"recordsFiltered":16,
"data":[
[
1,
"2016-07-23",
"text1"
],
[
12,
"2016-10-04",
"text2"
],
[
13,
"2016-10-04",
"text3"
],
[
16,
"2016-10-18",
"text4"
],
[
17,
"2016-11-05",
"text5"
],
[
18,
"2016-11-14",
"text6"
],
[
19,
"2016-11-15",
"text7"
],
[
20,
"2016-11-16",
"text8"
],
[
22,
"2016-11-16",
"text9"
],
[
23,
"2016-11-17",
"text10"
]
]
}
After turning to the second page, I get the following JSON object, which is which syntax is right, but doesn't appear:
{
"draw":1,
"recordsTotal":16,
"recordsFiltered":16,
"data":[
[
24,
"2016-11-17",
"text11"
],
[
25,
"2016-11-23",
"text12"
],
[
26,
"2016-11-23",
"text13"
],
[
27,
"2016-11-23",
"text16"
],
[
28,
"2016-11-24",
"text17"
],
[
29,
"2016-11-25",
"text18"
]
]
}
The drawCallBack function only writes the log the first time. How should I call the draw method? After I red some other questions related to mine here on StackOverflow, I know I should clear, and then redraw the table, but how? Could someone help me please?
You have to return the right draw index.
So the second one has to be "draw":2.
I don't know your serverside language, in PHP you can get the draw index with $_GET['draw']
I'm a first time user of jqGrid, so far I went trough official examples, I'm interested in loading data into grid either using json.
I'm currently looking at, Loading data(JSON Data):
http://trirand.com/blog/jqgrid/jqgrid.html
Here is a bit of javascript that creates grid :
jQuery("#list2").jqGrid(
{
url : '<c:url value="${webappRoot}/getdetails" />',
datatype : "json",
colNames : [ 'id', 'Location', 'Country Code', 'Type', 'Interval',
'Version', 'Last Active', 'Last Login', 'NOTE' ],
colModel : [
{ name : 'id', width : 10 },
{ name : 'location', width : 75 },
{ name : 'countryCode', width : 50 },
{ name : 'type', width : 40 },
{ name : 'interval', width : 30 },
{ name : 'version', width : 45 },
{ name : 'lastactive', width : 50, align : "right" },
{ name : 'lastlogin', width : 50, sortable : false },
{ name : 'note', width : 50, sortable : false}
],
rowNum : 10,
rowList : [ 10, 20, 30 ],
pager : '#pager2',
width: gridWidth,
sortname : 'id',
viewrecords : true,
sortorder : "desc",
caption : "JSON Example"
});
jQuery("#list2").jqGrid('navGrid', '#pager2',
{ edit : false, add : false, del : false});
${webappRoot}/getdetails transforms path to my project like http://localhost/myProject/getdetails, I'm using spring MVC(it might be irrelevant).
When I look in firebug this generates this http request :
GET http://localhost/newProject/getdetails?_search=false&nd=1304638787511&rows=10&page=1&sidx=id&sord=desc
200 OK
135ms
Here is the response :
{
"id": 1,
"location": "office_2782",
"countryCode": "UK",
"quarter": "500",
"version": "v3.05",
"lastactive": "yesterday",
"lastlogin": "today",
"note": "no note",
"type": "read-only"
}
When I navigate to JSON tab it all seems same as this, any idea what I'm doing wrong?
I'm trying to load only one record for start, and I can't get it working, any help is appriciated.
First of all you are not the first person who has problems understanding how the JSON data should be constructed, what the parameters sent from jqGrid to the server mean and so on. The official jqGrid documentation doesn't contain enough introduction, so the first steps of the jqGrid usage can be a little more difficult than one expect.
The problem which exists in your JSON response from the server is that it contains only one item of data instead of an array (or list) of items representing the grid rows. The data should be at least
[
{
"id": 1,
"location": "office_2782",
"countryCode": "UK",
"quarter": "500",
"version": "v3.05",
"lastactive": "yesterday",
"lastlogin": "today",
"note": "no note",
"type": "read-only"
}
]
or better as
{
"total": 1,
"page": 1,
"records": 1,
"rows": [
{
"id": 1,
"location": "office_2782",
"countryCode": "UK",
"quarter": 500,
"version": "v3.05",
"lastactive": "yesterday",
"lastlogin": "today",
"note": "no note",
"type": "read-only"
}
]
}
or even as
{
"total": 1,
"page": 1,
"records": 1,
"rows": [
{
"id": 1,
"row": [ "1", "office_2782", "UK", "500", "v3.05",
"yesterday", "today", "no note", "read-only" ]
}
]
}
or
{
"total": 1,
"page": 1,
"records": 1,
"rows": [
[ "1", "office_2782", "UK", "500", "v3.05", "yesterday", "today",
"no note", "read-only" ]
]
}
The reason of such strange at the first glance JSON data is that jqGrid is designed to support paging, sorting and filtering/searching of data implemented on the server. So the parameters rows=10&page=1&sidx=id&sord=desc from the url sent to the server mean that jqGrid asks the server to get the first page (page=1) of the data with the page having 10 rows per page (rows=10). The data should be previously sorted by id (sidx=id) in the descending order (sord=desc). If you has small number of rows (under some hundert for example) you can use client based sorting, paging and filtering if you add loadonce:true parameter of the jqGrid, but the server based implementation allows you to work with really large dataset having many hundred thousands rows of data with very good performace.
I recommend you to read my this answer where I tried to explain how the additional elements of the server response "total", "page" and "records" will be used. The values of the parameters can be encoded in JSON either as numbers or as strings (on your taste).
If the user clicks on the column header of the 'location' column for example jqGrid will send new request to the server having sidx=location&sord=asc in the url. So it is important to understand, that the server can be asked to provide the data for the grid not once per grid, but many times and the request will contain some parameters chosen by the user who works with the jqGrid.
Defining of jsonReader (and sometimes additional jsonmap parameters for every column) you describe the structure of the server response. Using the information jqGrid read the response and fill the grid.
The demo shows that with the corresponding jsonReader you can read even your original JSON data.
The last advice for you from me would be to consider at the beginning to use loadError event handle which helps to inform the user about the errors reported by the server. In the answer I have shown how it can be implemented in the case of ASP.NET MVC. I don't use spring MVC myself so I can't give you direct examples of how to better implement the error reporting in spring MVC, but the main idea is the same in any server technology: in case of errors the server should respond with the response having an error HTTP status code. Inside of your implementation of the loadError event handle you decode the response and display the information about the error.