I am trying to build a datatable (1.10.7) based on an input of a javascript var filled with JSON data. While I've successfully used datatables with ajax sources, I've never attempted to just provide my own variable, but I need to in this case.
Here's my variable:
json = [
{"dateReceived":"2015-01-01","designCustomer":"MULTITEST 1","designCustomerLocation":"SUNNYVALE, CA"},
{"dateReceived":"2016-04-05","designCustomer":"MULTITEST 2","designCustomerLocation":"SUNNYVALE, CA"},
{"dateReceived":"1982-04-18","designCustomer":"MULTITEST 3","designCustomerLocation":"SUNNYVALE, CA"}
]
According to DataTables' page on Javascript-Sourced Data,
This is achieved using the dataDT option in the initialisation object, passing in an array of data to be used (like all other DataTables handled data, this can be arrays or objects using the columns.dataDT option).
I'm confused by the differences in their test string, and in mine:
var dataSet = [
['Trident','Internet Explorer 4.0','Win 95+','4','X'],
['Trident','Internet Explorer 5.0','Win 95+','5','C'],
['Trident','Internet Explorer 5.5','Win 95+','5.5','A'],
['Trident','Internet Explorer 6','Win 98+','6','A'],
['Trident','Internet Explorer 7','Win XP SP2+','7','A']
Namely, their test variable doesn't contain field names, while mine does.
Here is the code that I've written to try and parse my variable, json:
var table = $('#ltc-table').DataTable( {
"data" : json,
"columns" : [
{ "title" : "designCustomer" },
{ "title" : "designCutomerLocation" },
{ "title" : "dateReceived" },
],
"lengthMenu": [ 25, 50, 101 ],
"oLanguage": {
"sSearch": "Filter Results: "
}
});
It seems, based on the page I linked above, that I'm doing this correctly, but I'm getting errors instead:
Uncaught Error: DataTables warning: table id=ltc-table - Requested unknown parameter '0' for row 0.
Any tips?
If you want to use objects as data source instead of arrays, you need to bind the columns using the columns.data options:
json = [
{"dateReceived":"2015-01-01","designCustomer":"MULTITEST 1","designCustomerLocation":"SUNNYVALE, CA"},
{"dateReceived":"2016-04-05","designCustomer":"MULTITEST 2","designCustomerLocation":"SUNNYVALE, CA"},
{"dateReceived":"1982-04-18","designCustomer":"MULTITEST 3","designCustomerLocation":"SUNNYVALE, CA"}
];
var table = $('#ltc-table').DataTable( {
"data" : json,
"columns" : [
{ "data" : "designCustomer" },
{ "data" : "designCustomerLocation" },
{ "data" : "dateReceived" }
],
"lengthMenu": [ 25, 50, 101 ],
"oLanguage": {
"sSearch": "Filter Results: "
}
});
See demo
Related
i'm trying to generate a table with Datatables.
I receive a json from my controller, here a sample:
this json can change (number of columns, name of the columns) and I can build my table with the good number of column and the good name.
My question is:
How can i do to have a dropdown when the "liste" have an array and a simple input when it's null?
Is it even possible?
EDIT :
I forget to explain something. The Json that I receive is a json to build the table not to fill it. So is it possible to do a columnsDef before the datas are in the cell.
EDIT n°2:
I used the solution that I accepted, but the problem was with my json. I tried to send a json to build and a json to fill the table. So I change my json and I send the list of options in the json to fill the table.
Hope it will help other people.
Thanks
Here are two solutions:
1) With a drop-down.
2) With a formatted array (as an alternative).
1) With a Dropdown
The end result looks like this:
The datatables definition is this:
<script type="text/javascript">
var dataSet = { "records" : [
{ "data" : "123456789",
"liste" : null,
"name" : "Nombre Enfants"
},
{ "data" : "5678901234",
"liste" : [ "Oui", "Non" ],
"name" : "Transport"
}]};
$(document).ready(function() {
$('#example').DataTable( {
data: dataSet.records,
columnDefs: [
{ targets: [ 0 ],
title: "Data",
data: "data" },
{ targets: [ 1 ],
title: "Liste",
data: function ( row ) {
if (row.liste == null) {
return null;
} else {
return buildDropdown(row.liste);
}
} },
{ targets: [ 2 ],
title: "Name",
data: "name" }
]
} );
function buildDropdown(data) {
var dropdown = "<select>";
for (var i = 0; i < data.length; i++) {
var option = "<option value=\"" + data[i] + "\">" + data[i] + "</option>";
dropdown = dropdown + option;
}
dropdown = dropdown + "</select>";
return dropdown;
}
} );
</script>
It builds a drop-down based on the assumption that a non-null value is an array. This may not always be the case in your data - just an assumption on my part.
2) With a formatted array
Just in case this is also of interest, DataTables has a built-in syntax for formatting array data, so it is displayed in a cell like this:
In this case, you no longer need the drop-down builder function. Everything else is the same as option (1) except for this part:
{ targets: [ 1 ],
title: "Liste",
data: "liste[, ]" },
Specifically, the [, ] notation lets you format the array data.
I mention this only because it lets you display all the array data in the cell, rather than neeeding to click a drop-down. But that is just a suggestion.
You may find that other functions such as searching and sorting are better with this option.
Update
The question has clarified that the table needs to be built dynamically from the data provided in the JSON.
You can pass variables to the datatables initializer - for example:
var col1 = { targets: [ 0 ], title: "Data", data: "data" };
var col2 = { targets: [ 1 ], title: "Liste", data: "liste" };
var col2 = { targets: [ 2 ], title: "Name", data: "name" };
var dynamicCols = [ col1, col2, col3 ];
The above col1 variable defines the title for the column, and where the column will get its data (from the dataSet.data fields).
The dynamicCols variable can then be used in a columnDefs as follows:
$(document).ready(function() {
$('#example').DataTable( {
data: dataSet.records,
columnDefs: dynamicCols
} );
However, I am not aware of a way to include a function in a columndef, using this approach (for example to present a cell's data as a drop-down, if needed).
There are additional techniques which can be used to make a datatable even more dynamic - several examples are available online - for example here. Without seeing a more detailed example of the JSON being provided, I am not sure if there are any additional suggestions I can make.
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.
I'm using Datatables to represent data from a JSON.
My JSON is as follows:
[{"name": "John Doe", "email": "john#gmail.com", "address" : "blah"}]
In Datatables I can easily show these 3 pieces of info in 3 diff columns using the following:
columnDefs = [
{ "mData": "name", "aTargets":[0] },
{ "mData": "email", "aTargets":[1] },
{ "mData": "address", "aTargets":[2] }
];
But the problem is that I want to show "name" and "email" in 1st column and then "address" in the 2nd column.
How can I do that? Please guide.
to make it more short, you can write it like this
"aoColumns": [
{ "mData": "i_id" },
{ "mData": "i_name" },
{ "mData": function (data, type, dataToSet) {
return data.i_id + "<br/>" + data.i_name;
}}
],
and the result
columnDefs = [
{
data: {name : "name", email : "email", address : "address"},
mRender : function(data, type, full) {
return data.name+' '+data.email+' '+data.address;
}
}
];
The above code can render multiple data in a column of a datatable.
Rather than putting either the name or e-mail in the first column in the column definition, you can use a function to get and print whatever data you want. See the mData section on this page for more details: https://datatables.net/usage/columns. In my example below I use aoColumns because I tested my answer that way; but in the link referenced they used aoColumnDefs and provide elaboration on the type and dataToSet fields. This approach should hopefully help anyone reading this answer whether you use aoColumns or aoColumnDefs.
For example, using aoColumns rather than aoColumnDefs:
aoColumns = [
{ "mData": getNameAndEmail },
{ "mData": "address" }
];
Then define the getNameAndEmail function in JavaScript scope which takes three parameters: the data passed back, the type of action on the data, and if the type is "set" then the data to set.
function getNameAndEmail(data, type, dataToSet) {
return data.name + "<br>" + data.email;
}
[You can use syntax like this:
It worked for me.]
"columnDefs":[{
"targets":0,//column index
"data":"first_name",
"render":function(data,type,row){
return data+' '+row['last_name'];
}
}]
[thanks]
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.
I am trying to load the Flexigrid by using a JSON String which is returned by a WCF Service.
My Service has a public string GetContacts(string CustomerID) method and it returns a Json string.
That JSON string is created from a List object by using
System.Web.Script.Serialization.JavaScriptSerializer class. So, my aim is to bind the JSON string to the my Flexigrid as objects. I convert the web service result to objects using
var customer = eval("("+result+")");
The result is the JSON string being returned from service. Is there any way to bind customer objects to Flexigrid?
Flexigrid requires a format as follows in json
EDIT Thanks to EAMann for the format update.
total: (no of rec)
page : (page no)
rows : [{cell: [ (col1 value) , (col2 value) ,.. ] },
{cell: [ (col1 value) , (col2 value) ,.. ] }]
in order to bind the data to the grid i prefer sending the data across the wire and then formatting it on the client, but thats just me heres an example
function formatCustomerResults(Customers) {
var rows = Array();
for (i = 0; i < Customers.length; i++) {
var item = Customers[i];
//Do something here with the link
var link = "alert('opening item " + item.DealGuid + "');"
rows.push({
cell: [item.DealId,
item.Created,
item.CurrentStatus,
item.LastNote,
'<a href="javascript:void(0);" onclick="' + link + '" >view</a>'
]
});
}
return {
total: Customers.length,
page: 1,
rows: rows
};
}
and then all you need is
$("#FlexTable").flexAddData(formatCustomerResults(eval(data)));
ps this last bit is jquery syntax
almog.ori's answer is almost perfect. In fact, that's just about how I had built things before trying to Google the solution. One exception, though.
The JSON object should be:
total: (no of rec),
page : (page no),
rows : [{cell: [ (col1 value) , (col2 value) ,.. ] },
{cell: [ (col1 value) , (col2 value) ,.. ] }]
If you neglect the array format of the rows element, you'll end up choking Flexigrid and throwing all sorts of errors. But I've verified that this works flawlessly as long as you remember which parts of the script take JSON objects and which parts take arrays of JSON objects.
This is an older post but I thought I would add another way to use the excellent script provided by almog.ori.
The OP said that his data was being returned from a WCF service. If you mark the operation contract body style as bare you can use the preProcess property to add your formatCustomerResults (or other function) function to initially load the grid.
Like this:
$("#gridContainer").flexigrid({
url: '/YourService.svc/..',
method: 'GET',
dataType: 'json',
preProcess: formatCustomerResults,
...
});
function formatCustomerResults(data){
...
Hope this helps someone.
Make sure also that you are using the correct HTTP method, default is POST
To use GET:
$("#gridContainer").flexigrid({
url: '/json/files.json',
method: 'GET',
dataType: 'json',
...
preProcess solution by nameEqualsPNamePrubeGoldberg works perfect.
This is how my custom function for preProcess looks like.
var rows = Array();
$.each(data.rows,function(i,row){
rows.push({id:row.val1, cell:[row.val2,row.val3]});
});
return {
total:data.total,
page:data.page,
rows:rows
};
I recommend you to follow this sample to parse your JSON code and make requests to server:
Step 1: Parse using a function
function parsedForm(json)
{
var h = "";
if (json.post.val1)
h += "<b>Value 1</b>: " + json.post.val1 + "<br />";
h += "<b>Value 2</b>: " + json.post.val2 + "<br />";
h += "<b>Value 3</b>: " + json.post.val3 + "<br />";
if (json.post.val4)
h += "<b>Value 4</b>: " + json.post.val4 + "<br />";
$('#fdata').empty().html(h);
$('.formdata').slideDown();
return json;
}
Step 2: The flexigrid view code
$("#flex1").flexigrid({
url: 'post2.php',
dataType: 'json',
colModel : [
{display: 'ISO', name : 'iso', width : 40, sortable : true, align: 'center'},
{display: 'Name', name : 'name', width : 180, sortable : true, align: 'left'},
{display: 'Printable Name', name : 'printable_name', width : 120, sortable : true, align: 'left'},
{display: 'ISO3', name : 'iso3', width : 130, sortable : true, align: 'left', hide: true},
{display: 'Number Code', name : 'numcode', width : 80, sortable : true, align: 'right'}
],
searchitems : [
{display: 'ISO', name : 'iso'},
{display: 'Name', name : 'name', isdefault: true}
],
sortname: "iso",
sortorder: "asc",
usepager: true,
title: 'Countries',
useRp: true,
rp: 15,
showTableToggleBtn: true,
width: 700,
onSubmit: addFormData,
preProcess: parsedForm,
height: 200
});
Step 3: Additonally, you can validate or serialize the data to request server
function addFormData(){
//passing a form object to serializeArray will get the valid data from all the objects, but, if the you pass a non-form object, you have to specify the input elements that the data will come from
var dt = $('#sform').serializeArray();
$("#flex1").flexOptions({params: dt});
return true;
}
$('#sform').submit(function (){
$('#flex1').flexOptions({newp: 1}).flexReload();
return false;
});
I hope it will help!
Make sure you have the dataType option set to json.
$('#gridContainer').flexigrid({
singleSelect: true,
showToggleBtn: false,
dataType: 'json'
});
I believe the latest flex code broke the solution using preProcess.
addData: function (data) { //parse data
if (p.dataType == 'json') {
data = $.extend({rows: [], page: 0, total: 0}, data);
}
if (p.preProcess) {
data = p.preProcess(data);
}
You need to flip it so that the preProcess if comes before the type JSON if. Otherwise the function listed as an answer does not work properly.
It's old, I know... But here is an example of json that works:
{
"total": 5,
"page": "1",
"rows": [
{"cell": [1, "asd", "dsa", "2013-07-30"]},
{"cell": [2, "asd", "dsa", "2013-07-30"]},
{"cell": [3, "asd", "dsa", "2013-07-30"]},
{"cell": [4, "asd", "dsa", "2013-07-30"]},
{"cell": [5, "asd", "dsa", "2013-07-30"]}
]
}
(5 results in total; first page (they are NOT zero-based); 5 lines of data, each containing { ID, "asd", "dsa", "a date" } )
Try to make total your first element in you JSON string like this.
`{"total" : 2,"page":1,"rows":[ {"cell" : ["226 CLAVEN LN", "312"]},{"cell" : ["1377 FAIRFAX PIKE","280"]}]}`