I have an HTML table that I'm converting into datatable. In this datatable, I can edit a value in a cell. I want to attach a "save" button to this datatable and once a user clicks it then it should save the content of the datatable into SQL Server database.
My problem is, I couldn't find out how I can extract the data from js:datatable object into c#? I think I need to use something like below but it doesn't work and returning error.
"Cannot read properties of undefined (reading 'type')". Here is the code:
<table id="tb_voteProjects" class="compact nowrap custom" cellspacing="0" >
<%=getColumnHeaders()%>
<%=getActiveData()%>
</table>
...
var table = $('#tb_voteProjects').DataTable({
...,
buttons: [
...
{
text: 'Save',
action: function ( e, dt, node, config ) {
$.ajax({
type: "POST",
url: 'Ranking.aspx/SaveRanks',
data: {table}, //HOW TO SEND THE TABLE CONTENT INTO C# ???
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (msg) {
window.location.reload();
},
error: function (e){
Console.log(e);
}
});
}
Any help would be appreciated.
Thanks.
Edit1: using ...data: table.rows().data()..., instead of ...data:table..., in my ajax didn't fix the issue.
You can use the dt object in your action function - that represents the DataTables API for your table.
From there you can use dt.rows().data().toArray(). This creates an array containing each row of table data in a sub-array.
You can then convert that JavaScript array to a JSON string:
data: JSON.stringify( dt.rows().data().toArray() ),
I assume you already know how to use your C# server code to retrieve the JSON payload from the body of the POST request.
Reference:
rows().data()
toArray()
Related
This question already has answers here:
How to parse a JSONString To Dataset?
(6 answers)
Closed 2 months ago.
I am using table data from jQuery Datatable and passing it to an ajax function. The function calls a web service to process the data and I am stuck trying to deserialize it.
The initial call comes from datatable's 'buttons' button group, where I am trying to implement a custom export to Excel:
buttons: [
{
extend: "collection",
text: "Export",
buttons: [
{
text: 'My Excel',
action: function (e, dt, node, config) {
exportToExcel(dt);
}
},
...
]
function exportToExcel(dt) {debugger
// var tableRows = dt.rows().data().toArray();
var tableRows = dt.data().toArray();
var blah = JSON.stringify({ TableData: tableRows });
$.ajax({
type: "POST",
dataType: "json",
contentType: "application/json; charset=utf-8",
cache: false,
url: "../WebService/ABC.asmx/ExportToExcel",
data: JSON.stringify({ TableData: blah }),
}).done(function (result) {
}).fail(...
I tried creating classes to see if that would work but no luck.
public string ExportToExcel(string TableData)
{
string JSONresult = string.Empty;
//Errors_Counts[] oDict = (JsonConvert.DeserializeObject<Dictionary<string, Errors_Counts[]>>(TableData)).Values.FirstOrDefault();
return JSONresult;
}
The data, once JSON-stringified looks like this:
{"TableData":
[
{"THEDATE":"2022-12-10T00:00:00","E38":0,"E39":1,"E40":37,"E41":0,"E42":0},
{"THEDATE":"2022-12-11T00:00:00","E38":0,"E39":0,"E40":20,"E41":0,"E42":0},
...
]
}
How would I deserialize this to end up with a dataset or data table that I can further process? Right now I just have a JSON string. The third party soaftware that I use for exporting to Excel works best with data table. So if I can end up with a data table with column names as TheDate, E38, E39, ... it would solve my issue.
if you just need a DataTable instance
public string ExportToExcel(JObject TableData)
{
//DataTable dataTable = TableData["TableData"].ToObject<DataTable>();
return TableData["TableData"].ToString();
}
My app is made in ASP.NET MVC 5. User can use search form which is displaying filtered data. Now I want to add button which will export displayed data.
To do this I am sending Search object to view and save it in html. Now When clicking export button I want to pass this object to controller, get data from database using this Search object and save results as text.
The thing is I cant bind json to c# object. Thats my view:
<div id="originalForm" style="visibility:hidden">
#Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model))
</div>
This is my ajax code:
function exportRaportToCsv() {
var $formData = $('#originalForm').text();
var allIds = getCheckedIds();
var dataToSend = JSON.stringify({
ids: allIds,
search: $formData
});
$.ajax({
type: "POST",
url: '#Url.Action("ExportToCsv", "BankCosts")',
data: dataToSend,
contentType: "application/json; charset=utf-8",
success: function (datar) {
window.location = '/BankCosts/Download?fileGuid=' + response.FileGuid
+ '&filename=' + response.FileName;
},
error: function (xhr) {
},
});
}
And this is my controller:
[HttpPost]
public ActionResult ExportToCsv(string[] ids, Search search)
{
// search is null here
}
When I spy sending data with Fiddler I can see, that I am passing this:
{"ids":[],"search":"\n {\"ID\":0,\"DateFrom\":\"2018-06-23T00:00:00\",\"DateTo\":\"2018-06-25T00:00:00\",\"hasUnrecognizedStatus\":false,\"skippedSearchResults\":0,\"paginationLimit\":100}\n"}
I think it is worth to mention, that ids is properly passed. If it contains data, that data is passed. I think the problem is that I have \ in my json. How can I remove this? Is there something wrong with my ajax?
When I use console.log to print $formData I can see that \ characters are gone and it looks better:
{"ID":0,"DateFrom":"2018-06-23T00:00:00","DateTo":"2018-06-25T00:00:00","hasUnrecognizedStatus":false,"skippedSearchResults":0,"paginationLimit":100}
[HttpPost]
public ActionResult ExportToCsv(string[] ids,[FromBody]Search search)
{
}
Try adding FromBody if your Search model is ok it should work.
based on your comments, I think that search object already stringified, so you don't need to stringify it.
just make your json like this
var dataToSend = {
"ids": allIds,
"search": $formData
};
Use JSON.parse() to transforms JSON string to a JavaScript object. Your $('#originalForm').text() is a JSON string actually.
var $formData = JSON.parse($('#originalForm').text());
var allIds = getCheckedIds();
var dataToSend = JSON.stringify({
ids: allIds,
search: $formData
});
In your case, $formData is a string (JSON string actually). So JSON.stringify() again trying to convert to JSON string which is already a JSON string that's causing unnecessary '/' character in form data that you are posting.
Make sure to set the content type to 'application/json' in ajax call properties Otherwise MVC model binder will not be able to map and fill .NET model from JSON posted data.
contentType: "application/json; charset=utf-8",
Since you are using
JSON.stringify
the search value posted in string format not object
Search
so
Try replace your controller with this
[HttpPost]
public ActionResult ExportToCsv(string[] ids, string search)
{
//then deserialize search json like
Search objSearch = JsonConvert.DeserializeObject<Search>(search);
}
or
[HttpPost]
public ActionResult ExportToCsv(string[] ids, JObject search)
{
//then deserialize search json like
Search objSearch = JsonConvert.DeserializeObject<Search >
(dataModel["search"].ToString());
}
View
$.ajax({
type: "POST",
url: '#Url.Action("ExportToCsv", "BankCosts")',
data:{ids= allIds.toString(),search:JSON.stringify($formData)}
contentType: "application/json; charset=utf-8",
success: function (datar) {
window.location = '/BankCosts/Download?fileGuid=' + response.FileGuid
+ '&filename=' + response.FileName;
},
error: function (xhr) {
},
});
I am calling a Web Method using Json and get HTML as a result.
I'm trying to set the value of a hidden field with this HTML and then access this hidden field from
server side but the hidden field value is always empty.
please help.
thanks
$.ajax({
type: "POST",
url: "ws/srv.asmx/GetReportResult",
data: JSON.stringify(prm),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data, status) {
var result = JSON.parse(data.d);
$("myHiddenField").val = result;
},
error: function (request, status, error) {
alert(request.statusText);
}
});
Try changing this line
$("myHiddenField").val = result;
To become
$("myHiddenField").val(result);
Jquery val is a function, so the parenthesis will fix the assignment.
are you have a hidden field control on server side? Than maybe your hidden field id is not myHiddenField when rendered to the page. Check your hidden field on browser and make sure its id is myHiddenField.
if it something like ct100_ct1242_myhiddenField than you can change
$("#myHiddenField").val = result;
with
$("[id$='myHiddenField']").val = result;
and if there is no codes changing the hidden field value on page load , page init etc you should see the result.
I am passing json data to my generic handler page GenericHandler.ashx.cs using jquery ajax request and json as data type.
in my handler code i would like to return html table in string format. here is snap of my handler code
context.Response.ContentType = "text/plain";
context.Response.Write(sResponse);
where sResponse contains <table><tr><td>PropertyName</td><td>PropertyID</td></tr><tr><td>abc</td><td>1</td></tr></table>
my jquery code (check inline comment in error function):
id = { 'PropertyID': id };
$.ajax("Handlers/GenericHandler.ashx?Type=getProperties",
{
type: 'post',
dataType: 'json',
cache: false,
contentType: "application/json",
data: JSON.stringify(id),
success: function (data) {
console.log(data);
},
error: function (xhr, status) {
console.log(status); // Output as parseError
console.log(xhr.responseText); // My sResponse string ! But Why Here ?
}
});
My Question :
Why i am not getting response in success function
Is it right way to do ? or should i convert html table to json object and then return it. And again display it in tabular format ?
From jQuery documentation here, you can see that the dataType parameter is what AJAX is expecting back as a response from the server. The contentType parameter is what is put in the header in your request to the server so that the server knows how to read the request.
Therefore, you should change your dataType to "text" like:
$.ajax("Handlers/GenericHandler.ashx?Type=getProperties",
{
type: 'post',
cache: false,
dataType: 'text',
contentType: "application/json",
data: JSON.stringify(id),
success: function (data) {
console.log(data);
},
error: function (xhr, status) {
console.log(status);
console.log(xhr.responseText);
}
});
I find this useful when alerting of a successful INSERT or UPDATE call on a database. It would be extraneous to create and return a JSON object for such a task.
Your response isn't valid JSON sine it's returning plain text. jQuery is expecting the response to be JSON because you've set contentType: "application/json"
If the rest of your site uses JSON as a transmission format, then wrap your HTML as a JSON object and return it.
In your back end code, return something that looks like this
{response_html : "<table><tr><td>PropertyName</td><td>PropertyID</td></tr><tr><td>abc</td><td>1</td></tr></table>"}
And in your jQUery code, you can access it in the success callback.
success: function (data) {
console.log(data.response_html);
},
NOTE - You'll need to remove the plain text content type from your backend code and make that JSON.
If you tell $.ajax that you expect a JSON, then a text/plain response from the server is not a valid response.
Regarding your second question: The good way to do it would be to return the data you want to work with, in JSON format, for example:
[
{ "label" : "PropertyName", "value" : "abc" },
{ "label" : "PropertyId", "value" : "1" }
]
And then in the success callback of your Ajax request, work with that data to build your HTML structure with jQuery.
Inside my controller there is JsonResult action which returns me a list of House object.
I want onclick using ajax to retrieve these data and to display json data inside my view.
Inside firebug I'm able to see proper Response and Json result but I dont know how to display inside my view.
function GetTabData(xdata) {
$.ajax({
url: ('/Home/GetTabData'),
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({ id: xdata }),
success: function (result) {
// tried with these but it doesnt work
// result = jQuery.parseJSON(result);
// alert(result.Title);
},
error: function () { alert("error"); }
});
}
public JsonResult GetTabData()
{
...
var temp = getMyData...
return Json(temp, JsonRequestBehavior.AllowGet);
}
// View page
<div id="showContent">
// Json data should appear here
</div>
Inside firebug JSON tab when success:function(result) is empty
I have following data:
Id 149
PropertyType "Apartment"
StreetNumber "202B"
CityName "Sidney"
Title "My test data"
success: function (json) {
var data = null;
$.each(json.items,function(item,i){
data = '<div>'+item.Id+ ' ' + item.CityName +'</div>';
$("#showContent").append(data);
});
}
First of all, you can specify the dataType attribute in your ajax call to 'json' and then don't have to decode the json response again -
dataType: 'json'
Then, you don't need to use parseJSON. Simply use result.Title etc.
success: function (result) {
alert(result.Title);
var showContent = $('#showContent');
showContent.html(result.Id+','+result.Title);
},
EDIT: As Mukesh said, you can have the ajax function return json without using any extra decoding.
The ajax call result is already an object. You can do whatever you want with it it inside the success function.
For example you could create a table of the information dynamically inside the function, or send the data to another function by calling the function inside that success function. Once you leave the success function, the data is not usable anymore.
Access the data object like any object (data.someProperty).