I am trying to use jQuery DataTables server-side with .net core.
I am using Ajax to call my controller and I have strongly typed View with a table without body.
I am getting data in my controller but it seems I can't display it.
I thought it was JSON (https://dotnetcoretutorials.com/2018/05/05/setting-json-serialization-configuration-at-runtime-on-a-net-core-api/) but I checked and it seems it wasn't.
I tried with this tutorial but still can't find what I am doing wrong.
I just can display the "sDefaultContent" defined in Ajax.
Controller:
[HttpPost]
public async Task<IActionResult> LoadTransaction()
{
var requestFormData = Request.Form;
List<Transactions> data = await ApiClientFactory.Instance.GetInvoice();
dataList = data;
try
{
var listData = ProcessModuleCollection(data, requestFormData);
dynamic response = new
{
Data = listData,
Draw = requestFormData["draw"],
RecordsFiltered = data.Count,
RecordsTotal = data.Count
};
return Ok(response);
//return Json(response);
}
}
View:
<div class="row">
<div>
<div >
</div>
<div class="panel-body">
<table id="example" class="table table-striped table-hover responsive">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.ValueDate)
</th>
<th>
#Html.DisplayNameFor(model => model.StructuredMessage)
</th>
</tr>
</thead>
</table>
</div>
</div>
(function($) {
var generateCustomerTable = $("#example")
.dataTable({
"processing": true,
"serverSide": true,
"ajax": {
"url": "/Home/LoadTransaction",
"method": "POST"
},
"columns": [
{ "data": "ValueDate", "name": "ValueDate", "sDefaultContent": '0-0-0000', "autoWidth": true },
{ "data": "StructuredMessage", "name": "StructuredMessage", "sDefaultContent": '0-0-0000', "autoWidth": true },
],
"ordering": true,
"paging": true,
"pagingType": "full_numbers",
"pageLength": 10
});
})(jQuery);
here is the printScreen of my console
console PrintScreen
i must admit as often the community StackOverFlow had already the answer
the thing missing is in the ajax call datasrc
this post helps me understanding what i was trying to do
and reading a bit more comments
'dataFilter': function(data){
var json = jQuery.parseJSON( data );
json.RecordsTotal = json.total;
json.RecordsFiltered = json.total;
json.Data = json.list;
return JSON.stringify( json ); // return JSON string
}
in this particular case regarding what i am sending from my controller
Related
JsonResult method not calling through $http call,
I am working on a project that uses ASP.NET MVC, AngularJS I am calling a mvc controller from AngularJS. I am getting an jsonresult as in the call to a MVC controller from AngularJS .
this is the result
[
{
"Branch_ID": 1,
"Branch_Name": "sdsds",
"Branch_Address": "sfsdfsdf",
"Branch_email": "sdfsdfsdf",
"Branch_Notes": "sfsffsfd",
"Branch_Manager": null,
"Branch_Phone": null,
"Branch_TimeFrom": "/Date(-2208996000000)/",
"Branch_TimeTo": "/Date(-2208996000000)/",
"saturday": false,
"sunday": false,
"monday": false,
"tuesday": false,
"wednesday": false,
"thursday": false,
"friday": false,
"Departments": null
}
]
branches controller
public class BranchesController : Controller
{
private IRepositoryBase<Branches> BrancheRepository;
public BranchesController(IRepositoryBase<Branches> brancheRepository)
{
this.BrancheRepository = brancheRepository;
}
// GET: Branches
public JsonResult Index()
{
var branches = BrancheRepository.GetAll();
//if (!String.IsNullOrEmpty(searchString))
//{
// branches = branches.Where(s => s.Branch_Name.ToUpper().Contains(searchString.ToUpper()));
//}
return Json(branches, JsonRequestBehavior.AllowGet);
}
}
Index.cshtml
<div class="container" ng-controller="branch-controller">
<div class="panel panel-info">
<div class="panel-heading">
Branch Details - Grid CRUD operations
</div>
<table class="table table-bordered">
<thead style="background-color:lightblue;">
<tr>
<th> Branch Address</th>
<th> Branch Email</th>
<th>Branch Name</th>
<th>Branch Notes</th>
<th> Actions</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="branche in Branches">
<td>{{branche.Branch_ID}}</td>
<td>{{branche.Branch_Address}}</td>
<td>{{branche.Branch_email}}</td>
<td>{{branche.Branch_Name}}</td>
<td>{{branche.Branch_Notes}}</td>
<td style="width:200px;">
Update
Delete
</td>
</tr>
</tbody>
</table>
</div>
Module.js
var myapp;
(function () {
myapp = angular.module('my-branches', []);
})();
Controller.js
myapp.controller('branch-controller', function ($scope, branchService) {
//Loads all branch records when page loads
loadBranches();
function loadBranches() {
var BrancheRecords = branchService.getAllBranches();
BrancheRecords.then(function (data) {
//success
$scope.Branches = data;
},
function (error) {
console.log(error);
alert("Error occured while fetching branche list...");
});
}
});
Service.js
myapp.service('branchService', function ($http) {
this.getAllBranches = function () {
return $http.get("/Branches/Index").then(function (response) {
return response.data;
});
};
});
First of all you need to change you code as it is shown in #georgeawg's answer and then your remaining problem is that you are using invalid property names. The result should look like this
<td>{{branche.Branch_Address}}</td>
<td>{{branche.Branch_email}}</td>
<td>{{branche.Branch_Name}}</td>
<td>{{branche.Branch_Notes}}</td>
Change the service call to:
var BrancheRecords = branchService.getAllBranches();
BrancheRecords.then(function (data) {
//success
$scope.Branches = data;
},
function (error) {
console.log(error);
alert("Error occured while fetching branche list...");
});
Change the service to:
myapp.service('branchService', function ($http) {
this.getAllBranches = function () {
return $http.get("Branches/Index").then(function(response) {
return response.data;
});
};
});
The data is assigned to the data property of the response object.
For more information, see
AngularJS $http Service API Reference - returns
I am trying to use a datatable and was wondering what i am doing wrong its just stuck on loading and showing waiting to start. This is on my activity controller and the LoadGridData function is called from the scripts below in my index.cshtml.
public ActionResult LoadGridData()
{
// Getting all Customer data
var data = GetAllActivityHeader();
return Json(new { data = data });
}
Here is my GetallActivityHeader function
public async Task<ActionResult<List<ActivityHeader>>> GetAllActivityHeader()
{
return await _activityRepo.GetAllActivityHeader();
}
This is my repositry method which is called above.
public async Task<List<ActivityHeader>> GetAllActivityHeader()
{
using (IDbConnection conn = Connection)
{
if(conn.State == ConnectionState.Closed)
conn.Open();
var result = await conn.QueryAsync<ActivityHeader>("GetActivityHeader");
return result.ToList();
}
}
In My Layout I have the following scripts
#section Scripts{
<script src="//cdn.datatables.net/1.10.9/js/jquery.dataTables.min.js">
</script>
<script>
$(document).ready(function () {
$('#myTable').DataTable({
"ajax": {
"url": "/Activity/LoadGridData",
"type": "GET",
"datatype": "json"
},
"columns": [
{ "data": "Name", "autoWidth": true },
{ "data": "Description", "autoWidth": true },
{ "data": "Phone", "autoWidth": true },
{ "data": "EmployeeName", "autoWidth": true },
{ "data": "SOP", "autoWidth": true },
{ "data": "Status", "autoWidth": true }
]
});
});
</script>
Html
<div class="container">
<br />
<div style="width:90%; margin:0 auto;">
<table id="myTable" class="table table-striped table-bordered dt-responsive nowrap" width="100%" cellspacing="0">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>Phone</th>
<th>EmployeeName</th>
<th>SOP</th>
<th>Status</th>
</tr>
</thead>
</table>
</div>
But when i debug the code i am getting the following issue. Also for some reason my edit and delete buttons are not showing I persume i need to code those before they show. Is there any better components for working with datatables and asp.net core?.
And also here is what my view is showing
Edit 1
Ok so i made the method async and that worked and there data their but its still saying no data in the datatable
public async Task<ActionResult> LoadGridData()
{
// Getting all Customer data
var data = await GetAllActivityHeader();
return Json(new { data = data });
}
Finally this is my class obv I dont want to display all in the datatable so I just used the column headers i wanted or is that not how datatables work?.
Im binding my Data in View to Controller, so later I could do what I want with the data. In my View, im using dataTable and #Html.EditorForModel() to render my View.
View
<form action="xx" method="POST">
<table id="myTable" class="table table-bordered table-hover table-striped">
<thead>
<tr>
<th></th>
<th>
#Html.DisplayNameFor(model => model.Field1)
</th>
<th>
#Html.DisplayNameFor(model => model.Field2)
</th>
<th>
#Html.DisplayNameFor(model => model.Field3)
</th>
</tr>
</thead>
<tbody>
#if (Model != null)
{
#Html.EditorForModel()
}
</tbody>
<tfoot></tfoot>
</table>
<input type="submit" value="submit" />
</form>
Script
$("#myTable").dataTable({
searching: false,
ordering: false,
responsive: true,
"bLengthChange" : false,
"pageLength": 20,
"bStateSave": true
});
Controller
[HttpPost]
public ActionResult MyAction(List<MyModel> MyListModel)
This method works great if the data is no more than 1 page in dataTables. if its more than 1 page, then My Controller either only can receive the List Data of the first page or receive nothing(null)
How should I bind all of my data in DataTables from View to Controller? This binding should include all pages, not only the first one
I'm unsure how you're triggering the update of data, so assuming it's a button the following should work:
$('#your-button').on('click', function(e){
var data = ('#myTable').DataTable().$('input,select,textarea').serialize();
$.ajax({
url: '/MyController/MyAction/',
data: data,
success: function(){
alert('success');
},
error: function(){
alert('failure');
}
});
});
Edit 1:
As per this answer to How to post data for the whole table using jQuery DataTables, if you're set on using a form use the following:
var table = $('#myTable').DataTable();
$('#myForm').on('submit', function(e){
var form = this;
var params = table.$('input,select,textarea').serializeArray();
$.each(params, function(){
if(!$.contains(document, form[this.name])){
$(form).append(
$('<input>')
.attr('type', 'hidden')
.attr('name', this.name)
.val(this.value)
);
}
});
});
since you don't want any ajax
Use Javascript Source Data, Pass your model to the view, serialize it, and use it as your source
var myData = #Html.Raw(Json.Encode(Model.ListOfData));
//then pass it to the datatable
$('#example').DataTable( {
data: myData,
columns: [
{ title: "col1" },
{ title: "col2" },
etc ...
]
} );
With DataTables, only the current page data exist in the DOM. If you submit the form, only the current page data are being submitted back in the server. One solution to this is submit the data via ajax:
var myTable = $('#myTable').DataTable();
$('#your-form').on('submit', function(e){
e.preventDefault();
//serialize your data
var data = myTable.$('input,select,textarea').serialize();
$.ajax({
url: '#Url.Action('MyAction', 'MyController')',
data: data,
success: function(responseData){
//do whatever you want with the responseData
}
});
});
You need to use the data() method to get the data for the whole table:
$('#your-form').on('submit', function(e){
e.preventDefault();
var table = $('#myTable').DataTable();
var data = table.data();
$.ajax({
url: '/MyController/MyAction/',
type: 'POST',
dataType: 'json',
contentType: "application/json;",
data: JSON.stringify(data),
success: function(){
alert('success');
},
error: function(){
alert('failure');
}
});
Please go through following link
https://www.codeproject.com/Articles/155422/jQuery-DataTables-and-ASP-NET-MVC-Integration-Part
I am getting error in binding JSON data to constuct a data table.
My JSON is of the following:
[
{
"ID": 1,
"Number": "2",
"Name": "Avinash"
},
{
"ID":2,
"Number":"21",
"Name":"XYZ"
},
{
"ID": 3,
"Number": "20",
"Name": "KRR"
}
]
I am binding this to jquery datatable as below:
$(document).ready(function () {
$('#table_id').dataTable({
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": '<%:Url.Action("LoadData","Home")%>'
});
$('#table_id').css("width", "100%")
});
My Table Structure is as follows:
<table id="table_id" border="0" class="display" cellpadding="1" cellspacing="1" align="center">
<thead>
<tr>
<th>ID</th>
<th>Number</th>
<th>Name</th>
</tr>
</thead>
</table>
I am getting error as follows:
Datatables Warning(tableid="table_id"):Requested Unknown Parameter'0' from the datasource for row 0
My Controller is as follows:
public ActionResult LoadData()
{
var Data = new DataTable();
Data=DataModel.LoadData();
var JsonData = JsonConvert.SerializeObject(Data, Formatting.None);
return Json(new
{
aaData = JsonData
}, JsonRequestBehavior.AllowGet);
}
Please help..
I have multiple check box values in a form. I am serializing the form and send to mvc controller as JSON data. How can i de-serialize the check box values?
This is my html -
#using (Html.BeginForm("SaveOfficeConfiguration", "Offices", FormMethod.Post, new { Id = "frmOfficeConfigSave" }))
{
<div id="divOfficeForm">
<div style="width: auto; height: auto; border: 3px outset silver;">
<table class="mainsectionable" width="100%">
<thead>
<tr>
<th style="text-align: center;">
<center>KCCM Profile Access</center>
</th>
</tr>
<tr>
<td>
#using (Html.BeginForm())
{
IEnumerable<SelectListItem> Brands = ViewBag.GetBrands;
foreach (var item in Brands)
{
#Html.CheckBox("KCCM_Brands", false, new
{
value = item.Value
});
<label>#item.Text</label><br />
}
}
</td>
</tr>
</thead>
</table>
</div>
</div>
}
This is my javascript function-
function SaveOfficeConfigNew() {
var officeID = $('input[name="hdnOfficeID"]').val();
var url = "/OfficeManagement/Offices/SaveOfficeConfiguration?officeID=" + officeID;
ShowWait();
$.ajax({
type: "POST",
url: url,
data: frmOfficeConfigSave.$('input').serialize(),
success: function (data) {
HideWait();
alert(data.msg);
},
error: function (data) {
HideWait();
alert(data.msg);
}
});
applyFilter();
return false;
}
This is my gonna be controller action -
[HttpPost]
public ActionResult SaveOfficeConfiguration(int ? officeID, FormCollection form)
{
try
{
*/..............
..............*/
return Json(new
{
success = true,
msg = String.Empty,
id = 1
}, JsonRequestBehavior.AllowGet);
}
catch (Exception error)
{
return Json(new
{
success = false,
msg = error.Message,
id = -1
}, JsonRequestBehavior.AllowGet);
}
}
You simply have to receive a List<string> parameter, with the same name you're giving the checkboxes, i.e., KCM_Brands. The Model Binder will deserialize it directly for you.
[HttpPost]
public ActionResult SaveOfficeConfiguration(int ? officeID, FormCollection form,
List<string> KCM_Brands)
{
....
}
To serialize your form data to post it, use the function suggedted in this post:
JSON object post using form serialize not mapping to c# object
You can use the FormsCollection to retrieve the check box values:
Controller:
[HttpPost]
public ActionResult SaveOfficeConfiguration(int ? officeID, FormCollection form)
{
var CheckBoxValues = form["KCCM_Brands"].Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(x=>int.Parse(x));
}
For More info Have a look here :
http://www.mindstick.com/Articles/2ee905ba-aea1-4d83-a49d-d8d8fb10c747/?Checkbox%20control%20in%20MVC
Instead of
#Html.CheckBox("KCCM_Brands", false, new
{
value = item.Value
});
use this code to generate checkboxes
<input type="checkbox" name="KCCM_Brands" value="#item.Value" />
The action on your controller should look like this
public ActionResult SaveOfficeConfiguration(int? officeID, List<string> KCCM_Brands)
When you post your form, List<string> KCCM_Brands will be populated only with the values of selected checkboxes.
Also, I don't know if your javascript is correct, but I had to make the following change for it to work
data: $('#frmOfficeConfigSave input').serialize()