I am using https://github.com/yajra/laravel-datatables/ package
to show data within html table via ajax request and here is my settings
route
Route::get('dashboard/initiation-by-org', ['uses' =>'DashboardController#showTotalInitiationByOrganization']);
controller
public function showTotalInitiationByOrganization(){
$litigation = collect(Dashboard::countLitigationsOfAnOrganizationByCountry());
return Datatables::of($litigation)->make(true);
}
call data table
$('#organization-cases').DataTable({
processing: true,
serverSide: true,
aaSorting: [],
iDisplayLength: 6,
iDisplayStart: 0,
ajax: '/dashboard/initiation-by-org',
"columns": [
{'data': 'organization'},
{'data': 'litigations'}
]
});
**My json response**
{
"draw": 0,
"recordsTotal": 2,
"recordsFiltered": 2,
"data": [
{
"organization": "Shakti Samuha",
"litigations": 1
},
{
"organization": "CWIN",
"litigations": 1
}
],
"input": [
]
}
my table
<table id="organization-cases" class="table table-bordeard">
<thead>
<tr>
<th>Organization</th>
<th>Litigations</th>
</tr>
</thead>
</table>
I have install this package according to the installation manual but I did not get any data in my table.
please tell me What is the problem of this issue?
Thanks
Manoz
Related
This is my working cshtml with ajax. Currently $(function () { loaddata();}) is what initializes the DataTable and "url": '/LoadData'() posts to the controller. But I need it to Post only when validation passes. I still need the Datatable to initialize though. When the document is ready I would like to initialize the Datatable just not LoadData. Post should automatically happen when validation passes.
button onclick="test()">RefreshData</button>
<table id="tblList" class="table table-striped table-bordered" style="width:100%">
<thead>
<tr>
<th>a</th>
<th>b</th>
<th>c</th>
<th>d</th>
</tr>
</thead>
</table>
js:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.1/jquery-ui.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.10.21/css/jquery.dataTables.css">
function test() {
$('#tblList').DataTable().ajax.reload();
}
function validationfailure() {
//$('#firstname').val()=="";
return 'please enter a valid name'
}
function loaddata() {
var data = {};
data.id = $("#id").val();
$('#tblList').DataTable({
destroy: true,
ajax: {
"type": "POST",
"url": '/LoadData',
"dataType": "json",
"data": function(d) {
d.id = $("#id").val();
}
},
columns: [
{ "data": "a", responsivePriority: 1, "searchable": true },
{ "data": "b", responsivePriority: 2, "searchable": true },
{ "data": "c", responsivePriority: 3, "searchable": true },
{ "data": "d", responsivePriority: 4, "searchable": true },
],
});
};
$(function() {
if(!validationfailure)
loaddata();
})
action:
[HttpPost]
[Route("LoadData")]
public IActionResult GetFinanceiro(SearchModel s)
{
List<DataTableModel> l = new List<DataTableModel> {
new DataTableModel{ a="a1"+s.Id,b="b1"+s.Id,c="c1"+s.Id,d="d1"+s.Id},
new DataTableModel{ a="a2",b="b2",c="c2",d="d2"},
new DataTableModel{ a="a3",b="b3",c="c3",d="d3"},
new DataTableModel{ a="a4",b="b4",c="c4",d="d4"},
};
return Json(new { data = l });
}
I am implementing jquery DataTable with server-side pagination. Refer code snippet below -
Script
$(async function() {
$('#registry_table').DataTable({
serverSide: true,
ajax: {
url: 'localhost:3000/provenance/registries',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + localStorage.getItem("token")
},
data: () => {
return {page: 0, per_page: 5};
}
},
columns: [
{data: 'name', defaultContent: 'N/A'},
{data: 'created', defaultContent: 'N/A'},
{data: 'extrinsic', defaultContent: 'N/A'},
{data: 'registry', defaultContent: ' <span class="text-primary bg-white fa-border d-inline-block" style="cursor: pointer" title="Rename Registry"><i class="fas fa-pen-nib"/> Rename</span>'}
],
language: {
searchPlaceholder: "Search...",
search: "",
lengthMenu: "_MENU_ items/page"
}
});
});
Html
<table class="table table-striped mg-b-0" id="registry_table">
<thead>
<tr>
<th class="text-left">#</th>
<th class="text-left">Name</th>
<th class="text-left">Created on</th>
<th class="text-left">Transaction</th>
<th class="text-center">Action</th>
</tr>
</thead>
</table>
API response
{
"registries": [
{
"registry": 489607958,
"created_by": "5DqdTHZLA8X2Lk2FqCPFM9kxd8GmdMbyboFiFg6gmB8sHCg4",
"name": "test 7",
"created": "2020-09-14T15:08:49.006766"
},
{
"registry": 1421927575,
"created_by": "5DqdTHZLA8X2Lk2FqCPFM9kxd8GmdMbyboFiFg6gmB8sHCg4",
"name": "test 6",
"created": "2020-09-14T15:08:43.104835"
},
{
"registry": 1560576458,
"created_by": "5DqdTHZLA8X2Lk2FqCPFM9kxd8GmdMbyboFiFg6gmB8sHCg4",
"name": "test 4",
"created": "2020-09-14T15:08:34.132407"
},
{
"registry": 1766285412,
"created_by": "5DqdTHZLA8X2Lk2FqCPFM9kxd8GmdMbyboFiFg6gmB8sHCg4",
"name": "test 5",
"created": "2020-09-14T15:08:27.376323"
},
{
"registry": 155398053,
"created_by": "5DqdTHZLA8X2Lk2FqCPFM9kxd8GmdMbyboFiFg6gmB8sHCg4",
"name": "test 3",
"created": "2020-09-14T15:08:16.768747"
}
],
"total": 7
}
If the total number of rows is 7 and per_page = 5, then it should show 2 pages. But in the browser, it shows 5 pages. Also, page info shows wrong information.
Browser
My questions are-
Is there a way to set the number of pages/total items once data fetched
Page info should be Showing 1 to 5 of 7 entries (filtered from 7 total entries), how to set those properly?
How to pass the entire row as a parameter to a function (rename button)
Note: API is in production and unlikely to change.
Update 1:
Script (modified data and added dataSrc with ajax section
data: (d) => {
d.page =self.page;
d.per_page =self.per_page;
delete d.columns;
delete d.order;
delete d.search;
delete d.start;
delete d.length;
},
dataSrc: (response) => {
response.draw = 1;
response.recordsTotal = response.total;
response.recordsFiltered = response.registries.length;
response.data = response.registries;
return response.data;
}
Now it doesn't show any data but, everything else is fine.
I am working on datatable .i want pagination on search for example i have a datatable with pagination . i have a search option but pagination does not work on search
<input class="btn btn-secondary" type="button" value="Show TheResults" id="theBtnSearch" />
$("#theBtnSearch").click(function () {
if ($.fn.dataTable.isDataTable('#thedatatab')) {
table = $('#thedatatab').DataTable();
//https://datatables.net/reference/api/ajax.reload()
table.ajax.reload();
}
});
<div class="DataTableClass" id="TheHeaderStyle" style="width: 100%">
<table id="thedatatab'" class="display table table-striped table-bordered">
<thead>
<tr>
<th><%: Html.DisplayNameFor(r => r.fieldA)%></th>
<th><%: Html.DisplayNameFor(r => r.fieldB)%></th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
The method that gets called into
public JsonResult GetTheData(DTParameters param)
{
try
{
//call stored procedure with parms from DTParameters
//DTParameters comes with your datatables download, if you did it right
return Json(result);
}
}
Your DataTable declaration
$('#thedatatab').DataTable({
"pagingType": "full",
"serverSide": true,
"oLanguage": {
"sSearch": "Filter Search Results:" //http://legacy.datatables.net/usage/i18n#oLanguage.sSearch
},
"ajax": {
"type": "POST",
"url": '/Case/GetTheData',
"contentType": 'application/json; charset=utf-8',
'data': function (data) {
//http://stackoverflow.com/questions/24499116/how-to-pass-parameters-on-reload-of-datatables
//all the search parms here
data.searchParm = $("#searchParm").val();
return data = JSON.stringify(data);
}
},
"processing": true,
"columns": [
{ "data": "fieldA" },
{ "data": "fieldB" },
],
columnDefs: [
{
"targets": [0],
"visible": false,
"searchable": false
}
],
"order": [1, "desc"]
, "createdRow": function (row, data, index) {
$(row).click(function () {
$("#ajaxSpinner").removeClass("HideMeDisplay");
$("#TheHiddenRowNumber").val(data.FieldA)
$("form").submit();
});
}
});
I have a Linq query that is returning data in 900 - 919ms through EF Core (over VPN). However, once the data is returned it is taking an age (20-30 seconds) to render the HTML table. The dataset is about 18,000 rows with 8 columns and I have implemented DataTables to paginate, filter and export. The dataset itself is comprised of text only.
I have been trying to profile those 20-30 seconds to no great success, I just can't seem to find the route of the issue.
Has anyone faced similar issues?
Can anyone recommend a good debug methodology to understand the cause of delay?
I have logging enabled and that is not telling me anything of use, Application Insights in VS is not available to me.
Many thanks.
Update
Below is method.
public async Task<ActionResult> ExportGrid()
{
var result = await dbcontext.Timesheet.AsNoTracking()//.Take(100)
//.Include(t => t.Program)
//.ThenInclude(p => p.Client)
//.Include(t => t.Task)
//.Include(t => t.Person)
.Where(t => !t.Deleted)
.Select(t => new TimesheetDataViewModel
{
Id = t.Id,
ClientName = t.Program.Client.Name,
ProgramName = t.Program.Name,
TaskType = t.Task.Name,
TaskName = t.Name,
TaskDescription = t.Description,
TaskStart = t.TaskStart,
TaskEnd = t.TaskEnd,
Minutes = t.Minutes,
Person = t.Person.Firstname + ' ' + t.Person.Surname
}).ToListAsync();
return View(result);
}
Below is the DataTables code
var _tableId = $('#datatable_timesheet');
var _orderColumns = [1];
var _searchableColumns = [0,1,2];
var _defaultSort = [1, "asc"];
$(document).ready(function () {
_tableId.DataTable({
paging: true,
ordering: true,
info: false,
responsive: true,
deferRender: false,
dom: '<"row"<"col-sm-3"l><"col-sm-6 text-center"B"><"col-sm-3"f>><"row"<"col-sm-12"tr>><"row"<"col-sm-5"i><"col-sm-7"p>>',
buttons: true,
lengthMenu: [
[5, 15, 20, -1],
[5, 15, 20, "All"] // change per page values here
],
//pagingType: "bootstrap_full_number",
language: {
"lengthMenu": " _MENU_ records",
"paginate": {
"previous": "Prev",
"next": "Next",
"last": "Last",
"first": "First"
}
},
columnDefs: [{ // set default column settings
'orderable': true,
'targets': _orderColumns
}, {
"searchable": true,
"targets": _searchableColumns
}]
//order: _defaultSort // set first column as a default sort by asc*/
});
});
it will paginate on client side
for better performance you can use server side pagination - for e.g. refer article to use server side pagination.
https://www.codeproject.com/Tips/1011531/Using-jQuery-DataTables-with-Server-Side-Processin
I found this quite hard to get my head round and in case anyone else is, below is how I finally got everything working except sort for an application built using .Net Core 1.1 and Entity.Framework.Core
HTML
<table class="table table-striped table-bordered table-hover" id="exportGrid">
<thead>
<tr>
<th>
Client Name
</th>
<th>
Program Name
</th>
<th>
Person
</th>
<th>
Minutes
</th>
<th>
Task Name
</th>
<th>
Task Description
</th>
<th>
Task Type
</th>
<th>
Task Start
</th>
<th>
Task End
</th>
</tr>
</thead>
</table>
JS and AJAX
$('#exportGrid').DataTable({
processing: true,
serverSide: true,
ajax: { "url": "TimesheetDataJsonObjectArray", "type": "POST" },
columns: [
{ "data": "clientName" },
{ "data": "programName" },
{ "data": "person" },
{ "data": "minutes" },
{ "data": "taskName" },
{ "data": "taskDescription" },
{ "data": "taskType" },
{ "data": "taskStart" },
{ "data": "taskEnd" }],
pageLength: 15,
paging: true,
ordering: true,
info: true,
responsive: true,
deferRender: false,
dom: '<"row"<"col-sm-3"l><"col-sm-6 text-center"B"><"col-sm-3"f>><"row"<"col-sm-12"tr>><"row"<"col-sm-5"i><"col-sm-7"p>>',
buttons: true,
lengthMenu: [
[5, 15, 20, -1],
[5, 15, 20, "All"]
]
});
Controller
[HttpPost]
public async Task<ActionResult> TimesheetDataJsonObjectArray(int draw, int start, int length)
{
var formData = HttpContext.Request.Form;
string search = formData["search[value]"];
var q = dbcontext.Timesheet.Where(t => !t.Deleted);
if(!String.IsNullOrEmpty(search))
{
q = q.Where(t => t.Person.Surname.Contains(search));
}
var b = await q
.Select(t => new TimesheetDataViewModel
{
Id = t.Id,
ClientName = t.Program.Client.Name,
ProgramName = t.Program.Name,
TaskType = t.Task.Name,
TaskName = t.Name,
TaskDescription = t.Description,
TaskStart = t.TaskStart,
TaskEnd = t.TaskEnd,
Minutes = t.Minutes,
Person = t.Person.Firstname + ' ' + t.Person.Surname
}).ToListAsync();
var result = b.Skip(start).Take(length);
DataTableData a = new DataTableData();
a.data = result.ToList();
a.draw = draw;
a.recordsTotal = q.Count();
a.recordsFiltered = q.Count();
return Json(a);
}
This is the bill_info table, for which i need to serialized row no like 1 2 . . . . . . . . . . . . .n
There is data list returned, how I can get serial_no custom field in datatable list view.
$data = BillInfo::get(['bill_info.*']);
return Datatables::of($data)
->removeColumn('id')
->make(true);
If you are using yajra laravel datatables
Just add ->addIndexColumn()
return DataTables::of($data)
->addIndexColumn()
->make(true);
In your javascript, you can set the first row as a serial number like this
columns: [
{ data: 'DT_RowIndex', name: 'DT_RowIndex', orderable: false, searchable: false },
{ data: 'name', name: 'name' },
{ data: 'action', name: 'action' }
]
use DT_Row_Index instead of DT_RowIndex for older yajra datatable version
When using Yajra Laravel datatables
return DataTables::of($result)
->addIndexColumn()
->make(true);
"columns": [
{
"data": 'DT_RowIndex',
orderable: false,
searchable: false
},
]
Set the variable rownum at the beginning of your query. Then set the increment process in your query.
DB::statement(DB::raw('set #rownum=0'));
$data = BillInfo::get(['bill_info.*',
DB::raw('#rownum := #rownum + 1 AS rownum')]);
return Datatables::of($data)
->removeColumn('id')
->make(true);
Here you can get rownum as serial no of the given records [1 . . . 8].
In Laravel Yajra Datatables v9.x as Service Implementation, I add this in getColumns function and works well in sorting, searching, and page changing.
'id' => ['title' => 'N.', 'orderable' => false, 'searchable' => false, 'render' => function() {
return 'function(data,type,fullData,meta){return meta.settings._iDisplayStart+meta.row+1;}';
}],
You can see my code :
<table id="datatable" class="table table-bordered table-striped">
<thead>
<tr>
<th>Sl No</th>
<th>Invoice No</th>
<th>Customer</th>
<th>Total Price</th>
<th>Paid</th>
<th>Due</th>
<th>Discount</th>
<th>Action</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
And the script part:
<script type="text/javascript">
$(function() {
var i = 1;
var table = $('#datatable').DataTable({
processing: true,
serverSide: true,
ajax: "{{ route('collections') }}",
columns: [{
"render": function() {
return i++;
}
},
{
data: 'issue_no',
name: 'issue_no'
},
{
data: 'customer_name',
name: 'customer_name'
},
{
data: 'total_order_price',
name: 'total_order_price'
},
{
data: 'paid_amount',
name: 'paid_amount'
},
{
data: 'due_amount',
name: 'due_amount'
},
{
data: 'discount_amount',
name: 'discount_amount'
},
{
data: 'action',
name: 'action',
orderable: false,
searchable: false
}
],
createdRow: function ( row, data, index ) {
if (data['due_amount'] > 0) {
$('td', row).eq(4).css('background-color', '#f4511e','color','#ffffff');
$('td', row).eq(4).css('color','#ffffff');
} else {
}
$('td', row).eq(3).addClass('text-right');
$('td', row).eq(4).addClass('text-right');
$('td', row).eq(5).addClass('text-right');
$('td', row).eq(6).addClass('text-right');
}
});
});
</script>
In the rendering part, you can add the auto-increment field
{
"render": function() {
return i++;
}
},
simple using render function script on yajra datatable, this is my code:
protected function getColumns()
{
return [
Column::make('row_number')
->title('#')
->render('meta.row + meta.settings._iDisplayStart + 1;')
->width(50)
->orderable(false),
];
}