C# jQuery Ajax Datatables ASP.NET Core 5 MVC - ajax

I am attempting to implement ASP.NET Core SignalR. I am looking for assistance. The project is located at: https://github.com/Talsiter/AspNetCore-SignalR-SqlTableDependency
The issue that I am running into is when a datatable is being populated from jQuery AJAX, no data is being populated into the view.
Items model (Item.cs)
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace InAndOut.Models
{
public class Item
{
[Key]
public int Id { get; set; }
public string Borrower { get; set; }
public string Lender { get; set; }
[DisplayName("Item name")]
public string ItemName { get; set; }
}
}
Items view (Index.cshtml)
#model IEnumerable<InAndOut.Models.Item>
<div class="container p-3">
<div class="row">
<div class="col-12">
<div class="card">
<div class="card-header">
<div class="card-body">
<table id="myTable" class="table table-bordered table-striped">
<thead>
<tr>
<th>Id</th>
<th>Item Name</th>
<th>Borrower</th>
<th>Lender</th>
<th>Action</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
</div>
#section Scripts {
#* These Scrips are Required *#
<script src="~/js/signalr/dist/browser/signalr.js"></script>
#*This one gives me an error of "ItemsHub undefined"*#
#*<script src="~/js/items01.js"></script>*#
#* This gives me an error "DataTable is not a function"
This probably requires the *#
<link href="//cdn.datatables.net/1.10.25/css/jquery.dataTables.min.css" rel="stylesheet" />
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.21/js/jquery.dataTables.min.js"></script>
<script src="~/js/items03.js"></script>
}
Items JS file (items03.js):
// This is from:
//https://stackoverflow.com/questions/51764211/jquery-datatable-loading-using-ajax-asp-net-mvc
// Does Not Display any data
function getAllMessages() {
$('#myTable').DataTable({
processing: true,
serverSide: false,
ordering: true,
paging: true,
searching: true,
columns: [
{ title: "Id" },
{ title: "ItemName" },
{ title: "Borrower" },
{ title: "Lender" },
{ title: "View Data" }
],
columns: [
{ data: "Id" },
{ data: "ItemName" },
{ data: "Borrower" },
{ data: "Lender" },
{
data: null,
defaultContent: "<button class='tblview'>View Id</button><button class='tblDelete'>Delete</button>"
}
],
ajax: {
"url": "/Item/GetItems",
"type": "GET",
"dataSrc": ''
},
"columnDefs": [
{
"targets": 0,
"visible": false
}
]
});
}
Item controller (ItemController.cs):
// This was updated from:
// https://stackoverflow.com/questions/51705732/jquery-datatable-ajax-no-data-available-mvc
public IActionResult GetItems()
{
var items = new List<Item>
{
new Item { Id = 1, ItemName = "Computer", Borrower = "Justin", Lender = "Don"},
new Item { Id = 2, ItemName = "Mouse", Borrower = "Mark", Lender = "Susan"},
new Item { Id = 3, ItemName = "Monitor", Borrower = "Mark", Lender = "Joe"},
new Item { Id = 4, ItemName = "Keyboard", Borrower = "Candace", Lender = "Angela"},
new Item { Id = 5, ItemName = "Printer", Borrower = "Mike", Lender = "Watson"},
};
// JsonRequestBehavior requires Microsoft.AspNet.MVC
// I do not want to reference it. I want to use Microsoft.AspNetCore.Mvc
//return Json(items, JsonRequestBehavior.AllowGet);
// I referenced this to mitigate the above issue
// https://stackoverflow.com/questions/38578463/asp-net-core-the-name-jsonrequestbehavior-does-not-exist-in-the-current-cont
//return Json(items);
// Error: Cannot read property 'style' of undefined
// This was another option
//return Json(items, new Newtonsoft.Json.JsonSerializerSettings());
// Error: Cannot read property 'style' of undefined
// This seems to be returning the correct data format
// Now the data just is not being displayed in the view
// My error seems to be in the JavaScript
return Json(new { data = items });
}
After many attempts, this is about the closest that I am able to get. While debugging the site, I do not receive any errors, but the mock data does not appear in the items view.
I am suspecting that my issue is in the Items JS file in the getAllMessages() method. I am just not sure how to fix it.

The naming convention for response in asp.net core is camel case instead of pascal case. Also you need remove "dataSrc": ''.
Change like below:
columns: [
{ data: "id" },
{ data: "itemName" },
{ data: "borrower" },
{ data: "lender" },
{
data: null,
defaultContent: "<button class='tblview'>View Id</button><button class='tblDelete'>Delete</button>"
}
],
ajax: {
"url": "/Item/GetItems",
"type": "GET",
//"dataSrc": ''
},

Related

Why sending JSON data via POST (ajax) returns null parameter?

Good afternoon everybody :)
I am working on asp.net mvc application.
I am using JQuery DataTable in order to show my data.
Actually, my ajax Post request calls a controller method which has to receive some parameters.
The problem is that they are null. I also have the Post 500 error :(
Here is my class:
public class ClientSelectionFiltersViewModel
{
public bool StrictFilteringContractTypes { get; set; }
public string ContractTypes { get; set; }
public string PaymentChoices { get; set; }
public string PopulationTypes { get; set; }
}
Here is a part of cshtml view:
#model ClientSelectionViewModel
#{
ViewBag.Title = "Sélection des clients";
}
<link href="~/lib/datatables/css/dataTables.bootstrap4.min.css" rel="stylesheet" />
<h3><i class="fas fa-clipboard-list mr-3"></i> Sélection des clients</h3>
<div asp-validation-summary="All" class="text-danger mt-2"></div>
<div id="filters">
<form method="post" asp-action="facturationWithFilters">
<!--some code here-->...
</form>
<button id="btn-filter-clients" class="btn atmb-btn-blue"><i class="fas fa-filter fa-fw mr-2"></i>Filtrer les clients</button>
</div>
<div id="client-selection" class="mt-2">
<div class="mb-1">
<a id="btn-send-selection" class="btn float-right atmb-btn-red">
<i class="fas fa-feather-alt fa-fw mr-2"></i>Lancer la facturation pour les utilisateurs sélectionnés
</a>
</div>
<table class="table table-striped table-hover table-sm table-bordered"
id="tableServerSide"
style="width:100%;">
<thead class="thead-dark text-white">
<tr>
<th>Cocher</th>
<th>#</th>
<th>Numéro de client</th>
<th>Types de contrats</th>
<th>Moyen de paiement</th>
<th>Population</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
#section Scripts {
<!--scripts DataTable-->
<script src="~/js/modal.js"></script>
<script src="~/lib/datatables/js/jquery.dataTables.min.js"></script>
<script src="~/lib/datatables/js/dataTables.bootstrap4.min.js"></script>
<!--script pour la gestion de DataTable-->
<script type="text/javascript">
$('#btn-filter-clients').click(function () {
console.log($("#contractFilter").val()); //ok I get my values
console.log($("#paymentFilter").val()); //ok I get my values
console.log($("#populationFilter").val()); //ok I get my values
console.log("début Data Table");
$("#tableServerSide").DataTable({
"processing": true,
"serverSide": true,
"filter": true,
"ajax": {
"url": "/clientselection/ajaxpostcall",
"type": "POST",
"datatype": "json",
"data": JSON.stringify({
filters: {
"ContractTypes": $("#contractFilter").val(),
"PaymentChoices": $("#paymentFilter").val(),
"PopulationTypes": $("#populationFilter").val(),
"StrictFilteringContractTypes": $("#StrictFilteringContractTypes").is(":checked")
}
}),
"contentType": "application/json",
"success": function (response) {
if (response != null) {
alert("Name : " + response.Name + ", Designation : " + response.Designation + ", Location :" + response.Location);
} else {
alert("Something went wrong");
}
},
"failure": function (response) {
alert(response.responseText);
},
"error": function (response) {
alert(response.responseText);
}
},
"columns": [ // on définit les colonnes du tableau
{
//Cases cocher
"data": null,
"className": "col-checkbox",
"render": function (data, type, row) {
var checkId = 'check' + row.id;
var isChecked = selectedIds.includes(checkId) ? ' checked="checked"' : '';
var checkbox = '<input id="' + checkId + '" type="checkbox" '
+ isChecked
+ ' class="server-checkbox" /> ';
/*
<td class="col-checkbox sorting_1">
<input id="check0" type="checkbox" class="server-checkbox">
</td>
*/
return checkbox;
}
},
{
//Numéro de client
"data": "id",
"className": "col-id"
},
{
//Types de contrats
"data": "contractstypes",
"className": "col-contractstypes",
"render": function (data, type, row) {
var chaine = string.Join(", ", row.value);
return chaine;
}
},
{
//Moyen de paiement PaymentChoice
"data": "paymentchoice",
"className": "col-paymentchoice"
},
{
//Population PopulationType
"data": "populationtype",
"className": "col-populationtype"
}
]
});
});
</script>
}
Here is my controller method:
[HttpPost]
public async Task<JsonResult> AjaxPostCall(ClientSelectionFiltersViewModel filters)
{
//some code here....
return Json(result);
}
I red at least 6 solutions which didn't work for me such as :
in ajax:
"data": JSON.stringify({
filters: {
ContractTypes: $("#contractFilter").val(),
PaymentChoices: $("#paymentFilter").val(),
PopulationTypes: $("#populationFilter").val(),
StrictFilteringContractTypes: $("#StrictFilteringContractTypes").is(":checked")
}
}),
and then in the controller :
[HttpPost]
public async Task<JsonResult> AjaxPostCall([FromBody] ClientSelectionFiltersViewModel filters)
{
//some code here....
return Json(result);
}
don't specify the "contentType": "application/json",
use different syntax of my json data with or without " "
...
Can you please tell me how to fix it?
Thanks I a lot.
You won't likely need [FromBody] on your action; try changing your JSON.stringify to:
"data": JSON.stringify({
"ContractTypes": $("#contractFilter").val(),
"PaymentChoices": $("#paymentFilter").val(),
"PopulationTypes": $("#populationFilter").val(),
"StrictFilteringContractTypes": $("#StrictFilteringContractTypes").is(":checked")
}),
This solution worked for me :
[HttpPost]
public async Task<JsonResult> AjaxPostCall(ClientSelectionFiltersViewModel filters, DataTableRequestParameters parameters)
{
//somecode...
}
And in JQuery :
var filters = {
ContractTypes: $("#contractFilter").val().join(', '),
PaymentChoices: $("#paymentFilter").val().join(', '),
PopulationTypes: $("#populationFilter").val().join(', '),
StrictFilteringContractTypes: $("#StrictFilteringContractTypes").is(":checked")
}
$("#tableServerSide").DataTable({
"processing": true,
"serverSide": true,
"filter": true,
"ajax": {
//"url": "/clientselection/ajaxpostcall", //doesn't work!!!
"url": "#Url.Action("AjaxPostCall", "ClientSelection")", //ok because of tag helper
"type": "POST",
"data": filters,
......
Thanks for your help!!
Remove "contentType"
Set "data" : jsonObject; without JSON.Stringy();
Remove [FromBody] from controller action method

Passing data to controller and changing the view

I have the following scenario:
I have a table with a list of book. Now, when I click on the selected rows, I want to send the book titles to the rental controller so that the controller can then call the appropriate view pass the book titles.
Here's the code for the table view:
<button id="checkoutButton">Checkout</button>
<table id="books" class="table table-bordered table-hover">
<thead>
<tr>
<th>Book</th>
<th>Category</th>
<th>Author</th>
<th>Registration Number</th>
<th>Volume</th>
<th>Number In Stock</th>
<th>Number Available</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
}
#section Scripts{
<script>
$(document).ready(function () {
var titles = [];
var table = $("#books").DataTable({
ajax: {
url: "/api/books",
dataSrc: ""
},
columns: [
{
data: "title"
},
{
data: "categoryId"
},
{
data: "registrationNumber"
},
{
data: "volume"
},
{
data: "numberInStock"
},
{
data: "numberAvailable"
},
{
data: "author"
}
]
});
$('#checkoutButton').click(function () {
var obj = table.rows('.selected').data();
if (obj.length == 0)
console.log("No row selected");
else {
for (var i = 0; i < table.rows('.selected').data().length; i++) {
console.log(table.rows('.selected').data()[i].title);
titles.push(table.rows('.selected').data()[i].title);
}
$.ajax({
url: "/Rental/print",
contentType: 'application/json',
method: "POST",
data: JSON.stringify({ titles })
})
}
});
And here's the controller:
public ActionResult print(Object [] titles)
{
for(var i = 0; i < titles.Length; i++)
{
Debug.WriteLine(titles[i]);
}
return View("New");
}
I haven't passed the title to the view yet because the view is not rendering at all. I have verified that the controller does get the data but it does not navigate to the "New.html". Although, if I manually navigate to this page, it does render. So, I am really not sure what I am doing wrong here.
I will very much appreciate if you can point me to the right direction.
Note: I have not included the js code which selects multiple rows because I wanted to keep the code simple. Let me know if I need to show that too.

ASP.net MVC Ajax DataTable Error 7

Kinda newbie when it comes to ASP.net MVC side of things not sure why I am getting Ajax Error 7 in DataTable
here is my code : for cshtml
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Register new Users</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap
/3.3.7/css/bootstrap.min.css" />
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.13/css/
jquery.dataTables.min.css" />
<link href="~/Content/themes/base/jquery-ui.min.css" rel="stylesheet" />
<style>
span.field-validation-error {
color: red;
}
</style>
</head>
<body>
<div style="width:90%; margin:0 auto ">
you are in the Table area
<table id="myDatatable">
<thead>
<tr>
<th>User ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>User Email</th>
<th>Username</th>
<th>Users ImagePath</th>
<th>SSID</th>
</tr>
</thead>
</table>
</div>
<script src="~/Scripts/jquery-3.1.1.min.js"></script>
<script src="~/Scripts/jquery.validate.min.js"></script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script>
<script src="https://cdn.datatables.net/1.10.13/js/jquery.dataTables.min.js"></script>
<script src="~/Scripts/jquery-ui-1.12.1.min.js"></script>
<script>
$(document).ready(function () {
var oTable = $('#myDatatable').DataTable({
"ajax": {
"url": '/home/GetUsers',
"type" : "get",
"dataType": "json"
},
"columns": [
{ "data": "Users_ID", "autoWidth": "true" },
{ "data": "Users_Fname", "autoWidth": "true" },
{ "data": "Users_Sname", "autoWidth": "true" },
{ "data": "Users_Email", "autoWidth": "true" },
{ "data": "Users_Usersname", "autoWidth": "true" },
{ "data": "Users_ImagePath", "autoWidth": "true" },
{ "data": "FK_Product_ID", "autoWidth": "true" }
]
})
})
</script>
</body>
</html>
I have tried few stackflow troubleshooting but am not getting anywhere
my file structure name are as follows
under the model folder I have EPOSv3DataModel.edmx
under the home folder I have HomeController.cs file within this
I have the following code :
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Welcome to Registration System";
//EPOSv3Entities1 r = new EPOSv3Entities1();
//var data = r.tbl_Users.ToList();
//ViewBag.userdetails = data;
return View();
}
#region Get Users from the database
public ActionResult GetUsers()
{
using (EPOSv3Entities1 entity = new EPOSv3Entities1())
{
// get the data order by firstname
var users = entity.tbl_Users.OrderBy
(a => a.Users_Fname).ToList();
return Json(new { data = users }, JsonRequestBehavior.AllowGet);
}// end of your using statement
}
#endregion
}end of class
}//end of namespace
I was following this video tutorial from: YouTube
and the site where this developer has his code is :ASP.net CRUD DataTable
Very much appreciate your support the table display but does not load any data
also when in URL when I enter the https://localhost/portnumber/Home/GetUsers the ajax error disappears but no loading data.
HELP :(
you can try this
using (EPOSv3Entities1 entity = new EPOSv3Entities1())
{
entity.Configuration.ProxyCreationEnabled = false;
// get the data order by firstname
var users = entity.tbl_Users.OrderBy
(a => a.Users_Fname).ToList();
return Json(new { data = users }, JsonRequestBehavior.AllowGet);
}// end of your using statement
you are using entity framework generated proxy object which might be causing problems in serializing

DataTables jquery.dataTables.min.js:181 Uncaught TypeError: Cannot read property 'length' of undefined

I can't specify what/where is the problem, here is my code :
HTML :
<table id="companies" class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th class="center">
Id
</th>
<th>RegNo</th>
<th>Name</th>
<th class="hidden-480">Industry</th>
<th class="hidden-phone">
Size
</th>
<th class="hidden-480">LineOfDefence</th>
<th>Address</th>
</tr>
</thead>
</table>
Server side :
var result = new
{
rows = (from company in db.Company.ToList()
select new
{
id = company.CompanyId,
RegNo = company.RegestrationNumber,
Name = company.Name,
Industry = company.IndustryType.Name,
Size = company.CompanySize.Name,
LineOfDefence = company.LineOfDefence.Name,
Address = company.Address
}).ToArray()
};
return Json(result, JsonRequestBehavior.AllowGet);
and here is my Ajax Call :
<script>
$(document).ready(function ()
{
$('#companies').DataTable( {
"ajax": {
url: "/Company/GetCompanyGrid",
type: "GET",
dataType: "json"
}
});
});
</script>
I'm getting this error : "jquery.dataTables.min.js:181 Uncaught TypeError: Cannot read property 'length' of undefined"
note : I'm using jquery-1.12.3.js & DataTables 1.10.12.
Any help would be appreciated .
finally I've figured out the problem :
first : datatables expects specific format, so I changed my server side code like this :
var result = new
{
**draw = 1,
recordsTotal = db.Company.ToList().Count,
recordsFiltered = db.Company.ToList().Count,**
data = (from company in db.Company.ToList()
select new
{
Id = company.CompanyId,
RegNo = company.RegestrationNumber,
Name = company.Name,
Industry = company.IndustryType.Name,
Size = company.CompanySize.Name,
LineOfDefence = company.LineOfDefence.Name,
Address = company.Address,
}).ToArray()
};
return Json(result
, JsonRequestBehavior.AllowGet);
second : I've added these lines to my script
<script>
$(document).ready(function ()
{
$('#companies').DataTable( {
"ajax": {
url: "/Company/GetCompanyGrid",
type: "GET",
dataType: "json"
},"columns": [
{ "data": "Id" },
{ "data": "RegNo" },
{ "data": "Name" },
{ "data": "Industry" },
{ "data": "Size" },
{ "data": "LineOfDefence" },
{ "data": "Address" },
{ "data": "Logo" },
{ "data": null },
]
});
});
</script>
and now it's working perfectly.
Datatables expects the returned json to be in a specific format, as per the documentation - see the 'Returned data' section.
Your json should look something like this:
return Json(new
{
param.draw,
recordsTotal = result.Count,
recordsFiltered = result.Count,
data = result
}, JsonRequestBehavior.AllowGet);
The error is probably a result of datatables looking for a field that isn't present. Note that the draw value is sent in the original GetCompanyGrid() request, you don't need to generate it yourself.

MVC3 reloading part of page with data razor

I have a table with my data from base and 3 buttons to delete, create and update which return PartialViews.
I want to update the part of my page with data after clicking the submit button in the corresponding dialog (delete, update, ...).
What is the easiest way to achive this?
This is what I've got now
I will just add, delete is mostly the same.
<div id="delete-dialog" title="Delete Product"></div>
<script type="text/javascript" >
$(".deleteLink").button();
var deleteLinkObj;
// delete Link
$('.deleteLink').click(function () {
deleteLinkObj = $(this);
var name = $(this).parent().parent().find('td :first').html();
$('#delete-dialog').html('<p>Do you want delete ' + name + ' ?</p>');
//for future use
$('#delete-dialog').dialog('open');
return false; // prevents the default behaviour
});
$('#delete-dialog').dialog({
dialogClass: "ConfirmBox",
autoOpen: false, width: 400, resizable: false, modal: true, //Dialog options
buttons: {
"Continue": function () {
$.post(deleteLinkObj[0].href, function (data) { //Post to action
if (data == '<%= Boolean.TrueString %>') {
deleteLinkObj.closest("tr").hide('fast'); //Hide Row
}
else {
}
});
$(this).dialog("close");
},
"Cancel": function () {
$(this).dialog("close");
}
}
});
</script>
And after dialog close I want something like a reload of a part of the page.
The data looks like
<table>
<tr>
<th> Name </th>
<th> Date </th>
<th> </th>
</tr>
#foreach (var m in this.Model)
{
<tr>
<td>
<div class="ProductName">#Html.DisplayFor(Model => m.Name)</div>
</td>
<td>
#Convert.ToDateTime(m.AddDate).ToShortDateString()
</td>
<td>
<div class="ProductPrice">#string.Format("{0:C}", m.Price)</div>
</td>
<td>
<div class="CategoryName">#Html.DisplayFor(Model => m.CategoryName)</div>
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = m.ID }, new { #class = "editLink" })
#Html.ActionLink("Delete", "Delete", new { id = m.ID }, new { #class = "deleteLink" })
</td>
</tr>
}
</table>
I'm not sure if im doing this well
I tried to put this action after click the button but nut sure if is right
I changed the Index to a Partial View
buttons: {
"Continue": function () {
$.post(deleteLinkObj[0].href, function (data) { //Post to action
if (data == '<%= Boolean.TrueString %>') {
deleteLinkObj.closest("tr").hide('fast'); //Hide Row
}
else {
}
});
$.ajax.ActionLink("Index",
"Index", // <-- ActionMethod
"Shop", // <-- Controller Name.
new { }, // <-- Route arguments.
null // <-- htmlArguments .. which are none. Y
)
$(this).dialog("close");
},
"Cancel": function () {
$(this).dialog("close");
}
}
I suggest you use the ASP.NET MVC ActionLink helper in your .cshtml file, and not jQuery:
[...]
<script type="text/JavaScript">
function openPopup()
{
// Set your options as needed.
$("#yourPopupDialogId").dialog("open");
}
</script>
[...]
#Ajax.ActionLink(
"Delete",
"Delete",
"Controller",
new { someValue = 123 },
new AjaxOptions
{
// Set your options as needed
HttpMethod = "GET",
UpdateTargetId = "yourPopupDialogId",
OnSuccess = "openPopup()"
}
)
[...]
<div id="yourPopupDialogId" style="display: none;"></div>
Now in your Controller for the methods you want to use for your popups you should return PartialViews:
public ActionResult Delete(int id)
{
RecordDeleteModel model = YourRepository.GetModel( id );
return PartialView( model );
}

Resources