I have an ajax backed dynatable. At the moment, it works perfectly for tables with known headers prior.
Example:
var tableHeaders = '';
// Generate table headers from some list
$scope.Model.computed.selection_list.map(
function(selection){
column_name = selection.table + "." + selection.column;
tableHeaders += "<th>" + column_name + "</th>";
});
//wipe div hosting the dynatable and reinitialise a table
var table_div = $('#TableDiv');
table_div.empty();
table_div.append('<table id="previewTable" class="table table-condensed table-responsive table-striped table-hover"><thead><tr>' + tableHeaders + '</tr></thead></table>');
var preview_table = $('#previewTable');
console.log("Table wiped");
//initialise the dynatable
preview_table.dynatable({
features: {
perPageSelect: true,
search: false
},
table: {
defaultColumnIdStyle: 'underscore',
headRowSelector:'thead tr',
headRowClass: ''
},
dataset: {
ajax: true,
ajaxUrl: data_url,
ajaxOnLoad: false,
ajaxMethod: 'POST',
records: []
}
});
However, I'd like to have the table headers generated after fetching the records but prior to filling out the rows.
Is this possible?
// Changing via an ajax success event hook doesn't work.
// The table headers change but the records don't bind to the correct column leaving every row as null
preview_table.bind('dynatable:ajax:success', function(e, response){
console.log("Ajax response: " + response) ;
tableHeaders = '';
first_record = response.records[0];
Object.keys(first_record).map(function(column_name){
tableHeaders += "<th>" + column_name + "</th>";
}
)
preview_table.html('<thead><tr>' + tableHeaders + '</tr></thead>')
console.log("headers: " + tableHeaders);
})
I had exactly the same problem and after hours of struggling I came up with this solution:
First, your initial TABLE should look like this:
<table id="my-table">
<thead>
<tr><th></th></tr>
</thead>
<tbody>
</tbody>
</table>
We need the empty TH to prevent the plugin from throwing an error (Couldn't find any columns headers in...), it will be removed later.
Then we use the dynatable:ajax:success to edit the columns as follow:
$("#my-table").one('dynatable:ajax:success', function(e, response){
//Get dynatable
var dynatable = $(this).data('dynatable');
//Remove the empty column
dynatable.domColumns.remove(0);
//Add new columns
var pos = 0;
for(var column in response.records[0]) {
dynatable.domColumns.add($('<th>'+column+'</th>'), pos++);
}
});
Finally, you can initiate the plugin:
$("#my-table").dynatable({
features: {
perPageSelect: true,
search: false
},
table: {
defaultColumnIdStyle: 'underscore',
headRowClass: ''
},
dataset: {
ajax: true,
ajaxUrl: data_url,
ajaxOnLoad: false,
records: []
}
});
Check the following demo, please note that the snippet is not fully functional it throws (SecurityError). Here is a fully working jsfiddle:
var data_url = "https://gist.githubusercontent.com/iRbouh/47a9fb7e5f6a79e0f4b0e7e8a837a825/raw/6adbba47bfbf9453c50f9710f77c71e69f683139/sample-data.json";
var preview_table = $('#my-table');
preview_table.one('dynatable:ajax:success', function(e, response){
//Get dynatable
var dynatable = $(this).data('dynatable');
//Remove init column
dynatable.domColumns.remove(0);
//Add new columns
var pos = 0;
for(var column in response.records[0]) {
dynatable.domColumns.add($('<th>'+column+'</th>'), pos++);
}
});
preview_table.dynatable({
features: {
perPageSelect: true,
search: false
},
table: {
defaultColumnIdStyle: 'underscore',
headRowClass: ''
},
dataset: {
ajax: true,
ajaxUrl: data_url,
ajaxOnLoad: false,
records: []
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<link href="https://cdn.rawgit.com/alfajango/jquery-dynatable/master/jquery.dynatable.css" rel="stylesheet"/>
<script src="https://cdn.rawgit.com/alfajango/jquery-dynatable/master/jquery.dynatable.js"></script>
<table id="my-table">
<thead>
<tr><th></th></tr>
</thead>
<tbody>
</tbody>
</table>
Related
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:
I have the following datatable. Its got a list of columns. Last column is a checkbox.
I want to get list of all rows which has the checkbox ticked? is it possible to get all datatable rows with the checkbox checked? my datatable is like below
$.fn.dataTable.moment('DD.MM.YYYY');
$('#bankReconDataListing tbody').off('click');
RECON_DATATABLE = $('#bankReconDataListing').DataTable({
"language": __DT,
"select": true,
"order": [
[1, "desc"]
],
"searchable": true,
"destroy": true,
"sAjaxSource": '/bankReconciliationGetData?coa=' + coa + '&toDate=' + toDate + '&fromDate=' + fromDate,
"sAjaxDataProp": "",
"bLengthChange": false,
"pageLength": 20,
"aoColumns": [{ //document date : 0
"mDataProp": null,
{ //Document type //5
//balance
"mDataProp": null,
render: function(data, type, row) {
return data.doctype;
}
},
render: function(data, type, row) {
return "<input type='checkbox' name='" + checkBoxName + "' data-tableinput='checkbox' " +
"id='checkBox" + reconJrnlId + "' value='" + reconJrnlId + "' checked='checked' />";
}
}],
"columnDefs": [],
"initComplete": function() {}
});
Give a class name to your checkbox column, say checkboxclass.
Then,
$('.checkboxclass:checked',table.fnGetNodes()).each(function(){
//what you want to do
}
You could attach an event handler to the checkboxes in the table. Whenever a checkbox is clicked, that row gets added to an array. If it's unchecked, you remove it from the array.
This is untested but something like this should work:
let arr = [];
$("#tableDiv tbody").on("click", "input[type='checkbox']", function(e) {
let row = $(this).closest('tr');
// Get row data
let data = table.row(row).data();
if (this.checked) {
// Add to array
arr.push(data);
} else {
arr.splice(arr.indexOf(data), 1);
}
});
#tableDiv is just the table's container. You could use whatever other selector is appropriate depending on your application.
Controller: In my controller I am getting data from sap b1if service.
I want to get json data from controller to view.
[HttpGet]
[AllowAnonymous]
public ActionResult Index()
{
ServiceReference1.ipostep_vP001sap0003in_WCSX_comsapb1ivplatformruntime_INB_WS_CALL_SYNC_XPT_INB_WS_CALL_SYNC_XPTipo_procClient B1ifSerPro
= new ServiceReference1.ipostep_vP001sap0003in_WCSX_comsapb1ivplatformruntime_INB_WS_CALL_SYNC_XPT_INB_WS_CALL_SYNC_XPTipo_procClient();
ServiceReference1.SelectQueryType request = new ServiceReference1.SelectQueryType();
request.Query = "Select TOP 1000 r.U_JobNr as U_JobNr,r.Code as Code,r.U_HlSQty as U_HlSQty,r.U_JobTp as U_JobTp,r.U_RDate as U_RDate,r.U_RTime as U_RTime,r.U_ASDate as U_ASDate,r.U_ASTime as U_ASTime,r.U_AEDate as U_AEDate,r.U_Lorry as U_Lorry,r.U_Driver as U_Driver,e.U_ZpCd as U_ZpCd,e.U_City as U_City,e.U_Phone1 as U_Phone1,e.U_SiteTl as U_SiteTl,r.U_ConNum as U_ConNum,r.U_CstWgt as U_CstWgt,r.U_Price as U_Price,r.U_TCTotal as U_TCTotal,r.U_SLicCh as U_SLicCh,r.U_PayMeth as U_PayMeth,r.U_JCost as U_JCost,r.U_RTimeT as U_RTimeT,r.U_SLicNr as U_SLicNr,r.U_VehTyp as U_VehTyp,r.U_IDHRTCD as U_IDHRTCD,r.U_IDHSEQ as U_IDHSEQ,r.U_CustRef as U_CustRef,r.U_Rebate as U_Rebate,r.U_WROrd as U_WROrd,r.U_WRRow as U_WRRow,e.U_Status as U_Status,r.U_RowSta as U_RowSta,r.U_LnkPBI as U_LnkPBI,r.U_AddCost as U_AddCost,r.U_AddCharge as U_AddCharge,r.U_ValDed as U_ValDed,e.U_PCardCd as U_PCardCd,e.U_SCardCd as U_SCardCd,r.U_OrdTot as U_OrdTot,r.U_PCTotal as U_PCTotal FROM[#IDH_JOBSHD] r ,[OCRD] bp ,[#IDH_JOBENTR] e WHERE r.U_JobNr = e.Code AND (r.U_CustCd = bp.CardCode Or (r.U_CustCd = '' AND r.U_ProCd = bp.CardCode)) ";
ServiceReference1.SelectQueryResponseType Response = B1ifSerPro.ZSelectQuery(request);
Response.SelectQueryResult.ToList();
//ServiceReference1.SelectQueryResponseTypeRow row = (ServiceReference1.SelectQueryResponseTypeRow)Response.SelectQueryResult.GetValue(1);
return Json(Response.SelectQueryResult.ToList(), JsonRequestBehavior.AllowGet);
//return Json("",JsonRequestBehavior.AllowGet);
}
My view as is follow:
JS is not working in my case. I want to get data as json form Controller and render in HTML using Bootstrap or simple will work.
#Model IEnumerable<BusinessLayer.OSM>
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
var osmlist;
$.ajax({
url:'#Url.Action("Index", "OSM")' , // '/OSM/Index/',
type: 'Get',
Data:{},
cache: false,
async: false,
DataType: 'Json',
success: function (data) {
osmlist = data;
var row = '';
$.each(data, function (i, item) {
row += "<tr>"
row += "<td>" + item.Code + "<td>"
row += "<td>" + item.U_JobNr + "<td>"
row += "<tr>"
$("#listRows tbody").html(row);
})
},
error: function (error) {
alert("Error : " + error.responseText);
}
});
});
</script>
<h2>Get OSM Rows</h2>
<table id="listRows" style="background-color: lightcoral">
#*<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Description</th>
<th>Category</th>
<th>Price</th>
</tr>
</thead>*#
<tbody></tbody>
</table>
<hr />
Is it the typo error while putting the question here or you have forgotten to correctly close the tr and td tags in the javascript.
I have to grab "data" items and loop and inject to specific table like bellow. How is that possible from javascript/jquery? I have attached picture of my Json response of ajax call check to get idea about Json i need to be processed. Any question welcome. Thanks in advance....
Table:
<table>
<tr>
<th>Ebay Image</th>
<th>Item Title</th>
</tr>
<tr need to loop this tr as per json objects>
<td><img src="link defined from json value"></td>
<td>title from json value</td>
</tr>
</table>
Jquery Ajax call:
$.post("/CategoryResearch/Search", { OperationName: _operationname, calltype: _calltype, page: _page, keywords: _keywords, type: _type, location: _location })
.done(function (data) {
if (data != null) {
$("#normalState").fadeOut();
//Loop and inject html table data to specific table
console.log(data);
}
});
Json Picture from console.log(data) -
Table:
(dont forget to add tableId as id and remove de tr tag of sample data)
<table id="tableId">
<tr>
<th>Ebay Image</th>
<th>Item Title</th>
</tr>
</table>
Jquery Ajax call:
(on edit i'm placing the entire loop directly in ajax call for simplify to you)
$.post("/CategoryResearch/Search", { OperationName: _operationname, calltype: _calltype, page: _page, keywords: _keywords, type: _type, location: _location })
.done(function (data) {
if (data != null) {
$("#normalState").fadeOut();
//Loop and inject html table data to specific table
if ($("#tableId tbody").length === 0) {
$("#tableId").append("<tbody></tbody>");
}
var jsonDataObject = JSON.parse(data);
$.each(jsonDataObject, function(i, item){
$("#tableId tbody").append(
"<tr>" +
"<td><img src=\"" + item.EbayImageUrl + "\"></td>"
"<td>" + item.EbayTitle + "</td>" +
"</tr>"
);
});
console.log(data);
}
});
You can loop through the array that you get as a response with a for...
$.ajax({
type: 'POST',
url: '/CategoryResearch/Search',
data: { OperationName: _operationname, calltype: _calltype, page: _page, keywords: _keywords, type: _type, location: _location },
dataType: 'json',
success: function(data) {
if (data != null) {
$("#normalState").fadeOut();
var rows = [];
for (var i=0, l=data.length; i<l; i++)
rows.push('<tr><td>'+data[i].EbayImageUrl+'</td><td>'+data[i].EbayTitle+'</td></tr>');
$('table tbody').html(rows.join(''));
}
}
});
have you tried using append?
<table id="appendedTable">
<tr>
<th>
header 1
</th>
</tr>
</table>
<script>
$(document).ready(function(){
$('#appendedTable').append('<tr><td>concatenate here your json value</td></tr>');
});
</script>
Parse the response
(I think I'm wrong about this part. I haven't used jQuery in years. I think it parses it for you, but, just in case...)
The response from the server is a string. Parse it with JSON.parse.
let myData = JSON.parse(data);
Based on the supplied screenshot, it looks like you get an array of objects.
Iterate the array
Loop over each element of the array with Array.forEach.
Add Rows to your table
Get a reference to your table with document.getElementsByTagName or document.getElementById, et al.
Add rows and cells with HTMLTableElement.insertRow() and HTMLTableRowElement.insertCell().
Example
const myData = [{
EbayImageUrl: 'http://via.placeholder.com/100x50/ff0000/ffffff',
EbayTitle: 'example title'
}, {
EbayImageUrl: 'http://via.placeholder.com/100x50/00ff00/ffffff',
EbayTitle: 'example title'
}, {
EbayImageUrl: 'http://via.placeholder.com/100x50/0000ff/ffffff',
EbayTitle: 'example title'
}];
const table = document.getElementsByTagName('table')[0];
myData.forEach(item => {
let row = table.insertRow();
row.insertCell().innerHTML = `<img src="${item.EbayImageUrl}">`;
row.insertCell().innerHTML = item.EbayTitle;
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css" rel="stylesheet" />
<table>
<tr>
<th>Ebay Image</th>
<th>Item Title</th>
</tr>
</table>
I am developing a mobile app using Phonegap and jQuery Mobile. Basically for the first time when the app loads the data which gets populated using AJAX comes fine but It doesn't update.
Example: If there are 5 rows of data coming from the database and with some users action 1 more row has been added in the database but it still displays 5 rows. Currently it updates only if I exit app fully.
Also to solve this problem I have tried the following:
tbody.append(tableCells).load();
tbody.append(tableCells).trigger('create');
tbody.append(tableCells).trigger('refresh');
Any solution/idea how can I update it live or something without a user exits the app completely? Please see the below code.
Code:
HTML:
<table id="myPendingChallenges-table" width="100%">
<thead>
<tr>
<th>Game Type</th>
<th>Team Name</th>
<th>Initiator Name</th>
</tr>
</thead>
<tbody></tbody>
</table>
to append rows inside the
JS: tbody.append(tableCells);
AJAX:
var currentUser = window.localStorage.getItem("currentUser");
user = JSON.parse(currentUser);
var username = user.username; //User name
//alert (username+', '+t_name+', '+formAction);
$.ajax({
type: 'POST',
url: 'http://www.example.com/webservice/index.php',
data: {username: username},
dataType : 'json',
success: function(data){
var json = JSON.stringify(data);
window.localStorage.setItem("teamChallenges", json);
challengePopulate();
},
error: function(){
alert('error!');
}
});
return false;
function challengePopulate()
{
var json = window.localStorage.getItem("teamChallenges");
var data = null;
if(!json)
data = JSON.stringify(window.teamChallenges);
var data = JSON.parse(json);
if(!data)
return;
var fields = ["game_type", "t_name", "ini_name"];
populatePCTable("#myPendingChallenges-table", fields, data);
}//end challengePopulate
function populatePCDTable(tableId, fields, data)
{
var tbody = $(tableId + " tbody");
var row = null;
for(var i in data) {
row = data[i];
if(!row)
continue;
var tableCells = "";
var fieldName = "";
for(var j in fields){
fieldName = fields[j];
teamName = row[fields[1]];
gameParam = row[fields[3]];
if(row[fieldName] == 'weighin'){
game_type = 'weighin';
row[fieldName] = '<img src="images/weightGame.png" width="100%" />';
}else if (row[fieldName] == 'activity'){
game_type = 'activity';
row[fieldName] = '<img src="images/activityGame.png" width="100%" />';
}
tableCells += "<td onClick=\"setPendingChallTitle('"+teamName+"');pendingchallengeDetails('"+teamName+"');\"><a href='#pendingChallengesDetailsPage'>"+row[fieldName]+"</a></td>";
}
tbody.append("<tr>" + tableCells + "<td onClick=\"ignorePendingChallenge(this,'"+teamName+"');\"><a href=''><img src='images/close_button.png' title='Ignore Challenge' /></a></td></tr>");
}
}//end function populatePCDTable