Make a selectable html table with objects as values - javascript

I am been trying to create a html table that is populated by objects.
The table was supposed to be selectable by row (via hover), when the row was hovered over a function ran.
The table headers are in an array:
var topTitles = ["Type","Origin","Destination","T","A","G"];
all the data are sitting inside arrays,
var Type = [];
var Origin = [];
var Destination = [];
var T = [];
var A = [];
var G = [];
I tried to modify an example piece of code, but it was very difficult to conceptualize it and place it into a programatic solution. What is an easy way to map such data directly into a interactive table.
function createTable() {
var table = document.getElementById('matrix');
var tr = addRow(table);
for (var j = 0; j < 6; j++) {
var td = addElement(tr);
td.setAttribute("class", "headers");
td.appendChild(document.createTextNode(topTitles[j]));
}
for (var i = 0; i < origins.length; i++) {
var tr = addRow(table);
var td = addElement(tr);
td.setAttribute("class", "origin");
td.appendChild(document.createTextNode(mode[i]));
for (var j = 0; j < topTitles.length; j++) {
var td = addElement(tr, 'element-' + i + '-' + j);
td.onmouseover = getRouteFunction(i,j);
td.onclick = getRouteFunction(i,j);
}
}
}
function populateTable(rows) {
for (var i = 0; i < rows.length; i++) {
for (var j = 0; j < rows[i].elements.length; j++) {
var distance = rows[i].elements[j].distance.text;
var duration = rows[i].elements[j].duration.text;
var td = document.getElementById('element-' + i + '-' + j);
td.innerHTML = origins[i] + "<br/>" + destinations[j];
}
}
}
if (highlightedCell) {
highlightedCell.style.backgroundColor="#ffffff";
}
highlightedCell = document.getElementById('element-' + i + '-' + j);
highlightedCell.style.backgroundColor="#e0ffff";
showValues();
}

This is probably the easiest way I could think of building the table without changing your data structure and make it very clear where all the data is coming from. It is defiantly not the best code, but it should work for your situation.
CodePen
var topTitles = ["Type","Origin","Destination","T","A","G"];
var Type = ["Type1", "type2", "type3"];
var Origin = ["Origin1", "origin2", "origin3"];
var Destination = ["Destination1", "Destination2", "dest3"];
var T = ["t1", "t2","T3"];
var A = ["steaksauce", "a2", "a3"];
var G = ["G1", "G2", "G3"];
var appendString = [];
for(var i =0; i < topTitles.length; i++){
if(!i){
appendString.push("<tr><td>" + topTitles[i] + "</td>");
}
else if(i === topTitles.length -1){
appendString.push("<td>" + topTitles[i] + "</td></tr>");
}
else{
appendString.push("<td>" + topTitles[i] + "</td>");
}
}
for(var i =0; i < Type.length; i++){
appendString.push("<tr><td>" + Type[i] + "</td><td>" + Origin[i] + "</td><td>" + Destination[i] + "</td><td>" + T[i] + "</td><td>" + A[i] + "</td><td>" + G[i] + "</td></tr>");
}
var table = document.getElementById('table');
table.innerHTML = appendString.join('');

Related

GAS/ Javascript giving wrong figures when summing up numbers

My Javascript/GAS code uses the user ID to call for time entries via API for a specific date range (1 week) and sum up the hours. These time entries are saved in an array and then summed up. The first 50 additions on the log are correct but as you go through the list you realize wrong summed figures and long decimal places. What could be wrong and what can I do to solve this. Here is my code:
var TKF_URL = 'https://api.10000ft.com/api/v1/';
var TKF_AUTH = 'auth'
var TKF_PGSZ = 2500
var from = '2020-01-06'
var to = '2020-01-22'
var options = {
method: 'get',
headers: {
Authorization: 'Bearer ' + TKF_AUTH
}
};
function getUsers() {
var userarray = [];
var lastpage = false;
var page = 1;
do {
// gets 10kft data
var users = read10k_users(page);
// writes data from current page to array
for (var i in users.data) {
var rec = {};
// pushing of mandatory data
rec.id = users.data[i].id;
rec.display_name = users.data[i].display_name;
rec.email = users.data[i].email;
userarray.push(rec);
}
// checks if this is the last page (indicated by paging next page link beeing null
if (users.paging.next != null) {
lastpage = false;
var page = page + 1;
} else {
lastpage = true;
}
}
while (lastpage == false);
return (userarray);
return (userarray);
}
function read10k_users(page) {
var endpoint = 'users?';
var url = TKF_URL + endpoint + 'per_page=' + TKF_PGSZ + '&auth=' + TKF_AUTH + '&page=' + page;
var response = UrlFetchApp.fetch(url, options);
var json = JSON.parse(response);
//Logger.log(json.data)
return (json);
}
function showTimeData() {
var users = getUsers()
var endpoint = 'users/';
var time_array = [];
for (var i = 0; i < users.length; i++) {
var total_hours = 0;
// Logger.log(users[i].id)
var url = 'https://api.10000ft.com/api/v1/users/' + users[i].id + '/time_entries?fields=approvals' + '&from=' + from + '&to=' + to + '&auth=' + TKF_AUTH;
var response = UrlFetchApp.fetch(url, options);
var info = JSON.parse(response.getContentText());
var content = info.data;
for (var j = 0; j < content.length; j++) {
total_hours += content[j].hours;
// }
//
// if(total_hours < 35){
//
// sendMail(user[i]);
//
// }
Logger.log('User name: ' + users[i].display_name + ' ' + 'User id: ' + users[i].id + ' ' + 'total hours: ' + total_hours)
}
}
function sendMail(user) {
var emailAddress = user.email;
var message = 'Dear ' + user.display_name + 'Your timesheets is incomplete , please visist 10k Ft and commlete your timesheet'
var subject = 'TimeSheet';
MailApp.sendEmail(emailAddress, subject, message);
}
}
Log results
You have total_hours declared outside of your loop. So what you are doing is calculating the total hours all workers combined, not total hours per worker.
(removed a lot of code to show only the important parts for your bug)
function showTimeData() {
var users = getUsers()
var total_hours = 0; // you declare the variable here
for (var i = 0; i < users.length; i++) {
var content = info.data;
// Calculate the sum for current user
for (var j = 0; j < content.length; j++) {
total_hours += content[j].hours;
}
// Check if total_hours for ALL workers is less than 35
if (total_hours < 35) sendMail(user[i]);
// total_hours is not reset, so the sum is used in next iteration.
}
}
Move the declaration of total_hours to inside the loop, or reset it to zero.
function showTimeData() {
for (var i = 0; i < users.length; i++) {
var total_hours = 0; // you declare the variable here
}
}
Your loop should look something like this:
for (var i = 0; i < users.length; i++) {
var total_hours = 0;
var url = "https://api.10000ft.com/api/v1/users/" + users[i].id + "/time_entries?fields=approvals" + "&from=" + from + "&to=" + to + "&auth=" + TKF_AUTH;
var response = UrlFetchApp.fetch(url, options);
var info = JSON.parse(response.getContentText());
var content = info.data;
for (var j = 0; j < content.length; j++) {
total_hours += content[j].hours;
}
if (total_hours < 35) {
sendMail(user[i]);
}
Logger.log("User name: " + users[i].display_name + " " + "User id: " + users[i].id + " " + "total hours: " + total_hours);
}

getting the variable's value from another funtion

Is there a way to get the 'username' and 'questionid' variable's value in my send() function like how I did with inputText?
var username;
var questionid;
function renderHTML(data) {
var htmlString = "";
var username = data[0].username;
//var examid = data[1].examid;
var questionid = data[2].questionid;
for (var i = 0; i < data.length; i++) {
htmlString += "<p>" + data[i].questionid + "." + "\n" + "Question: " + data[i].question + "\n" + "<input type='text'>";
htmlString += '</p>';
}
response.insertAdjacentHTML('beforeend', htmlString);
}
function send() {
var inputText = document.querySelectorAll("input[type='text']");
var data = [];
for (var index = 0; index < inputText.length; index++) {
input = inputText[index].value;
data.push({
'text': input
});
}
console.log(data);
You do not need var before username and questionid in your renderHTML function, as they have already been defined:
var username;
var questionid;
function renderHTML(data) {
var htmlString = "";
username = data[0].username;
//var examid = data[1].examid;
questionid = data[2].questionid;
for (var i = 0; i < data.length; i++) {
htmlString += "<p>" + data[i].questionid + "." + "\n" + "Question: " + data[i].question + "\n" + "<input type='text'>";
htmlString += '</p>';
}
response.insertAdjacentHTML('beforeend', htmlString);
}
function send() {
var inputText = document.querySelectorAll("input[type='text']");
var data = [];
for (var index = 0; index < inputText.length; index++) {
input = inputText[index].value;
data.push({
'text': input
});
}
console.log(data);

Save the Row data in Table using Javascript

Hi Here I am trying to save the data which user enter in a table. I have written Javascript for this.
<script type="text/javascript">
function Savefile() {
var tbl = document.getElementById("modaltable");
var final = " ";
var finalvalue = " ";
if (tbl != null) {
for (var i = 0; i < tbl.rows.length; i++) {
for (var j = 0; j < tbl.rows[i].cells.length; j++) {
var text = document.getElementById("Comment").value;
var typeofscram = document.getElementById("<%=DropDownList2.ClientID %>").value;
var scramblerreq = document.getElementById("<%=DropDownList1.ClientID %>").value;
var final = text + " " + typeofscram + " " + scramblerreq;
}
finalvalue += final;
}
}
var myCsv = finalvalue;
window.open('data:text/csv;charset=utf-8,' + escape(myCsv));
}
</script>
But it is saving only first row values. But I need to save the remaining row values also. In second row also it is saving first row details.Any mistake in above code.

how to use following code recursively for different tables

Query(document).ready(function() {
var trCount = $('.Firsttable tr').length;
for (var i = 4; i <=4; i++) {
var $td = $('.Firsttable tr:eq(2) td:eq(' + i + ')'),
highest = 0,
lowest = 9e99;
for (var j = 1; j < trCount; j++) {
$td = $td.add('.Firsttable tr:eq(' + j + ') td:eq(' + i + ')');
}
$td.each(function(i, el){
var $el = $(el);
if (i > 0) {
var val = parseInt($el.text().replace(/[\$,]/g, ''), 10);
if (val < lowest) {
lowest = val;
$td.removeClass('low');
$el.addClass('low');
}
}
});
}
Assign ID attribute to each of your tables and write a function like this:
<script type="text/javascript">
function testTable(tableId) {
var trCount = $('#'+ tableId +' tr').length;
for (var i = 4; i <=4; i++) {
var $td = $('#'+ tableId +' tr:eq(2) td:eq(' + i + ')'),
highest = 0,
lowest = 9e99;
for (var j = 1; j < trCount; j++) {
$td = $td.add('#'+ tableId +' tr:eq(' + j + ') td:eq(' + i + ')');
}
$td.each(function(i, el){
var $el = $(el);
if (i > 0) {
var val = parseInt($el.text().replace(/[\$,]/g, ''), 10);
if (val < lowest) {
lowest = val;
$td.removeClass('low');
$el.addClass('low');
}
}
});
}
</script>
Now just call this function for every table by passing it's id,
<script type="text/javascript>
Query(document).ready(function() {
testTable('table1');
testTable('table2');
}
</script>
Hope it helps, thanks.

How to create a dynamic table in a dynamic cell?

I created a dynamic table that contains 20 rows and 2 columns. this is my code:
function createTblBtnClick() {
var tbl = document.createElement("table");
tbl.setAttribute("id", "myTable");
tbl.setAttribute("dir", "rtl");
tbl.cellPadding = 0;
tbl.cellSpacing = 0;
for (i = 0; i < rowNum; i++) {
var row = tbl.insertRow(-1);
for (j = 0; j < colNum; j++) {
var cell = row.insertCell(-1);
cell.setAttribute("id", "cell" + i.toString() + "-" + j.toString());
}
}
document.getElementById("MyTablePanel").innerHTML = "";
document.getElementById("MyTablePanel").appendChild(tbl);
for (i = 0; i < rowNum; i++) {
for (j = 0; j < colNum; j++) {
var srt = "<a href='javascript:select(" + i.toString() + "," + j.toString() + ")' ><div id='div-" + i.toString() + "-" + j.toString() + "'> </div></a>";
document.getElementById("cell" + i.toString() + "-" + j.toString()).innerHTML = srt;
}
}
}
Now I want to add another table in any of my cells. In fact I want to divide each of my cells to 2. How can I do it?
I test below code but it creates 4 column in a row :
function createTblBtnClick() {
var tbl = document.createElement("table");
var tb2 = document.createElement("table");
tbl.setAttribute("id", "myTable");
tbl.setAttribute("dir", "rtl");
tbl.cellPadding = 0;
tbl.cellSpacing = 0;
tb2.setAttribute("id", "myTable1");
//tbl.setAttribute("dir", "rtl");
tb2.cellPadding = 0;
tb2.cellSpacing = 0;
var inner_tb = 0;
for (i = 0; i < rowNum; i++) {
var row = tbl.insertRow(-1);
for (j = 0; j < colNum; j++) {
var cell = row.insertCell(-1);
cell.setAttribute("id", "cell" + i.toString() + "-" + j.toString());
}
}
document.getElementById("MyTablePanel").innerHTML = "";
document.getElementById("MyTablePanel").appendChild(tbl);
////////////////////////////////////////////////////////
var row1 = tb2.insertRow(-1);
for (inner_tb = 0; inner_tb < 2; inner_tb++) {
var cell1 = row.insertCell(-1);
cell.setAttribute("id", "in_cell " + inner_tb.toString());
}
document.getElementById("cell" + i.toString() + "-" + j.toString()).innerHTML = "";
document.getElementById("cell" + i.toString() + "-" + j.toString()).appendChild(tb2);
///////////////////////////////////////////////////////////////
for (i = 0; i < rowNum; i++) {
for (j = 0; j < colNum; j++) {
var srt = "<a href='javascript:select(" + i.toString() + "," + j.toString() + ")' ><div id='div-" + i.toString() + "-" + j.toString() + "'> </div></a>";
document.getElementById("cell" + i.toString() + "-" + j.toString()).innerHTML = srt;
}
}
}
Do exactly the same logic, but append the table to a cell reference.
var innerTbl = document.createElement("table");
//Populate the table...
//With the table populated, append it in the cell of the outertable.
cell.appendChild(innerTbl);
I think this might be what you're trying to do:
http://jsfiddle.net/mPwpq/1/
function createTblBtnClick() {
var rowNum = 20;
var colNum = 2;
var tbl = document.createElement("table");
tbl.setAttribute("id", "myTable");
tbl.setAttribute("dir", "rtl");
tbl.cellPadding = 0;
tbl.cellSpacing = 0;
for (i = 0; i < rowNum; i++) {
var row = tbl.insertRow(-1);
for (j = 0; j < colNum; j++) {
var cell = row.insertCell(-1);
cell.setAttribute("id", "cell" + i.toString() + "-" + j.toString());
// Add inner table with two columns
var innerTbl = document.createElement("table");
innerTbl.innerHTML = '<tr><td>A</td><td>B</td></tr>';
cell.appendChild(innerTbl);
}
}
document.getElementById("MyTablePanel").innerHTML = "";
document.getElementById("MyTablePanel").appendChild(tbl);
}
just a suggestion. Rather than using javascript for doing creating table, why not create the table in the HTML. Get that table in a var using Document.getElementByID. create new string variable like "thisRow" and add the HTML code in the string of the variable like
thisRow += "rowcellinner table"
and then use .append(thisRow);
you can assign the value to thisRow variable in each counter of the loop and append it to table. I find this easier to do.

Categories