How to change AJAX data in DataTables - ajax

I have a DataTable which is able to successfully fetches AJAX data once while initialising the table.Now I need to be able to "refetch" the AJAX data to update the DataTable, but without re-initialising the table.
After some research I found out I need to use the following line "as a function":
ajax.data( data, settings )
Explained here: http://datatables.net/reference/option/ajax.data
However. I cannot find how to use this "as a function". It has not one example on the page.
I tried it as follows.My original DataTable creation:
launch_datatable_ajax = function(){
get_ajax_data();
dyn_t = $('#dynamic_table').DataTable({
"ajax": {
"url":ajax_url,
"data":data,
"dataSrc":""
},
"columns": [
{ "data" : "ID" },
{ "data" : "post_title" },
{ "data" : "supplier_company" },
{ "data" : "img_src" },
{ "data" : "tags" },
{ "data" : "post_meta" },
],
});
}
Then I tried to reload the Data with new parameters. Here's where I'm stuck.
dyn_t.ajax.data(data,dyn_t.settings);
I think I'm correct for the parameters:
dyn_t.settings gives some info on: console.log(dyn_t.settings);
'data' gives my object (the get variables) on: console.log(data);
But console.log says:
Uncaught TypeError: dyn_t.ajax.data is not a function(…)

Reloading can be done with dyn_t.ajax.reload();.
However your requirement is to send updated URL parameters to the server also.
To do this, you need to use the function argument for ajax: http://datatables.net/reference/option/ajax#function
The function re-validates in every ajax.reload() call. This is why the new params will be sent. So assuming you have an HTML form with id my-form, try something like this:
ajax: function ( data, callback, settings ) {
$.ajax({
url: "ajax_url?" + $("my-form").serialize(),
data: { start: data.start, count: data.length }
});
},

Related

How to reload datatable by using new url and some parameters without reinitialize it

I know I can make ajax request on datatable using ajax.url like this :
var table = $('#example').DataTable( {
ajax: "/mylink"
} );
...
table.ajax.url( 'newData.json' ).load();
But how can I pass data as parameters to url using the same syntax?
I try table.ajax.url( 'mylink' ).data(myData).load(); . Obsviouly it is not solution.
I do not want to destroy and reinitialize the datatable in order to use :
...
"ajax" : {
"url" : "mylink",
"data" : myData
}
...
What do I do? What is the syntax using existing initialized table (here js var table)?
thanks
In your DataTables ajax section, instead of using the object form of the data option, you can use the function form. This allows you to dynamically pass in your request data for each new ajax call.
So, instead of this:
"data" : myData
It would be this:
"data": function () {
return myData;
}
And, as you already note, you can use the ajax.url() call to specify the new URL:
table.ajax.url( 'newData.json' ).load();
Warning: This assumes you are not using server-side processing, as this will overwrite the server-side request data which is auto-generated by DataTables. If you are using server-side processing, then you have to merge your custom data into the pre-existing request data.
The documentation shows an example for that, using jQuery extend:
"data": function ( d ) {
return $.extend( {}, d, {
"extra_search": $('#extra').val()
} );
}
You don't need to use $.extend. You just need to be careful that you do not overwrite the request data generated by Datatables.
Another way to handle this is to simply append data to the data structure represented by d in "data": function ( d ):
"data": function ( d ) {
d.extra_search = $('#extra').val();
}
Update with a more detailed example
Here is a full example, which you can copy into a html file and run for yourself, if you wish. It uses data from a dummy JSON provider, just for testing.
The HTML, showing the table and a button. The button is how I tested the ability to call a new URL and pass new request parameters to that new URL:
<div style="margin: 20px;">
<button id="button_one" type="button">Resubmit</button>
<br><br>
<table id="example" class="display" style="width:100%"></table>
</div>
Here is the related script containing the DataTable definition and a function which calls the new URL (with new request parameters):
<script>
$(document).ready(function() {
// ajax for initial table creation:
var requestUrl = "https://jsonplaceholder.typicode.com/posts";
var requestData = { "name": "Abel", "location": "here" };
var table = $('#example').DataTable( {
ajax: {
method: "GET",
url: requestUrl,
"data": function ( ) {
return requestData;
},
dataSrc: "",
},
"columns": [
{ "title": "User ID", "data": "userId" },
{ "title": "ID", "data": "id" },
{ "title": "Title", "data": "title" }
]
} );
$("#button_one").click(function() {
// subsequent ajax call, with button click:
requestUrl = "https://jsonplaceholder.typicode.com/todos";
requestData = { "name": "Charlie", "location": "there" };
table.ajax.url( requestUrl ).load();
});
} );
</script>
The key points in this example are:
There are 2 different URLs. The first one is used when DataTables is created. The second one is used when the button is clicked.
There are 2 different sets of request data, for the two URLs.
Using this approach, you can repeatedly call table.ajax.url( requestUrl ).load() with different URLs and different sets of request data, without needing to destroy the DataTable.
Handling Form Data
Here is a simple HTML form:
<form id="filter-form">
City:<input type="text" id="city" name="city">
Country:<input type="text" id="country" name="country">
<input type="submit" value="Submit">
</form>
For testing, I have the following JavaScript which captures the contents of the form into an array:
var form_data = [];
$( "#filter-form" ).submit(function( event ) {
event.preventDefault();
form_data = $( this ).serializeArray();
table.ajax.url( url ).load();
});
The end result is data like this in the form_data variable:
[
{
"name": "city",
"value": "Berlin"
},
{
"name": "country",
"value": "Germany"
}
]
Now I can merge that data into the automatically created server-side request data. This is where I can choose to use the $.extend() function I mentioned above:
$('#example').DataTable( {
serverSide: true,
ajax: {
method: "POST",
url: url, // from a variable
data: function( d ) {
return $.extend( {}, d, { "my_extra_data": form_data } );
}
},
... //whatever else is in your DataTable definition...
});
This function results in request data like the following:
{
"draw": "2",
"columns[0][data]": "id",
"columns[0][name]": "",
...
"start": "0",
"length": "10",
"search[value]": "",
"search[regex]": "false",
"my_extra_data[0][name]": "city",
"my_extra_data[0][value]": "Berlin",
"my_extra_data[1][name]": "country",
"my_extra_data[1][value]": "Germany"
}
You can see your my_extra_data values are included along with the server-side auto-generated request data. And all of this gets sent to the server as part of your request.
If you are using POST then it's in the request body.
If you are using GET, then it's the same data - but added to the URL as a query string.
In both cases, it's converted to the standard string representation used by form data.
It's then up to the server-side code to access this data in the usual way.
NOTE: You may have expected your URL-encoded form data to be provided as this:
...&city=Berlin&country=Germany
But instead it is provided as arrays of name/value pairs:
&my_extra_data%5B0%5D%5Bvalue%5D=Berlin&my_extra_data%5B1%5D%5Bname%5D=country&my_extra_data%5B1%5D%5Bvalue%5D=Germany
So, there is extra server-side work needed to parse this data.
If you want to convert your form data directly into a JavaScript object like this:
{ "city": "Berlin", "country", "Germany" }
then take a look at the answers to this question:
Convert form data to JavaScript object with jQuery

JSGrid unable to perform search

Is there anything we must write externally to perform search on a column. from demos i understand that no code is written , please help me out.
I have filtering:true, so that i have search boxes on each col , when i enter text and hit on enter button of keyboard or search icon nothing happens but it calls a REST-ful service which i have written to get data for grid
Following is my code
controller : {
loadData : function(filter) {
var d = $.Deferred();
$.ajax({
url : "myurl",
dataType : "json",
type : 'POST',
}).done(function(response) {
// client-side filtering
$.grep(response, function(project) {
return project.Name === filter.Name;
});
d.resolve({
data : response.project
});
});
return d.promise();
},
},
The first problem is $.grep doesn't change the source array, it returns the result of filtering.
Also be sure about data in response, since you filter the response while resolving deferred with response.project. Apply grep to the array of items.
Another thing is ensure the format of returning data, if pageLoading is false, the deferred should be resolved with the array of items (not { data: [items] }).
So depending on #2 and #3 the fixed code could be:
.done(function(response) {
var result = $.grep(response, function(project) {
return project.Name === filter.Name;
});
d.resolve(result);
});
Hope this will help.

Kendo Datasource response is empty

I am new to Kendo UI. I am trying to read the remote data and display in the screen. I am able to see the remote json data by accessing the URL in the browser. But when I try to alert() the response data inside kendo UI, it is empty.
here is the sample code.
<script type="text/javascript">
var shareDataSource;
var viewModel;
function searchByVin() {
var vin = $("#vinNumber").val();
shareDataSource = new kendo.data.DataSource({
transport: {
read: {
url: "http://localhost:9080/portal/programexcep/resources/request/vin/"+vin,
dataType: "json"
}
},
schema: {
data: "data",
model: { id: "Id" }
},
requestEnd: function(e) {
var response = e.response;
var type = e.type;
alert(type);
alert(response.length);
}
});
shareDataSource.read();
alert(vin);
alert(kendo.stringify(shareDataSource.data()));
}
</script>
The JSON data is
{"Id":10,"FirstName":"John Smith","vin":"html5"}
as the response in the browser. The alert(kendo.stringify(shareDataSource.data())); is empty
and the alert(response.length); is also undefined.
Can someone help on this?
The problem is that shareDataSource.read(); is asynchronous which means that you invoke read but data is not immediately available. You can use fetch instead that executes a portion of code when the data is available. Your code would be:
shareDataSource.fetch(function() {
alert(vin);
alert(kendo.stringify(shareDataSource.data()));
});
There is also a problem in requestEnd function: you try to get the length of response but in the model definition you say that data field is called data so your server should be returning something like:
{
"data" : [
{ "Id" : 1 },
{ "Id" : 2 },
{ "Id" : 3 }
]
}
and then for accessing the length you should do response.data.length

How to pass multi rows edited in jqgrid to server controller?

I'm new in jqgrid.
I want to pass multi rows edited in jqgrid to pass MVC server controller.
controller expects json string type of data.
how my jsp pass all rows to controller?
jQuery("#save").click( function(){
alert("enter save fn");
var gridData=jQuery("#gridList").jqGrid('getGridParam','data');
jQuery.ajax({
url : '/uip/web/p2/saveEmployeeList.dev'
,type : 'POST'
,cache : false
,data : JSON.stringify(gridData)
,contentType : 'application/json; charset=utf-8'
,dataType : 'json'
})
});
I print out HttpServletRequest in controller. there is one row exist.
even little clue would be helpful.
If I understand you correctly you want to save all edited rows by one Ajax action instead of a Ajax request after any row is edited?
If so, this might be the solution. Instead of Ajax you use the 'clientArray' option in your configuration as your URL parameter. This causes jqGrid to save every edited row internally in JavaScript and post nothing to your server.
With a onclick on a save button you could do something as follows:
var changedRows = [];
//changedRows is a global array
if($('#save-rows').length) {
$('#save-rows').click(function() {
var postData = {}
$.each(changedRows, function(key) {
postData[key] = $('#paymentsgrid').jqGrid('getRowData', this);
});
$.post(baseUrl + '/controller/action', {
'data' : postData
}, function(response) {
$('<div></div>').html(response.content).dialog({
'title' : 'Message',
'modal' : true,
'width' : 800,
'height' : 400,
'buttons' : {
'OK' : function() {
$(this).dialog('close');
}
}
});
if(response.reload) {
$('#grid').trigger('reloadGrid');
}
}, 'json');
});
}
Also important is to specify a save event in your grid:
$('#paymentsgrid').jqGrid('saveRow', paymentController.lastsel, null, 'clientArray', null, function(rowId) {
changedRows.push(rowId);
});
You might should modify or optimize some things but in the basic, this should work or give you an idea how to accomplish what you want.

jsTree JSON with MVC

I have done a lot of research and cannot find an answer. I want to integrate JSTREE with MVC3.0. Here is my Javascript setup:
setupTree: function (treeDivId) {
$('#' + treeDivId).jstree({
"json_data": {
"ajax": {
url: CustomTree.SectorLoadUrl,
type: "POST",
contentType: "application/json;charset=utf-8",
dataType: "json",
data: function (n) {
return { id: n.attr ? n.attr("id") : "0" };
},
success: function (data, textstatus, xhr) {
alert(data);
},
error: function (xhr, textstatus, errorThrown) {
alert(textstatus);
}
}
},
"themes": {
"theme": "default",
"dots": true,
"icons": false
},
"plugins": ["themes", "json_data"]
});
}
I also get the data correctly as can be seen in the uploaded image:
However, the following lines of code:
data: function (n) {
return { id: n.attr ? n.attr("id") : "0" };
},
Always return a -1 for n.
And I get a parser error on the OnError handler in my textstatus.
I am going to answer this question in the hopes that it helps someone.
I spent a total of 5hrs trying to understand what was going on and finally added a hack.
Using Firebug, I noticed that a callback was being appended to the URL. When the data was returned, the callback was not getting executed. I didn't specify any callbacks, so that was the first item to look into.
Per documentation, turns out that jquery1.5 onwards it will automatically append a callback if it thinks the data type is jsonp. However, I explicitly mentioned 'json' as my data type so I don't understand why it appended that callback.
Here's what the jquery documentation says:
"jsonp": Loads in a JSON block using JSONP. Will add an extra "?callback=?" to the end of your URL to specify the callback.
So this made me wonder what was going on. Also turns out, as of jquery 1.5, you can now specify multiple data types in the AJAX call and jquery will automatically try to convert.
Buried deep within the jquery documentation is this: "As of jQuery 1.5, jQuery can convert a dataType from what it received in the Content-Type header to what you require."
So I just thought it would be better to return the data type as text, then use jquery to convert it to json. The moment I changed my dataType to "text json" instead of just "json", everything magically started working.
My guess is, there's something up with auto-inference on data types with the new jquery. I am on a strict deadline so I cannot research this issue anymore, but if someone finds answers, please do post.
Here is my modified Javascript:
setupTree: function (treeDivId) {
$('#' + treeDivId).jstree({
"json_data": {
"ajax": {
"url" : CustomTree.SectorLoadUrl,
"type" : "POST",
"dataType" : "text json",
"contentType" : "application/json charset=utf-8",
}
},
"themes": {
"theme": "default",
"dots": true,
"icons": false
},
"plugins": ["themes", "json_data"]
});

Resources