This is my html where I show the DataTable:
<tr>
<th>ID</th>
<th>Assurance</th>
<th>Credit Balance</th>
<th>Credit Result</th>
<th>Created Date</th>
<th style="text-align: center">Actions</th>
</tr>
</thead>
<tbody>
<tr th:each="credit: ${credits}">
<td th:text="${credit.id}"/>
<td th:text="${credit.assurance}"/>
<td th:text="${credit.creditBalance}"/>
<td th:text="${credit.creditResult}"/>
<td type="date" pattern="yyyy-MM-dd" th:text="${credit.creationDate}"/>
This is the endpoint:
#PreAuthorize("hasRole('ROLE_ADMIN')")
#GetMapping("/showList")
public ModelAndView showCreditList(){
ModelAndView mav = new ModelAndView("list-credits");
mav.addObject("credits",creditService.getAllCredits());
return mav;
}
And this is the script where I create the DataTable:
<script>
$(document).ready(function (){
$("#credit").DataTable();
})
</script>
I have no problem while creating this DataTable. But I tried so many ways like
$(document).ready(function() {
var table = $('#example').DataTable({
"ajax": "/api/data"
});
setInterval( function () {
table.ajax.reload();
}, 5000 );
});
Another try:
$(document).ready(function() {
var table = $('#example').DataTable({
columns: [
{ title: "Field 1" },
{ title: "Field 2" },
{ title: "Field 3" }
],
ajax: {
url: "/api/data",
dataSrc: function(data) {
var tableData = data.map(function(record) {
return [record.field1, record.field2, record.field3];
});
return tableData;
}
}
});
setInterval( function () {
table.ajax.reload();
}, 5000 );
});
But the problem is I am returning a List<Credit> from my endpoint. So ajax.reload simply can't format the data for DataTable. I am using this call from ajax.
#GetMapping("/all")
public List<Credit> getAllCredits(){
return creditService.getAllCredits();
}
Do you have any solution to this? How do I solve it?
I am trying to write an event handler for page change in a datatable. following is the existing code.. the libraries are included in a baselayout for following code..
DefaultView.cshtml
<div class="row">
<div class="col-lg-6 col-md-6 col-sm-6 col-xs-6 pageheading">
<h1>
<small>AMS Default</small>
</h1>
</div>
</div>
<hr />
<br />
<div class="row">
<div class="col-lg-12">
<table dt-options="dtOptions" datatable dt-columns="dtColumns"
class="table table-striped table-bordered dt-responsive">
<thead>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
</table>
</div>
</div>
#section CommonScripts{
<script src="~/Angular/Areas/Common/Controllers/DefaultController.js"></script>
<script src="~/Angular/Areas/Common/Services/DefaultService.js"></script>
}
Defaultcontroller.js
AMSApp.controller('DefaultController', ['$rootScope', 'DefaultService', 'DTOptionsBuilder', 'DTColumnBuilder',
function ($rootScope, DefaultService, DTOptionsBuilder, DTColumnBuilder) {
var self = this;
this.Users = {};
this.GetAllUsers = function () {
$rootScope.CloseAlerts();
DefaultService.GetAllUsers().success(function (result) {
self.Users = result;
self.loadd();
}).catch(function (error) {
$rootScope.ErrorMsg = "OOPS some thing went wrong. Please try again.";
});
}
this.GetAllUsers();
this.loadd = function () {
$rootScope.dtColumns = [
DTColumnBuilder.newColumn('DisplayName').withTitle('UserName'),
DTColumnBuilder.newColumn('IsSNA').withTitle('IsSNA'),
DTColumnBuilder.newColumn('IsAdmin').withTitle('IsAdmin'),
DTColumnBuilder.newColumn('IsDownloadPermitted').withTitle('DownloadPermitted')
];
$rootScope.dtOptions = DTOptionsBuilder.newOptions()
.withOption('data', self.Users)
.withDisplayLength(10);
}
}]);
/*
Button Click handler:
$("#customerSearchButton").on("click", function (event) {
$.ajax({
url: "",
type: "post",
data: { searchText: searchText }
}).done(function (result) {
Table.clear().draw();
Table.rows.add(result).draw();
}).fail(function (jqXHR, textStatus, errorThrown) {
// needs to implement if it fails
});
}
*/
DefaultService.js
AMSApp.service('DefaultService', function ($http) {
this.GetAllUsers = function () {
return $http.get('/Common/User/GetAllUsers');
}
});
I tried several versions like in the above-commented code.. but I need something like following in the controller.
/*need something like this*/
DTOptionsBuilder.on('page.dt', function () {
var info = table.page.info();
console.log("hey i got eexecuted");
$('#pageInfo').html('Showing page: ' + info.page + ' of ' + info.pages);
});
firstly is it possible? - if not what are other alternatives?
Note: I prefer not to give an id to the table.
I wanted to get values from form fields and save them as an object into an observableArray. And show them in the table. So, every time i hit 'add' button the table should be updated but its not working.
<select data-bind="options: gradeList, optionsText: 'Name', value: selectedGrade"></select>
<input type="text" data-bind="value: komark" />
<button data-bind="click: addMark">Add</button>
<table>
<thead>
<tr>
<th>SN</th>
<th>Name</th>
<th>Mark</th>
</tr>
</thead>
<tbody data-bind="foreach: allMarks">
<tr>
<td data-bind="$data.id"></td>
<td data-bind="$data.name"></td>
<td data-bind="$data.mark"></td>
</tr>
</tbody>
</table>
<p data-bind="text: allMarks"></p>
this is my html. 'gradeList' is also an observableArray but its working and i'm getting nice dropdown menu. On last 'p' element, text gets updated with every 'add' button click with [Object object] text but table never gets updated.
var newModel = function () {
var self = this;
self.komark = ko.observable();
self.mark = ko.observable();
self.selectedGrade = ko.observable();
self.gradeList = ko.observableArray([]);
self.allMarks = ko.observableArray([]);
self.loadAllGrades = function () {
$.ajax({
type: "GET",
dataType: "text",
url: "studenthandler.ashx",
data: { "action": "getAllGrades", "id": 0 },
success: function (res) {
self.gradeList(JSON.parse(res));
},
error: function () {
alert("Failed to load.\nHit Refresh.");
}
});
};
self.addMark = function () {
// console.log("button clicked");
self.mark({ "id": self.selectedGrade().Id, "name": self.selectedGrade().Name, "mark": self.komark() });
console.log(self.mark());
self.allMarks.push(self.mark());
console.log(self.allMarks());
};
self.loadAllGrades();
}
this is my javasript. The value of 'mark' and 'allMarks' gets updated in console but TABLE never gets updated.
<td data-bind="$data.id"></td> doesn't do anything, you haven't specified a binding. You probably wanted:
<td data-bind="text: $data.id"></td>
<!-- ----------^^^^^^ -->
...and similar for name, mark.
Working example:
var newModel = function() {
var self = this;
self.komark = ko.observable();
self.mark = ko.observable();
self.selectedGrade = ko.observable();
self.gradeList = ko.observableArray([]);
self.allMarks = ko.observableArray([]);
self.loadAllGrades = function() {
/*
$.ajax({
type: "GET",
dataType: "text",
url: "studenthandler.ashx",
data: { "action": "getAllGrades", "id": 0 },
success: function (res) {
self.gradeList(JSON.parse(res));
},
error: function () {
alert("Failed to load.\nHit Refresh.");
}
});
*/
self.gradeList.push(
{Id: 1, Name: "Grade1"},
{Id: 2, Name: "Grade2"},
{Id: 3, Name: "Grade3"}
);
};
self.addMark = function() {
// console.log("button clicked");
self.mark({
"id": self.selectedGrade().Id,
"name": self.selectedGrade().Name,
"mark": self.komark()
});
//console.log(self.mark());
self.allMarks.push(self.mark());
//console.log(self.allMarks());
};
self.loadAllGrades();
}
ko.applyBindings(new newModel(), document.body);
<select data-bind="options: gradeList, optionsText: 'Name', value: selectedGrade"></select>
<input type="text" data-bind="value: komark" />
<button data-bind="click: addMark">Add</button>
<table>
<thead>
<tr>
<th>SN</th>
<th>Name</th>
<th>Mark</th>
</tr>
</thead>
<tbody data-bind="foreach: allMarks">
<tr>
<td data-bind="text: $data.id"></td>
<td data-bind="text: $data.name"></td>
<td data-bind="text: $data.mark"></td>
</tr>
</tbody>
</table>
<p data-bind="text: allMarks"></p>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
Side note: $data.id is a long way to write id. :-)
Side note 2: The [object Object] you're seeing for allMarks is because you're applying the text binding to an array of objects, so you get the default toString behavior of the object. You probably want a foreach for allMarks as well.
The following code samples demonstrates how I initialize a jQuery Datatable with HTML, knockout and typescript
HTML:
<table id="coursemoment-info-table" class="table table-hover">
<thead>
<tr >
// headers
</tr>
</thead>
<tbody>
<!-- ko foreach: selectedCourseMoment().courseApplications -->
<tr>
<td>
<a data-bind="{text: ssn, attr:{ href: '/Medlem/' + ssn} }"></a>
</td>
<td data-bind="text:name + ' ' + surname"></td>
.
.
.
</tr>
<!-- /ko-->
</tbody>
</table>
Typescript:
private initCourseMomentInformationDataTable(): void {
$("#coursemoment-info-table").DataTable({
pageLength: 5,
order: [1, 'desc'],
language: {
url: "/Assets/js/jquery-datatable-swedish.json"
}
});
}
I have had some problems with reinitializing the table, but I managed to handle it with first clearing the datatable, and then adding rows to the datatable and redraw it.
if (this.tableInitiliazed) {
$("#coursemoment-info-table").DataTable().clear().draw();
for (var i = 0; i < data.courseApplications.length; i++) {
var application = data.courseApplications[i];
$("#coursemoment-info-table").DataTable().row.add(
[
application.ssn,
// blah blah yada yada
]).draw();
}
This does indeed reinitiliaze the datatable, but it does not put a hyperlink to the first column as it does when initializing the table. All the other table settings are correct, such as language and pagelength.
Since I add one row at a time, with the multiple columns I do not know how to set column settings for "applications.ssn" directly. I have tried to initialize the datatable in the viewmodel with typescript but I get the same problem.
Any ideas how to reinitialize and put a hyperlink setting for a specific column?
I think you want to use Datatables render to create your link. so here is a custom data binder for data table that uses render to create the link.
here is the fiddle to see it in action. http://jsfiddle.net/LkqTU/35823/
ko.bindingHandlers.dataTable = {
init: function(element, valueAccessor, allBindingsAccessor) {
var value = valueAccessor(),
rows = ko.toJS(value);
allBindings = ko.utils.unwrapObservable(allBindingsAccessor()),
$element = $(element);
var table = $element.DataTable( {
data: rows,
columns: [
{ data: "id" },
{ data: "firstName" },
{ data: "lastName" },
{ data: "phone" },
{
data: "ssn",
"render": function ( data, type, full, meta ) {
return '<a href="/Medlem/'+data+'">' + data + '<a>';
}
}
]
} );
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$element.dataTable().fnDestroy();
});
value.subscribe(function(newValue) {
rows = ko.toJS(newValue)
console.log(rows);
$element.find("tbody tr").remove();
table.rows().remove().draw();
setTimeout(function(){ $.each(rows, function( index, row ) {
table.row.add(row).draw()
});
}, 0);
}, null);
}
}
Currently I am doing datatable server side ajax processing. Scenario is:
As like normal datatable operations i.e. sorting-searching-pagination.
one Column(say the last one) with action header will contain the action buttons like ADD/EDIT/DELETE/MARK/CACHE etc.
Based on user role and its access permission user can access particular buttons which is assigned by admin. For Example,
User with Role=1 has ADD-EDIT button enabled.
User with Role=2 has EDIT-DELETEbutton enabled
When userrole 1 or 2 is logged in user can see and access only that buttons.
If I pass the access information from JSP's(getting info from session object) script tag to main javascript function and with If-Else condition it can be done.BUT the access information is exposed to client.
REQUIREMENT: I want to create buttons dynamically but in server side(Java-Spring) or hiding the logic from user.
so far this is my try:
script.js
function getDatatable(id, url, columns) {
globalDatatable = $('#' + id).DataTable({
lengthChange : false,
processing : true,
serverSide : true,
order : [ [ 0, 'asc' ] ],
paging : true,
fnDrawCallback : function(oSettings) {
},
ajax : {
url : url,
type : "GET",
datatype : "application/json",
data : function(d) {
return JSON.stringify(d);
}
},
initComplete : function(settings, json) {
},
columns : columns,
});
}
function getIpRangeDatatable(id,url){
var columns=[];
columns.push({ data: "ipid" ,name:"ipid"});
columns.push({ data: "startIp",name:"startIp" });
columns.push({ data: "endIp",name:"endIp" });
columns.push({ data: "allow",name:"allow" });
columns.push({ data: "roleName" ,name:"roleName"});
columns.push({ data: "description" ,name:"description"});
columns.push({ data: "loginId",name:"loginId" });
columns.push({ data:function(o1){ return parseDateTime(o1.fromDate); },name:"fromDate" });
columns.push({ data: function(o1){ return parseDateTime(o1.toDate); },name:"toDate" });
columns.push({ data: function(o1){
var buttons=[{name:"Edit", action:"doOperations(2,12,3,"+o1.ipid+")"}
,{name:"Delete", action:"doOperations(3,12,4,"+o1.ipid+")"}];
return getActionMenus(buttons);
}});
getDatatable(id,url,columns);
}
function getActionMenus(buttons) {
var menu= "<div class='btn-group'>"+
"<button type='button' class='btn btn-default'><span class='glyphicon glyphicon-share' aria-hidden='true'></span> Action</button>"+
"<button type='button' class='btn btn-default dropdown-toggle' data-toggle='dropdown' aria-haspopup='true' aria-expanded='false'> <span class='caret'></span> <span class='sr-only'>Toggle Dropdown</span> </button>"+
"<ul class='dropdown-menu dropdown-menu-right'>";
for(var i in buttons ){
menu+="<li><a href='javascript:"+buttons[i].action+"' data-title='IpRange'><span class='glyphicon glyphicon-edit' aria-hidden='true'></span>"+ buttons[i].name+"</a></li>";
}
menu+="</ul></div>";
return menu;
}
Test.jsp
<%
String ctxPath = request.getContextPath() + "/";
String id = "ipRange_" + Utils.getUUID();
%>
<div class="wrapper-content-area-pad">
<div class="panel panel-primary flat-panel">
<div class="panel-heading flat-panel">IP Range Details</div>
<div class="panel-body">
<a href="javascript:doGenericOperations(2,12,3,0)"class="btn btn-default" data-title="IpRange">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span>Add IP</a>
<table id="<%=id%>"
class="table compact table-striped table-bordered table-action" cellspacing="0"
width="100%">
<thead>
<tr>
<th>IPId</th>
<th>Start IP</th>
<th>End IP</th>
<th>Allow Rule</th>
<th>Type of User</th>
<th>Description</th>
<th>Username</th>
<th>From Date</th>
<th>To Date</th>
<th>Actions</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
<script>
$(document).ready(function(){
getIpRangeDatatable('<%=id%>', 'appAdmin/s/manage_ip/datatable/1');
});
</script>
JSON data sample:
{"draw":1,"recordsFiltered":6,"data":[{"ipid":11,"startIp":"172.16.0.0","endIp":"172.16.255.255","allow":0,"allowNull":false,"description":"Faculty ip range ","roomId":0,"roomIdNull":false,"fromDate":null,"toDate":1474889095000,"userId":9295,"userIdNull":false,"roleName":"Faculty","userRoleId":4,"userRoleIdNull":false,"loginId":"shylaja.sharath#pes.edu"},{"ipid":12,"startIp":"10.10.101.10","endIp":"10.10.101.10","allow":0,"allowNull":false,"description":"Tech team Ubuntu","roomId":0,"roomIdNull":false,"fromDate":null,"toDate":null,"userId":0,"userIdNull":true,"roleName":"Student","userRoleId":3,"userRoleIdNull":false,"loginId":null},{"ipid":13,"startIp":"172.16.0.1000","endIp":"172.16.255.255","allow":0,"allowNull":false,"description":"Faculty ip range ","roomId":0,"roomIdNull":false,"fromDate":null,"toDate":null,"userId":0,"userIdNull":true,"roleName":null,"userRoleId":0,"userRoleIdNull":true,"loginId":null},{"ipid":18,"startIp":"172.16.174.40","endIp":"172.16.174.40","allow":1,"allowNull":false,"description":"Faculty IP Range","roomId":12,"roomIdNull":false,"fromDate":null,"toDate":null,"userId":0,"userIdNull":true,"roleName":"Faculty","userRoleId":4,"userRoleIdNull":false,"loginId":null},{"ipid":20,"startIp":"192.168.1.12","endIp":"192.168.3.35","allow":0,"allowNull":false,"description":"","roomId":0,"roomIdNull":false,"fromDate":null,"toDate":null,"userId":0,"userIdNull":true,"roleName":null,"userRoleId":0,"userRoleIdNull":true,"loginId":null},{"ipid":21,"startIp":"1.1.1.1","endIp":"192.168.1.255","allow":0,"allowNull":false,"description":"","roomId":0,"roomIdNull":true,"fromDate":null,"toDate":null,"userId":0,"userIdNull":true,"roleName":null,"userRoleId":0,"userRoleIdNull":true,"loginId":null}],"recordsTotal":6}