After seeing a lot of code samples, I cant make a simple datatable using Jquery Datatables and MVC.
I got the error
My controller is this
public class DataTableController : Controller
{
// GET: DataTable
public ActionResult Index()
{
return View();
}
public ActionResult GetData()
{
var registros = new List<PruebaClass>();
var pruebaClass1 = new PruebaClass
{
Race = "Aliens",
Year = 1990,
Total = 50
};
var pruebaClass2 = new PruebaClass
{
Race = "MArcianos",
Year = 200,
Total = 20
};
registros.Add(pruebaClass1);
registros.Add(pruebaClass2);
var resultado = Json(new { aaData = registros.ToList() }, JsonRequestBehavior.AllowGet);
return resultado;
}
public class PruebaClass
{
public string Race { get; set; }
public int Year { get; set; }
public int Total { get; set; }
}
}
My view is this
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<table id="miTable">
<thead>
<tr>
<th>Race</th>
<th>Year</th>
<th>Total</th>
</tr>
</thead>
</table>
#section Scripts{
<link rel="stylesheet" type="text/css" href="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.0/css/jquery.dataTables_themeroller.css">
<link rel="stylesheet" type="text/css" href="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.0/css/jquery.dataTables.css">
<script type="text/javascript" charset="utf8" src="http://ajax.aspnetcdn.com/ajax/jquery.dataTables/1.9.0/jquery.dataTables.min.js"></script>
<script type="text/javascript" src="~/Scripts/MyDataTablejs.js"></script>
}
And my javascript file is this
$(document).ready(function () {
$('#miTable').DataTable(
{
"sAjaxSource": "../DataTable/GetData",
"columns": [
{ "Data": "Race", "autoWidth": true },
{ "Data": "Year", "autoWidth": true },
{ "Data": "Total", "autoWidth": true }
]
});
});
I can reach the ActionResult, and my view shows two rows but the content of each cell is null. And I got the awfull error Datatables warning (table id= 'miTable')Requested unknown parameter '0' from the datasource '0' .
Im pretty sure that the problem is the source (maybe the JSON format) and the column name mapping, but I cant figure out what is.
Any help?
Shame on me. Finally I matched the columns definition with apropiate options in the jquery file. I knew that I was missing something. All I need to do was to use the "aocolumns" and "mDataProp"
this code solves all
$(document).ready(function () {
$('#miTable').DataTable(
{
"sAjaxSource": "../DataTable/GetData",
"aoColumns": [
{ "mDataProp": "Race", "autoWidth": true },
{ "mDataProp": "Year", "autoWidth": true },
{ "mDataProp": "Total", "autoWidth": true }
]
});
});
Related
v1.10 Datatables.net table will not load using ajax - examples at datatables.net did not help, nor did the documentation. The table displays, but says "No data available in table". I don't think it matters, but this is for an old MVC5 app that I'm doing a little maintenance on. I'm hoping someone can spot what's wrong?
HTML Table definition:
<table id="bob">
<thead>
<tr>
<th>License Type</th>
<th>Active</th>
<th>Pending</th>
<th>Other</th>
</tr>
</thead>
<tfoot>
<tr>
<th>License Type</th>
<th>Active</th>
<th>Pending</th>
<th>Other</th>
</tr>
</tfoot>
</table>
JavaScript Init:
$(function () {
var url = '#Url.Action("LicenseCountsReport", "Letters")';
$('#bob').DataTable({
ajax: {
dataSrc: '',
url: url,
columns: [
{ data: 'licensetype' },
{ data: 'activecount' },
{ data: 'pendingcount' },
{ data: 'othercount' }
]
}
});
});
Data Method & Associated Classes:
public class LicenseCountReportItem
{
public string licensetype { get; set; }
public string activecount { get; set; }
public string pendingcount { get; set; }
public string othercount { get; set; }
}
private class JsonDataResult
{
public List<LicenseCountReportItem> data { get; set; }
}
[HttpGet]
public JsonResult LicenseCountsReport()
{
JsonDataResult reportData = new JsonDataResult
{
data = new List<LicenseCountReportItem>()
};
try
{
List<LicenseCountReportItem> items = _lr.GetLicenseCountsReport();
if (items != null && items.Count > 0)
{
reportData = new JsonDataResult
{
data = items
};
return Json(reportData, JsonRequestBehavior.AllowGet);
}
return Json(reportData, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
Logger.Log(ex, LogLevel.ERROR);
return Json(reportData, JsonRequestBehavior.AllowGet);
}
}
JSON Response (formatted), an array of objects:
{
"data":[
{
"licensetype":"Commercial Apprentice Applicators",
"activecount":"130",
"pendingcount":"22",
"othercount":"99"
},
{
"licensetype":"Professional Applicators",
"activecount":"4239",
"pendingcount":"3314",
"othercount":"55147"
}
]
}
There are 2 problems I can see:
1 - The first problem: You have used the DataTables ajax option: dataSrc: ''. Instead, you should remove this option (or use its default value of data, as follows: dataSrc: 'data').
If you use dataSrc: '', you are telling DataTables that your JSON is an unnamed array - something like this:
[
{
"licensetype": "Commercial Apprentice Applicators",
"activecount": "130",
"pendingcount": "22",
"othercount": "99"
},
{
"licensetype": "Professional Applicators",
"activecount": "4239",
"pendingcount": "3314",
"othercount": "55147"
}
]
But that is not how your JSON is structured. Your array is nested inside a JSON object: { "data": [ ... ] }.
2 - The second problem: You have placed your columns option inside the ajax option. But the columns option needs to be at the same level as the ajax option:
$('#bob').DataTable({
ajax: {
url: url,
},
columns: [
{ data: 'licensetype' },
{ data: 'activecount' },
{ data: 'pendingcount' },
{ data: 'othercount' }
]
});
The columns option is independent of the ajax option.
I want create a table with JSON using Javascript and obtaining data from a database and show it on my page when I load it. This table thas to have a link to put the data in the selected row into textboxes.
To fill the table I use a method on .asmx:
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json, UseHttpGet = false, XmlSerializeString = false)]
public void CargarUsuarios()
{
var wcf = new wsDN.ServicioClient();
var respuesta = wcf.Listar_Usuario().Valor.ToString();
Context.Response.ContentType = "application/json";
Context.Response.Write("{" + $"\"data\" : {respuesta}" + "}");
}
and this is how I create my table:
<table class="table table-bordered table-hover" id="tbl_Usuarios">
<thead>
<tr>
<th>ID Usuario</th>
<th>Cédula</th>
<th>Nombre</th>
<th>Apellidos</th>
<th>Usuario</th>
<th>Contraseña</th>
<th>Opciones</th>
</tr>
</thead>
</table>
and this is the JS:
<script src="js/main.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#tbl_Usuarios').DataTable({
"language": {
"url": "https://cdn.datatables.net/plug-ins/1.10.11/i18n/Spanish.json"
},
"ajax": {
"url": "/Contenido.asmx/CargarUsuarios",
"type": "POST",
"dataType": "json"
},
"columnDefs": [
{
"targets": 6,
"orderable": false,
"render": function (data, type, row) {
return 'Modificar';
}
}
]
});
});
</script>
Probably you need to add some library which will Add DataTable property/function to jquery/html element (do you use this jquery plugin datatables.net ? )
I'm trying to implement Server Side DataTable.
Everything goes perfectly fine up to the last rowCallback where I'm appending button to additional column for Actions (i.e. Edit/Delete).
Issue:
Here's my code.
<link href="~/Content/datatables.min.css" rel="stylesheet" /> //<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/v/dt/dt-1.10.16/datatables.min.css"/>
<link href="~/Content/font-awesome.min.css" rel="stylesheet" />
<div class="container">
<div class="row" style="margin-top:25px">
<table class="table table-bordered table-responsive dataTables-list">
<thead>
<tr>
<th>
Id
</th>
<th>
Name
</th>
<th>
Actions
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Id)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
<i class="fa fa-pencil"></i>
</td>
</tr>
}
</tbody>
</table>
</div>
</div>
JavaScript:
<script src="~/Scripts/datatables.min.js"></script> //<script type="text/javascript" src="https://cdn.datatables.net/v/dt/dt-1.10.16/datatables.min.js"></script>
<script>
$(document).ready(function () {
$('.dataTables-list').DataTable({
/*Sorting*/
"bSort": true,
"aoColumnDefs": [{
'bSortable': true
}],
"processing": true, // for show progress bar
"serverSide": true, // for process server side
"ajax": {
"url": "/Home/LoadData",
"type": "POST",
"datatype": "json"
},
"aoColumns": [{
"mDataProp": "Id"
}, {
"mDataProp": "Name"
}, {
"mDataProp": "Actions"
}],
"rowCallback": function (row, data, index) {
var newBtns = '<i class="fa fa-pencil"></i> ';
// $(row).append(newBtns);
$('td:eq(2)', row).html(newBtns);
},
language: {
paginate: {
next: '»',
previous: '«'
},
emptyTable: "Der er ingen poster.",
sInfo: "Viser _START_ til _END_ af poster."
}
});
});
</script>
Controller:
[HttpPost]
public ActionResult LoadData()
{
try
{
var draw = Request.Form.GetValues("draw").FirstOrDefault();
var start = Request.Form.GetValues("start").FirstOrDefault();
var length = Request.Form.GetValues("length").FirstOrDefault();
//Find Order Column
var sortColumn = Request.Form.GetValues("columns[" + Request.Form.GetValues("order[0][column]").FirstOrDefault() + "][data]").FirstOrDefault();
var sortColumnDir = Request.Form.GetValues("order[0][dir]").FirstOrDefault();
int pageSize = length != null ? Convert.ToInt32(length) : 0;
int skip = start != null ? Convert.ToInt32(start) : 0;
int recordsTotal = 0;
var v = (from a in _db.AllRoles select a); //Table contains only two Columns - Id and Name
//SORT
if (!(string.IsNullOrEmpty(sortColumn) && string.IsNullOrEmpty(sortColumnDir)))
{
v = v.OrderBy(sortColumn + " " + sortColumnDir);
}
recordsTotal = v.Count();
var data = v.Skip(skip).Take(pageSize).ToList();
return Json(new { draw = draw, recordsFiltered = recordsTotal, recordsTotal = recordsTotal, data = data }, JsonRequestBehavior.AllowGet);
}
catch (Exception ex)
{
throw;
}
}
The issue is due to column difference may be but I don't know how to solve it as implementing ServerSide Datatable for first time.
Thanks in advance.
I modified the below section in my Code to solve the Error.
"aoColumns": [{
"mDataProp": "Id"
}, {
"mDataProp": "Name"
}, {
"mDataProp": "Actions",
"defaultContent": '<i class="fa fa-pencil"></i> '
}],
I added defaultContent for that column as it is not getting values from Database/Sp.
P.S. Answer provided by #dee is also correct and will solve the error. Both are the Solutions to this Question.
The link in the error message provides very good information about what is the problem. You have specified three columns for the DataTable function but as you write in the comment Table contains only two Columns - Id and Name.
"aoColumns": [{
"mDataProp": "Id"
}, {
"mDataProp": "Name"
}, {
"mDataProp": "Actions"
}],
The Resolution section of the document tells what is needed to do:
If using columns ensure that you have specified exactly the number of columns that are present in the HTML for the table.
So you will need the transform the result of the query into another class which will have additional property for Actions. HTH
Newbie ALERT
Basically I have a web application that has a dropdown list. When you select an item in the drop-down list the table is drawn to show all the credentials that are tied to that drop-down option.
Problem: When running, everything functions properly except for the JavaScript piece that does not remove the line in the table, but deletes the record on the back-end. So once i refresh and go back to that credential type the one I deleted is gone.
I've tried a lot of different stuff, but i pretty new to JavaScript and C#, don't know if there is a better way of doing this. Probably supplied too much information but i rather too much than not enough! :)
Any help, tips, ideas are greatly appreciated.
Credential API Controller: Delete Function
[HttpDelete]
public IHttpActionResult DeleteCustomer(int id)
{
var credentialInDb = _context.Credentials.SingleOrDefault(c => c.Id == id);
if (credentialInDb == null)
return NotFound();
_context.Credentials.Remove(credentialInDb);
_context.SaveChanges();
return Ok();
}
Model for Credential
public class Credentials
{
public int Id { get; set; }
[Required]
[StringLength(255)]
public string Name { get; set; }
[Required]
[StringLength(255)]
public string Username { get; set; }
[Required]
[StringLength(255)]
public string Password { get; set; }
public string Website { get; set; }
public string Notes { get; set; }
public CredentialType CredentialType { get; set; }
[Display(Name = "Credential Type")]
public int CredentialTypeId { get; set; }
}
ViewModel for CredentialFormViewModel
This allows the selectedCredential variable for the page below
public class CredentialFormViewModel
{
public IEnumerable<CredentialType> CredentialTypes { get; set; }
public Credentials Credentials { get; set; }
public int SelectedCredentialTypeId { get; set; }
}
View that displays the DataTable:
#model Appp.ViewModels.CredentialFormViewModel
#{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Select a Credential Type</h2>
#Html.DropDownListFor(m => m.SelectedCredentialTypeId, new SelectList(Model.CredentialTypes, "Id", "Name"), "Select Credential Type", new { #class = "form-control", onchange = "SelectCredType()" })
<br/>
<table id="credentials" class="table table-bordered table-hover">
<thead>
<tr>
<th>Credential</th>
<th>Username</th>
<th>Password</th>
<th>Website</th>
<th></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
#section scripts
{
<script>
function SelectCredType() {
var credId = $('#SelectedCredentialTypeId').val();
if ($.fn.dataTable.isDataTable("#credentials")) {
if (credId == "") {
var table = $("#credentials").DataTable();
table.destroy();
} else {
var table = $("#credentials").DataTable();
table.destroy();
SelectCredType();
}
} else {
$(document)
.ready(function() {
var table = $("#credentials")
.DataTable({
ajax: {
url: "/api/credentials?credentialTypeId=" + credId,
dataSrc: ""
},
columns: [
{
data: "name",
},
{
data: "username"
},
{
data: "password"
},
{
data: "website"
},
{
data: "id",
render: function(data, type, credentials) {
return "<button class='btn btn-primary btn-xs js-delete' data-credential-id=" + credentials.id + ">Delete</button>";
}
}
]
});
}
);
}
};
$("#credentials")
.on("click",
".js-delete",
function() {
var button = $(this);
bootbox.confirm("Are you sure you want to delete this?",
function(result) {
if (result) {
$.ajax({
url: "/api/Credentials/" + button.attr("data-credential-id"),
method: "DELETE",
sucess: function() {
table.row(button.parents("tr")).remove().draw();
}
});
}
});
});
</script>
}
First issue
Your JavaScript code does not work because the table variable is undefined within your delete function.
There are many ways you could approach to fix that. But first you will need to get your head around variable scopes in JavaScript.
Your simplest solution is to make table a globally-scoped variable that way you can access the instance from any function you create. So instead of defining it here:
...
$(document)
.ready(function() {
var table = $("#credentials")
...
Move it up to the top of your script file:
var table;
function SelectCredType() {
...
$(document)
.ready(function() {
table = $("#credentials")
...
}
Now when you access it from your Delete function, it will be defined.
Note: I would also change the name of the table variable to something else as global variables in JavaScript will conflict with any script you import which can lead to a debugging nightmare. Best to name it something that will be most likely unique, eg. coberlinTable.
Second Issue
I don't know if you did a cut and past error, but you have misspelled success in your ajax Delete function.
My Kendo UI TreeView is not getting the returned JSON objects added to the treeview.
I can see from the controller method that gets called that the Json being given to the DataSource looks like this (but with more files and folders)
{"NodeID":-842352767,
"Name":"/",
"Folders":[{"NodeID":1804712307,"Name":"/$Recycle.Bin","Folders":null,"Files":null},{"NodeID":-582712839,"Name":"/Windows","Folders":null,"Files":null}],
"Files":["/.rnd","/msdia80.dll"]}
My view is as follows:
#model ProjName.Models.BrowseNode
<div id ="wrapper">
<h1>Browser</h1>
<div id="treeview" style="float:left;margin: 40px;">
</div>
</div>
<script>
function populateTreeView() {
var remoteDataSource = new kendo.data.HierarchicalDataSource({
type: "json",
transport: {
read: "FileBrowser/GetHierarchy"
},
schema: {
model: {
id: "NodeID",
text: "Name",
expanded: false,
children: "Folders",
},
}
});
$("#treeview").kendoTreeView({
dataSource: remoteDataSource,
dataTextField: "Name"
});
}
$(document).ready(function () {
populateTreeView();
});
With BrowseNode defined as:
public class BrowseNode
{
public int NodeID {
get
{
if (null == Name)
return default(int);
return Name.GetHashCode();
}
}
public string Name { get; set; }
public List<BrowseNode> Folders { get; set; }
public List<string> Files { get; set; }
}
Anything obviously wrong or any tips for debugging this sort of thing?
It turned out my JSON wasn't what the DataSource wanted. It should have been an array returned at the top level, so the JSON is surrounded by [ ] brackets as follows:
[{"NodeID":-842352767, "Name":"/", "Folders":[{"NodeID":1804712307,"Name":"/$Recycle.Bin","Folders":null,"Files":null},{"NodeID":-582712839,"Name":"/Windows","Folders":null,"Files":null}], "Files":["/.rnd","/msdia80.dll"]}]