Pagination from Ajax response - json

I'm trying to fetch data from JSON response in a datatable and it works fine. My next step is to add a pagination for all rows. Since I'm using Laravel I've earlier used Laravels built-in system:
{{ $var->links() }}
Now since I'm receiving the response from a POST request to filter out dates, I'm struggling with filtering amount of rows per page. I've tried to Google around without and couln't find a good answer.
I'm a beginner in JavaScript and some support would really help!
This is my code ATM:
$("#date").ready(function() {
$("#date").on('change', function() {
var date = $("#date").find(':selected').val();
var token = $("input[name='_token']").val();
$(document).on('click', '.pagination a', function(event) {
event.preventDefault();
var page = $(this).attr('href').split('page=')[1];
fetch_data(page);
});
$.ajax({
url: "{{ route('mydata') }}",
type: "POST",
data: {
'date': date,
'_token': token
},
dataType: "json",
success: function(data) {
console.log(data);
function status() {
if (data[i].status = 1) {
return '<td class="px-4 py-4"><span class="bg-yellow-500 font-semibold text-white p-2 rounded">Active</span></td>';
}
if (data[i].status = 2) {
return '<td class="px-4 py-4"><span class="bg-blue-500 font-semibold text-white p-2 rounded">Closed</td>';
}
}
function formatDate(date) {
var date = new Date(date);
var yyyy = date.getFullYear().toString();
var mm = (date.getMonth() + 1)
.toString(); // getMonth() is zero-based
var dd = date.getDate().toString();
var h = date.getHours().toString();
var h = ("0" + h).slice(-2);
var m = date.getMinutes().toString();
return yyyy + '-' + (mm[1] ? mm : "0" + mm[0]) + '-' + (dd[1] ? dd :
"0" + dd[0]) + ' ' + h + ':' + m;
}
function remaining_days(start, end) {
var start = new Date(start);
var end = new Date(end);
const _MS_PER_DAY = 1000 * 60 * 60 * 24;
const s = Date.UTC(start.getFullYear(), start.getMonth(), start
.getDate());
const e = Date.UTC(end.getFullYear(), end.getMonth(), end.getDate());
if (end - start < 0) {
return '<span class="text-red-800 font-bold">Late</span>';
} else {
return Math.floor((e - s) / _MS_PER_DAY) + ' Days left';
}
}
var output = '';
for (var i = 0; i < data.length; i++) {
output += '<tr class="bg-gray-100 text-center">';
output += '<td class="px-4 py-4">New</td>';
output += '<td class="px-4 py-4">' + formatDate(data[i].updated_at) +
'</td>';
output += '<td class="px-4 py-4">' + data[i].title + '</td>';
output += '<td class="px-4 py-4">' + data[i].get_admin.first_name +
' ' + data[i]
.get_admin.last_name + '</td>';
output += '<td class="px-4 py-4">#' + data[i].id + '</td>';
output += '<td class="px-4 py-4">' + remaining_days(data[i].created_at,
data[i].end_date) +
'</td>';
output += status();
output += '</tr>';
}
$('#myticketstable').html(output);
},
error: function(xhr) {
if (xhr.status == 422) {
const errors = JSON.parse(xhr.responseText);
console.log(errors);
$.each(xhr.responseJSON.errors, function(i, error) {
console.log('something went wrong');
});
}
}
});
}).trigger('change');});
Best regards

Related

How can I add a line break in an email body after each row

I've created this script to send the none empty rows of a sheet as an email. So far it sends the email, but it places all the found rows in a single continuous line in the email body.
I've tried placing a line break <br/> in various places in the HTML part of the script but no luck so far.
function sendSheetDataViaEmail() {
var SSID = SpreadsheetApp.openById('1dfgdfgdf').getSheetByName('sheet1');
var lastRow = SSID.getLastRow();
var cell = SSID.getRange(12, 1,lastRow-3,9).getDisplayValues();
var data2D = cell.filter(function(item) {//filter by user Id and by spliting month and year
return item[0] != "" // if not empty
});
Array.prototype.transpose = function() { var a = this; return Object.keys(a[0]).map(function (c) {
return a.map(function (r) { return r[c]; }); }); }
//transpose the array, because getValues() returns an array of rows
data2D = data2D.transpose();
// data2D.splice(1,1); // removes the second column... count starts at 0
//if now you need an array or rows again, just transpose again
data2D = data2D.transpose();
var L = data2D.length;
var html = "";
html = "<table id='loadListOfFaturasDeHojeTable' class='order-table table dark3Dtable'> <thead><tr>
<th '>F. ID 🔃</th><th>Trans ID</th> <th>C. ID</th> <th >C. NOME</th> <th >CODDIGO</th> <th >NU DE
SERIE</th> <th >VALOR</th><th >DATA</th> </tr> </thead> <tbody>";
for (var i=0;i<L;i++) {
var thisRow = data2D[i];
var rowHTML = "";
rowHTML = "<tr>";
var rowHTML0 = '<td style="color: red;">'+ thisRow[0] + '</td>'
var rowHTML1 = '<td >'+ thisRow[1] + '</td>'
var rowHTML2 = '<td >'+ thisRow[2] + '</td>'
var rowHTML3 = '<td >'+ thisRow[3] + '</td>'
var rowHTML4 = '<td >'+ thisRow[4] + '</td>'
var rowHTML5 = '<td >'+ thisRow[5] + '</td>'
var rowHTML6 = '<td >'+ thisRow[6] + '</td>'
var rowHTML7 = '<td >'+ thisRow[7] + '</td>'
var rowHTML8 = '<td ">'+ thisRow[8] + '</td>'
rowHTML = rowHTML0 +rowHTML1+rowHTML3 + rowHTML4 + rowHTML5 + rowHTML6 + rowHTML7 + rowHTML8 +
"</tr><br/>";
html = html + rowHTML ;
}
// Logger.log('html: ' + html)
html = html + "</table>";
var settings = {
mailTo: SSID.getRange('J3')//email address
.getValue(),
subject: SSID.getRange('J4')
.getValue(),
body: html,
}
MailApp.sendEmail(settings.mailTo, settings.subject,"" , {
htmlBody: settings.body,
});
}
Try it this way:
function sendSheetDataViaEmail() {
var ss=SpreadsheetApp.openById('ssid');
var sh=ss.getSheetByName('sheet1');
var lastRow=sh.getLastRow();
var vA=sh.getRange(12, 1,sh.getLastRow()-11,9).getDisplayValues().filter(function(item){return item[0]});
var html="";
html='<table id="loadListOfFaturasDeHojeTable" class="order-table table dark3Dtable"><tr><th>F.ID 🔃</th><th>TransID</th><th>C.ID</th><th>C.NOME</th><th>CODDIGO</th><th>NUDESERIE</th><th>VALOR</th><th>DATA</th></tr>';
for(var i=0;i<vA.length;i++) {
html+='<tr><td style="color:red;">'+ thisRow[0] + '</td><td >'+ thisRow[1] + '</td><td >'+ thisRow[2] + '</td><td >'+ thisRow[3] + '</td>';
html+='<td >'+ thisRow[4] + '</td><td >'+ thisRow[5] + '</td><td >'+ thisRow[6] + '</td><td >'+ thisRow[7] + '</td>'<td ">'+ thisRow[8] + '</td>';
}
MailApp.sendEmail(sh.getRange('J3').getValue(),sh.getRange('J4').getValue() ,"",{htmlBody:html});
}

Convert JSON data to table

I am trying to create table from my JSON data which looks like this:
It works for a specific JSON data:
var items = [
{"Name":"A","Type":2,"Result":"0"},
{"Name":"A","Type":1,"Result":"1"},
{"Name":"B","Type":2,"Result":"1"},
{"Name":"B","Type":1,"Result":"0"},
]
But, it doesn't create table correctly if the columns ("Type") is random
var items = [
{"Name":"A","Type":5,"Result":"1"}
{"Name":"A","Type":2,"Result":"0"},
{"Name":"A","Type":1,"Result":"1"},
{"Name":"B","Type":3,"Result":"1"},
{"Name":"B","Type":2,"Result":"1"},
{"Name":"B","Type":1,"Result":"0"},
]
Can someone tell me what's the issue with my code?
I want to create table for dynamic JSON data which may not have cell values for all the columns. With this code, I don't see entry in column 5 for A as 1.
function get_prop(obj, prop) {
return prop.split('.').reduce((o,k) => obj[k], obj);
}
function coll2tbl(json, row_header, col_header, cell) {
var table = {};
var row_headers = [];
var cols = {};
json.map(function(a) {
var h = get_prop(a, row_header);
if (h in table === false) {
table[h] = {};
row_headers.push(h);
}
var c = get_prop(a, col_header);
cols[c] = null;
table[h][c] = get_prop(a, cell);
});
var cells = [];
for (var row in table) {
cells.push(Object.values(table[row]));
}
console.log('row_headers' + row_headers);
console.log('Object.keys(cols)' + Object.keys(cols));
console.log('cells' + cells);
var headerRow = '<th>' + capitalizeFirstLetter('TestName') + '</th>';
var colKeys = Object.keys(cols);
colKeys.map(function(col) {
headerRow += '<th>' + capitalizeFirstLetter(col) + '</th>';
});
var bodyRows = '';
for (var i in cells) {
bodyRows += '<tr>';
bodyRows += '<td>' + row_headers[i] + '</td>';
for (var j in cells[i]) {
console.log('Processing row: ' + row_headers[i] + ' result: ' + cells[i][j] + ' i=' + i + ' j=' + j);
bodyRows += '<td>';
if (cells[i][j] === "1") {
bodyRows += '<font color="green">' + cells[i][j] + '</font>';
}
else if (cells[i][j] === "0") {
bodyRows += '<font color="red">' + cells[i][j] + '</font>';
}
else if (cells[i][j] === "-1") {
bodyRows += '<font color="orange">' + cells[i][j] + '</font>';
}
else {
bodyRows += "-";
}
bodyRows += '</td>';
}
bodyRows += '</tr>';
}
//return { row_headers, col_headers: Object.keys(cols), cells };
return ('<table> <thead><tr>' + headerRow + '</tr></thead><tbody>' + bodyRows + '</tbody></table>');
}
function capitalizeFirstLetter(string) {return
string.charAt(0).toUpperCase() + string.slice(1);
}
coll2tbl(items, 'Name', 'Type', 'Result');
My table should like like this:
Name 1 2 3 4 5
A 1 1 - - 1
B 1 1 1 - -
The answer https://stackoverflow.com/a/52199138/10320683 is of course correct, but if you need or want to stick to your specific code, you can put this below your json.map (which should by the way use forEach and not map, since you do not use the returned array anyways)
for (var col in cols) {
for (row in table) {
if (!table[row].hasOwnProperty(col)) {
table[row][col] = "-";
}
}
}
The reason why your code did not work is that by iterating over the rows, you do not get all the possible type properties, which becomes clear if you inspect your table variable: { a: {1: "1", 2: "0", 5: "1"}, b: {...}} (this is missing the 3 type property), so by calling Object.values(table[row]) later on, you get the following array for your cells: ["1", "0", "1"], but you do have 4 columns, so the "Type 5" result (1) gets shifted one column to the left.
Also, you need to be careful because your code is relying on the sorting that Object.values() produces, which means that if you want to change the order of your columns, your code would not work.

Using JSON response in CFIF

Is it possible to use response.DATA[i][j] in a CFIF statement.
chkUsernameUnique = function(theUsername){
$.ajax({
type: "GET",
url: "/book.cfc",
data: {method: "testFunction", datum: $('#date').val(), returnFormat: "JSON"},
dataType: "json",
success: function(response) {
var str = '<table><tr>';
var i;
var j;
//loop over each column name for headers
for (i = 0; i < response.COLUMNS.length; i++) {
str += '<th>' + response.COLUMNS[i] + '</th>';
}
str += '</tr>';
//loop over each row
for (i = 0; i < response.DATA.length; i++) {
str += '<tr>';
//loop over each column
for (j = 0; j < response.DATA[i].length; j++) {
str += '<td>' + response.DATA[i][j] + '</td>';
}
str += '</tr>';
}
str += '</table>';
$('#debugDiv').html(str);
},
error: function(ErrorMsg) {
console.log('Error');
}
});
}
What I want to do is something like:
<cfif response.DATA[i][j] is 3> str += '<td>test</td>';</cfif>
This returns the following error message: variable [RESPONSE] doesn't exists.
The response variable is the server response for your AJAX request and you are working with it on clientside. Thus you are still in the realm of JavaScript:
if (response.DATA[i][j] == 3) { str += '<td>test</td>'; }
ColdFusion (i.e. <cfif>) is executed on serverside, thus cannot be used to evaluate data during runtime (after the browser requested an URI).

Sort JSON data by Date/Time value

Hope someone could help with this small task. I have an array of text blocks that have a DateTime value assigned to them. I would like to publish those text blocks sorted by DateTime so that the latest updated item is always on top.
Here is the script:
function jsonCallBack(data) {
var strRows = "";
$.each(data.News, function(i, item) {
var htmlNewsBody = item["htmlNewsBody"];
var maxLength = 120
var trimmedString = htmlNewsBody.substr(0, maxLength);
trimmedString = trimmedString.substr( 0, Math.min( trimmedString.length,
trimmedString.lastIndexOf(" ") ) );
strRows += "<div id='nrNewsItem-" + i + "'>";
strRows += "<h3>" + item["txtTitle"] + "</h3>";
strRows += "<p>" + item["dtDateTime"] + "</p>";
strRows += "<p>" + trimmedString + "...</p>";
strRows += "</div>"
});
$("#printHere").html(strRows);
};
Also have a working jsFiddle with JSON data.
You can add a custom compare method:
function compare(a,b) {
if (a.dtDateTime < b.dtDateTime) {
return 1;
}
if (a.dtDateTime > b.dtDateTime) {
return -1;
}
return 0;
}
Then in your function:
function jsonCallBack(data) {
data.News.sort(compare);
....

jquery div undefined with .html()

I am using Jquery ajax.
I have made ajax call to fetch data and concact the html string and attached to id of div.
$("#divMenuList").html(JsMenuListHtml);
alert($("#divMenuList").html());
But with alert is showing undefined. I have it using listing if i am page change it showing first time with html string but if i will delete second page record and re-call that function it will showing undefined.
Here is the whole function:
function performlisting(data, JsCurrPage) {
var JsMenuTitle = '';
var JsOrderNumber = '';
var JsMenuId = '';
var JsMenuListHtml = '';
var JsCounter = 0;
var JsAlternateRow = '';
var JsIsActive = "false";
var JsIsActiveClass = "";
var JsIsActiveTitle = "";
if (data.Data.length > 0) {
for (i = 0; i < data.Data.length ; i++) {
JsCounter++;
if (JsCounter % 2 == 0) {
JsAlternateRow = "alternate-row";
}
else {
JsAlternateRow = '';
}
//set true/false for update status
if (data.Data[i]['IsActive'] == true) {
JsIsActive = "false";
JsIsActiveClass = "icon-3 info-tooltip";
JsIsActiveTitle = "Published";
}
else if (data.Data[i]['IsActive'] == false) {
JsIsActive = "true";
JsIsActiveClass = "icon-4 info-tooltip";
JsIsActiveTitle = "UnPublished";
}
else {
JsIsActive = "false";
JsIsActiveClass = "icon-4 info-tooltip";
JsIsActiveTitle = "UnPublished";
}
JsMenuTitle = data.Data[i]['MenuTitle'];
JsOrderNumber = data.Data[i]['OrderNumber'];
JsMenuId = data.Data[i]['MenuId'];
JsMenuListHtml = JsMenuListHtml +
'<tr class= ' + JsAlternateRow + '>' +
'<td style="width:3.4%;"><input type="checkbox" value=' + JsMenuId + ' /></td><td style="width:38.8%;">' + JsMenuTitle + '</td>' +
'<td style="width:39%;">' +
'<a title="Up-Rank" href="javascript:void(0);" onclick="return performUpMenu(\'' + JsOrderNumber + '\', \'' + JsMenuId + '\')"><img src=' + JsUpImage + '></a>' +
'<a title="Down-Rank" href="javascript:void(0);" onclick="return performDownMenu(\'' + JsOrderNumber + '\', \'' + JsMenuId + '\')"><img src=' + JsDownImage + '></a>' +
'' + JsOrderNumber + '</td>' +
'<td class="options-width">' +
'' +
'<a href="javascript:void(0);" onclick="return performstatusmenu(\'' + JsIsActive + '\', \'' + JsMenuId + '\');" title= ' + JsIsActiveTitle + ' class=' + JsIsActiveClass + '></a>' +
'</td>' +
'</tr>';
}
$("#divMenuList").html("");
$("#divMenuList").html(JsMenuListHtml);
alert($("#divMenuList").html());
//hide num of raws dropdown
if (parseInt(JsTotalRecs) > parseInt(JsPageSize)) {
alert("Called1");
SetPaging(JsTotalRecs, parseInt(JsCurrPage));
}
else {
alert("Called");
$("#pager").html('');
}
$("#CurrPage").val(JsCurrPage);
SetAllCheckboxes();
}
else {
if ($("#CurrPage").val() > 1) {
//Error Message Pager
$("#product-table").html("");
$("#divSuccessMessage").html("");
alert(parseInt($("#CurrPage").val()));
GetListing(parseInt($("#CurrPage").val() - 1), parseInt(JsPageSize));
}
else {
$("#product-table").html("");
$("#divErrMessage").html("");
$("#divSuccessMessage").html("");
}
}
}
Regards