Fetching Json string of C# datatable and displaying in jquery Datatable - javascript

Main thing is i am new in Jquery Datatable and from last 2 days I am trying to use it, using json string. But i am not getting require output.
Here is my HTML :
<body>
<div class="container">
<table id="MydataTableDiv">
<thead>
<tr>
<th>NAME</th>
<th>MARKS</th>
</tr>
</thead>
</table>
</div>
</body>
Here is my Script :
$(document).ready(function () {
$("#MydataTableDiv").DataTable({
serverSide: true,
processing: true,
ajax: {
"url": "../Home/GetData",
"dataSrc":''
},
columns: [
{ data: "NAME" },
{ data: "MARKS" }
],
});
});
And finally ,
My Home Controller :
public JsonResult GetData()
{
DataTable _dt = new DataTable();
_dt.Columns.Add("NAME");
_dt.Columns.Add("MARKS");
for (int i = 0; i < 10; i++)
{
DataRow _dr = _dt.NewRow();
_dr["NAME"] = "A_" + i;
_dr["MARKS"] = i * 10;
_dt.Rows.Add(_dr);
}
string JsonResult = JsonConvert.SerializeObject(_dt);
return Json(new {data=JsonResult }, JsonRequestBehavior.AllowGet);
}
Here is my Json string returned from controller :
[{"NAME":"A_0","MARKS":"0"},{"NAME":"A_1","MARKS":"10"},{"NAME":"A_2","MARKS":"20"},{"NAME":"A_3","MARKS":"30"},{"NAME":"A_4","MARKS":"40"},{"NAME":"A_5","MARKS":"50"},{"NAME":"A_6","MARKS":"60"},{"NAME":"A_7","MARKS":"70"},{"NAME":"A_8","MARKS":"80"},{"NAME":"A_9","MARKS":"90"}]
This code gives me a blank and empty table which contains all paging, filteration options.
please help me what is mistake in above code or is there any other way to use it for dynamic data.

From what I have observed, datatables need a JSON object rather than a string. You are returning a string which can be converted to a JSON.
Made small change to your ajax call
ajax: {
url: "http://localhost:21594/api/values",
"dataSrc": function ( json ) {
return JSON.parse(json);
}
},
The above converts your data which you are returning as string to a JSON which datatable understands

Related

Can't get Datatables row group working with ajax

I am trying to group rows in my table based on date ranges using the first column's data("Due_Date") and using the rowGroup extension from Datatables. I have searched and tried solutions from others such as using the data property('Due_Date') vs. the index of an array([0]) and removed buttons from table to prevent conflicts. I believe the versions of jQuery, Datatables, and rowGroup extensions are correct. I actually need the table to be split into three groups(red, yellow, and green) based on the table legend.(If "Due_Date" is before, current date, the current date, or 1 or 2 days after the current date, the group = red group. 3-4 days after current date = yellow group, and 5 or more days after current date = green group.) I realize I don't have the correct logic for the grouped date ranges but as of now I can't get the table to group by the data property at all. The table displays data but it seems as if the grouping is being ignored? Apologies in advance, I'm new to this and not sure where I'm going wrong. Any help is appreciated. Here is my relevant code:
//html
<table class="table table-striped" id="circuitsDueTable">
<caption style="caption-side:top">
<ul>
<li><span style="background-color:#ff3333;font-weight:bolder">RED</span> = Current
Date: Plus Two Days</li>
<li><span style="background-color:#ffff4d;font-weight:bolder">YELLOW</span> =
Pending: Three to Four Days</li>
<li><span style="background-color:#4dff4d;font-weight:bolder">GREEN</span> = Have
Time: Five or More Days</li>
</ul>
</caption>
<thead>
<tr>
<th>OCV DUE DATE</th>
<th>CIRCUIT NAME</th>
<th>OCV</th>
<th>CIRCUIT VIEW</th>
</tr>
</thead>
<tbody id="circuitsDueTableBody"></tbody>
<tfoot></tfoot>
</table>
//javascript/jquery
function getTable() {
$.ajax({
url: baseUrl + "VoltReading/GetOCVDue",
method: "POST",
dataType: "json",
success: function(data) {
if (circuitsDueTable) {
circuitsDueTable.destroy();
}
circuitsDueTable = $("#circuitsDueTable").DataTable({
data: data,
order: [
[0, "asc"]
],
rowGroup: {
dataSrc: "Due_Date"
},
columns: [{
data: 'Due_Date'
},
{
data: 'Circuit_Num'
},
{
data: 'Stage_Num'
},
{
render: function(data, type, row) {
return '<button class="btn btn-success btn-xs viewCircuitBtn"
value="' + row.Circuit_Id + '">View Circuit</button></a>';
}
}
],
//return moment(row.Due_Date).format();
});
}
});
}
getTable()
//php controller
public function GetOCVDue()
{
$ocvsDue = $this->ocv->SelectCircuitOCVDates();
echo json_encode($ocvsDue);
}
//json data
[
{"Circuit_Id":"89","Circuit_Num":"090622002C","Due_Date":"2022-09-10","Stage_Num":"1"},
{"Circuit_Id":"90","Circuit_Num":"0909221B","Due_Date":"2022-09-13","Stage_Num":"1"},
{"Circuit_Id":"89","Circuit_Num":"090622002C","Due_Date":"2022-09-14","Stage_Num":"2"},
{"Circuit_Id":"90","Circuit_Num":"0909221B","Due_Date":"2022-09-17","Stage_Num":"2"},
{"Circuit_Id":"88","Circuit_Num":"090622001B","Due_Date":"2022-09-22","Stage_Num":"3"},
{"Circuit_Id":"89","Circuit_Num":"090622002C","Due_Date":"2022-09-22","Stage_Num":"3"},
{"Circuit_Id":"90","Circuit_Num":"0909221B","Due_Date":"2022-09-25","Stage_Num":"3"}
]
Here is a basic approach - I say "basic" because it does not use a library such as Moment or the newer Luxon - but only the built-in Date object:
var today = new Date();
var redDate = today.setDate(today.getDate() + 2);
var yellowDate = today.setDate(today.getDate() + 4);
I use the above dates to calculate a status color for each record, and I add that status value to the JSON results returned from the URL.
Then, I use the rowGroup.dataSrc option to base its grouping on this newly calculated status color:
rowGroup: {
dataSrc: "status"
}
The full JavaScript is as follows:
$(document).ready(function() {
function getTable() {
$.ajax({
url: "YOUR URL GOES HERE", // I used my own test URL
method: "POST",
dataType: "json",
success: function(data) {
if (circuitsDueTable) {
//circuitsDueTable.destroy();
}
var today = new Date();
var redDate = today.setDate(today.getDate() + 2);
var yellowDate = today.setDate(today.getDate() + 4);
data.forEach(function(row) {
var date = Date.parse(row.Due_Date);
var color = 'green'; // default for 5 or more days
if ( date <= redDate ) {
color = 'red';
} else if ( date <= yellowDate ){
color = 'yellow';
}
row['status'] = color; // add color to row
});
circuitsDueTable = $("#circuitsDueTable").DataTable({
data: data,
order: [
[0, "asc"]
],
rowGroup: {
dataSrc: "status"
},
columns: [{
data: 'Due_Date'
},
{
data: 'Circuit_Num'
},
{
data: 'Stage_Num'
},
{
render: function(data, type, row) {
return '<button class="btn btn-success btn-xs viewCircuitBtn" value="' + row.Circuit_Id + '">View Circuit</button></a>';
}
}
],
//return moment(row.Due_Date).format();
});
}
});
}
getTable()
} );
And the resulting table looks like this:

Update a table in thymeleaf without page refresh

JS code:
<script type="text/javascript" th:inline="javascript">
var senderLogin = [[${senderLogin}]]
var recipientLogin = [[${recipientLogin}]]
function CheckAndGetMessage() {
$.ajax({
type : "GET",
url: '/get_updated_dialog',
data: {'senderLogin':senderLogin, 'recipientLogin':recipientLogin },
success: function (messageList) {
document.getElementById("messageList_local").value = messageList;
$('#message_table').DataTable().ajax.reload();
return;
}
});
};
setInterval(CheckAndGetMessage,1000);
Java code:
#RequestMapping(value = "/get_updated_dialog",method = RequestMethod.GET)
#ResponseBody
public List<Message> getUpdatedDialog(Authentication authentication, #RequestParam("senderLogin") String senderLogin, #RequestParam("recipientLogin") String recipientLogin, Model model){
List<Message> messageList = messageService.UpdatedDialogBetweenUsers( recipientLogin, senderLogin,authentication, model);
return messageList; }
Another Java code:
model.addAttribute("messageList", messageList);
(Attribute is adding in function which returns a view with table page)
My table:
<div id="messageList_local" th:with="messageList_local=${messageList}">
<table id="message_table" cellspacing="0" cellpadding="0">
<span th:each="message : ${messageList}"> <!-- close tags and etc -->
I tried to call this in JS:
document.getElementById("messageList_local").value = messageList;
$('#message_table').DataTable().ajax.reload();
But my table did not refresh. P.S. I checked with debugger that getUpdatedDialog returns a list with updated messages.

Web grid search function using JS and ASP.NET MVC

I am using ASP.NET MVC. I try to implement search box.
I have a input box and a button:
<div>
<input type="text" name="Search" id="Search" />
<input type="submit" value="Search" id="SearchButton" />
</div>
Then I use JS to receive user input and trigger a function:
$(document).ready(function () {
$('#SearchButton').click(function Search() {
$.ajax({
url: '#Url.Action("Search", "PCA")',
data: { AutoCribItemID: $('#Search').val() },
type: "POST",
dataType: "json",
success: function (result) {
var data = new Array();
for (var i = 0; i < result.Data.length; i++) {
data.push(result.Data[i]);
}
loadData(data);
},
error: function () {
alert("Failed! Please try again.");
}
});
});
});
Then in back end, there is a respond method:
[HttpPost, ActionName("Search")]
public JsonResult Search(string AutoCribItemID) {
List<PCAModel> allRecords = new List<PCAModel>();
allRecords = db.elements.Where(model => model.AutoCribItemID.Contains(AutoCribItemID)).ToList();
return Json(new { Data = allRecords }, JsonRequestBehavior.AllowGet);
}
You can see this C# method returns a list to frontend. Then what I want to do is to show all data after searching to user.
Here is a method to show data after searching:
function loadData(result) {
var table = $('<table id="indexTable"></table>');
var thead = $('<thead></thead>');
var trow = $('<tr class="header"></tr>');
trow.append('<th>EffectiveDate</th>');
trow.append('<th>ChangeAgree</th>');
trow.append('<th>Client</th>');
trow.append('<th>Installation</th>');
trow.append('<th>AutoCribItemID</th>');
trow.append('<th>RGBSupplier</th>');
trow.append('<th>Price</th>');
trow.append('<th>SubmitDate</th>');
trow.append('<th>WINUserName</th>');
trow.append('<th>Export</th>');
thead.append(trow);
table.append(thead);
var tbody = $('<tbody></tbody>');
for (var i = 0; i < result.length; i++) {
tbody.append(result[i]);
}
table.append(tbody);
$('#indexTableBody').html(table);
location.reload();
}
Note: 'result' parameter above is from C# function from backend.
The question is, web page shows all record in the table instead of showing searched data. I only need to show data after searching in web grid.
Without knowing the structure of your AutoCribItemID's, my guess is that because you're using .Contains in your where clause it's returning anything that matches that search term. So, for example, if you had integer IDs and someone searched for "1", it would return any ID that contains the number 1 including 1, 10, 11, 12, 13, etc. You probably want to use an equality comparison instead, i.e. model.AutoCribItemID == AutoCribItemID

Dynamic Javascript sourced data - DataTable

I am using DataTable in my application. My application is not a server hosted one. (I will render the HTML directly in my standalone application. Well, that is a different story.)
Currently I am populating DataTable like below,
$(dataTableSelector).dataTable({
"sDom": 't <f> <i> <p> > ',
"bRetrieve": true,
"aaSorting": [],
"aaData": rows,
"aoColumns": columns,
"oLanguage": {
"sSearch": "",
"sInfo": "_START_ - _END_ Total: _TOTAL_ ",
"sInfoFiltered": "(filtered from _MAX_)"
}
});
Here rows are my entire data, in array of arrays as a Javascript sourced data.
But now my problem is, if the data I am going to render with DataTable is huge, then loading takes longer time.
So I am trying to change the data table similar to server side processing(but please note that I don't have any server. It is just a local HTML page). On clicking next,it should load next only, page data.Till then, it should not load the same.
Say, I have a function in javascript
function loadData(start,end, searchString){
//Function to fetch records from a Table with start and end numbers of records.
//searchString is optional.
//rows= GetDataFromTable(start,end, searchString);
return rows;
}
So, whenever the next or previous button is clicked in the data table, or searched, my javascript method should be called and it should repopulate Datatable. Any ideas?
You can load from a local variable into Datatables on every user interaction by using the ajax option and providing your own custom function. One example of its use is on their site, called "Pipelining data to reduce Ajax calls for paging".
Below is a simple example of slicing and filtering a large array and returning a small set based on the selections made on the Datatable. Note that Datatables sends more parameters which I haven't used, but you should use them to make a proper implementation. Also, it's possible that Datatables sends request.length = -1, but I have not dealt with that either.
JavaScript
var rows;
$(document).ready(function() {
rows = getLongArrayOfData();
$("#example").dataTable({
"columns": [
{"data": "column1", "title": "Column 1"},
{"data": "column2", "title": "Column 2"}
],
"serverSide": true,
"ajax": getRows()
});
});
function getRows() {
return function ( request, drawCallback, settings ) {
var dataFiltered;
var recordsTotal = rows.length;
if (request.search.value !== "") {
dataFiltered = rows.filter(FilterStartsWith(request.search.value));
}
var recordsFiltered =
(dataFiltered === undefined) ? rows.length : dataFiltered.length;
var dataSliced =
(dataFiltered === undefined ? rows : dataFiltered)
.slice(request.start, request.start + request.length);
var returnData = {
draw: request.draw,
recordsTotal: recordsTotal,
recordsFiltered: recordsFiltered,
data: dataSliced
};
drawCallback(returnData);
};
}
function FilterStartsWith(wordToCompare) {
return function(element) {
if (typeof element == "object") {
returnValue = false;
for (var property in element) {
if (element.hasOwnProperty(property)) {
if (startsWith(element[property], wordToCompare)) {
returnValue = true;
break;
}
}
}
return returnValue;
}
return startsWith(element, wordToCompare);
}
}
function startsWith(element, wordToCompare) {
if (typeof element != "string") element = new String(element);
return element.slice(0, wordToCompare.length) == wordToCompare;
}
function getLongArrayOfData() {
var retArr = new Array();
for(i=1; i<=100000; i++) {
retArr.push({column1: i, column2: "abc" + (500+i)});
}
return retArr;
}
HTML
<table id="example">
<thead>
</thead>
<tbody>
</tbody>
</table>

Passing dynamic JSON data to create a HTML table

I have a function that receives JSON data, it can be any length and contain any number of columns and rows of data.
I have read that jqGrid would be a good jQuery plugin to use for this scenario but I cannot get it to work.
I have the following code to try and get my table to be populated:
//This code is in another section of my web page but the data is valid
//and is populated over a websocket
var ss = $.parseJSON(data);
var theGrid = jQuery("#list1")[0];
theGrid.addJSONData(ss.NewDataSet.SECURITY_GROUPS);
//alert(ss.NewDataSet.SECURITY_GROUPS[0].NAME);
$(document).ready(function() {
jQuery("#list1").jqGrid({
datatype: "local",
height: 250,
multiselect: true,
caption: "Manipulating Array Data"
});
});
<table id="list1"></table>
Maybe give DataTables a try if jqGrid isn't working for you. It's probably my favorite, and super easy to load via JSON as you've described.
Here's how to load from an AJAX source: http://datatables.net/release-datatables/examples/data_sources/ajax.html
$(document).ready(function() {
$('#example').dataTable( {
"bProcessing": true,
"sAjaxSource": '../ajax/sources/arrays.txt'
});
});
UPDATE
var columnArr = [];
var valueArr = [];
var data = ss.NewDataSet.SECURITY_GROUPS; //data is your SECURITY_GROUPS object
//Strip the titles off your first array item only since they are all the same.
$.each(data[0], function(key, value) {
columnArr.push({"sTitle" : key});
});
$.each(data, function(key, value) {
var innerArr = [];
$.each(value, function(innerKey, innerValue) {
innerArr.push(innerValue);
});
valueArr.push(innerArr);
});
$('#example').dataTable( {
"aaData": valueArr,
"aoColumns": columnArr
});

Categories

Resources