I have a searchable HTML table, that retrieves SharePoint list items from a multiple subsites, and everything about it is nearly perfect. The one issue I am facing is that the "Program" item keeps printing every time the function runs through/loops, but I only want it to print the "Program" header/item once, and have the correlating items all print under the one Program header. I will attach below a screenshot of my table and how it prints, as well as my function that reads the information and prints it to the table. Any suggestions/help/advice would be greatly appreciated.
Would I use something along the lines of an if statement?
For example, have the Meeting Minutes and MSR rows for each type of Program print under only one Program.
Actual Result:
**Expected Result**
+------------+----------------------+-----------+------------+--------------+--------------+
| Program | To | Date | Approved | Notes | Deliverable |
+------------+----------------------+-----------+------------+--------------+--------------+
| Program 1 | example#example.com | 12/23/2018| Yes | Example Notes| MSR |
| | example#example.com | 03/30/2020| Yes | Example Notes| Meeting Mins |
+------------+----------------------+-----------+------------+--------------+--------------+
| Program 2 | example#example.com | 12/23/2018| Yes | Example Notes| MSR |
| | example#example.com | 12/03/2017| Yes | Example Notes| Meeting Mins |
+------------+----------------------+-----------+------------+--------------+--------------+
| Program 3 | example#example.com | 04/17/2020| Yes | Example Notes| MSR |
| | example#example.com | 03/30/2020| No | Example Notes| Meeting Mins |
+------------+----------------------+-----------+------------+--------------+--------------+
Here is my code:
.then(([r1, r2, r3]) => {
const objItems = r1.concat(r2,r3);
console.log(objItems);
var tableContent =
'<table id="deliverablesTable" style="width:100%" border="1 px"><thead><tr><td><strong>Program</strong></td>' +
"<td><strong>To</strong></td>" +
"<td><strong>Date Submitted</strong></td>" +
"<td><strong>Approved</strong></td>" +
"<td><strong>Notes</strong></td>" +
"<td><strong>Deliverable</strong></td>" +
"</tr></thead><tbody>";
for (var i = 0; i < objItems.length; i++) {
if (objItems.Program == "1"){
tableContent += "<tr>";
tableContent += "<td>" + objItems[i].Program + "</td>";
tableContent += "</tr>";
tableContent += "<tr>";
tableContent += "<td> </td>";
tableContent += "<td>" + objItems[i].To + "</td>";
tableContent += "<td>" + objItems[i].Date + "</td>";
tableContent += "<td>" + objItems[i].Approved + "</td>";
tableContent += "<td>" + objItems[i].Notes + "</td>";
tableContent += "<td>" + objItems[i].Deliverable + "</td>";
tableContent += "</tr>";
}
else if (objItems.Program == "2"){
tableContent += "<tr>";
tableContent += "<td>" + objItems[i].Program + "</td>";
tableContent += "</tr>";
tableContent += "<tr>";
tableContent += "<td> </td>";
tableContent += "<td>" + objItems[i].To + "</td>";
tableContent += "<td>" + objItems[i].Date + "</td>";
tableContent += "<td>" + objItems[i].Approved + "</td>";
tableContent += "<td>" + objItems[i].Notes + "</td>";
tableContent += "<td>" + objItems[i].Deliverable + "</td>";
tableContent += "</tr>";
}
else if (objItems.Program == "3"){
tableContent += "<tr>";
tableContent += "<td>" + objItems[i].Program + "</td>";
tableContent += "</tr>";
tableContent += "<tr>";
tableContent += "<td> </td>";
tableContent += "<td>" + objItems[i].To + "</td>";
tableContent += "<td>" + objItems[i].Date + "</td>";
tableContent += "<td>" + objItems[i].Approved + "</td>";
tableContent += "<td>" + objItems[i].Notes + "</td>";
tableContent += "<td>" + objItems[i].Deliverable + "</td>";
tableContent += "</tr>";
}
}
$("#deliverables").append(tableContent);
})
.catch((err) => {
alert("Error: " + err);
console.error(err);
});
});
[1]: https://i.stack.imgur.com/ULOMF.png
var tableData =
[{'program': 'Program 1', 'To': 'example1', Date: '8/5', Approved: 'Yes', Notes: 'Note', Deliverable: 'Deliverable'},
{'program': 'Program 1', 'To': 'example2', Date: '8/5', Approved: 'Yes', Notes: 'Note', Deliverable: 'Deliverable'},
{'program': 'Program 2', 'To': 'example3', Date: '8/5', Approved: 'No', Notes: 'Note', Deliverable: 'Deliverable'},
{'program': 'Program 3', 'To': 'example4', Date: '8/5', Approved: 'Yes', Notes: 'Note', Deliverable: 'Deliverable'},
{'program': 'Program 3', 'To': 'example4', Date: '8/5', Approved: 'Yes', Notes: 'Note', Deliverable: 'Deliverable'},
{'program': 'Program 3', 'To': 'example4', Date: '8/5', Approved: 'Yes', Notes: 'Note', Deliverable: 'Deliverable'}]
//Fake loadData(...)
Promise.all(tableData)
.then((r1) => {
const objItems = r1;
makeTable(objItems);
})
function makeTable(tableData){
var group = {};
for(var d of tableData){
if(group[d.program]){
group[d.program].push(d);
} else {
group[d.program] = [d];
}
}
var tableContent = ''; // I put the table in the html but you can populate it here
for (var prop in group) {
tableContent += "<tr>";
tableContent += "<td rowspan=\""+ group[prop].length +"\">" + prop + "</td>";
tableContent += "<td>" + group[prop][0].To + "</td>";
tableContent += "<td>" + group[prop][0].Date + "</td>";
tableContent += "<td>" + group[prop][0].Approved + "</td>";
tableContent += "<td>" + group[prop][0].Notes + "</td>";
tableContent += "<td>" + group[prop][0].Deliverable + "</td>";
tableContent += "</tr>";
for(var i = 0; i < group[prop].length - 1; i++){
tableContent += "<tr>";
tableContent += "<td>" + group[prop][i+1].To + "</td>";
tableContent += "<td>" + group[prop][i+1].Date + "</td>";
tableContent += "<td>" + group[prop][i+1].Approved + "</td>";
tableContent += "<td>" + group[prop][i+1].Notes + "</td>";
tableContent += "<td>" + group[prop][i+1].Deliverable + "</td>";
tableContent += "</tr>";
}
}
$("#deliverablesTable").append(tableContent);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="deliverablesTable" style="width:100%" border="1 px">
<thead>
<tr>
<td><strong>Program</strong></td>
<td><strong>To</strong></td>
<td><strong>Date</strong></td>
<td><strong>Approved</strong></td>
<td><strong>Notes</strong></td>
<td><strong>Deliverable</strong></td>
</tr></thead><tbody>
Related
I am trying to get my dynamically created HTML table to display text (contained within an array) on hover of a given cell, using the title attribute, but it will not read the contents of the array and instead reads the array name as a string.
Here is the table generating code and have attempted to add titles to cells of 2 columns currently:
var result = "<table id='dataEditTableid' class='stripe' border=1><thead><tr><th><b>Name</b></th><th><b>7.1</b></th><th><b>7.2</b></th><th><b>7.3</b></th><th><b>7.4</b></th><th><b>7.5</b></th><th><b>7.6</b></th><th><b>8.1</b></th><th><b>8.2</b></th><th><b>8.3</b></th><th><b>8.4</b></th><th><b>8.5</b></th><th><b>8.6</b></th><th><b>9.1</b></th><th><b>9.2</b></th><th><b>9.3</b></th><th><b>9.4</b></th><th><b>9.5</b></th><th><b>9.6</b></th></tr></thead>";
result += "<tbody>";
for (var i=0; i < studentsList.length; i++) {
result += "<tr>";
result += "<td>"+studentsList[i][0]+"</td>";
result += "<td title = studentsList[i][3] style='background-color: "+redBlue(studentsList[i][3])+";' id=" + i+3 + "></td>";
result += "<td title = studentsList[i][4] style='background-color: "+redBlue(studentsList[i][4])+";' id=" + i+4 + "></td>";
result += "<td style='background-color: "+redBlue(studentsList[i][5])+";' id=" + i+5 + "></td>";
result += "<td style='background-color: "+redBlue(studentsList[i][6])+";' id=" + i+6 + "></td>";
result += "<td style='background-color: "+redBlue(studentsList[i][7])+";' id=" + i+7 + "></td>";
result += "<td style='background-color: "+redBlue(studentsList[i][8])+";' id=" + i+8 + "></td>";
result += "<td style='background-color: "+redBlue(studentsList[i][9])+";' id=" + i+9 + "></td>";
result += "<td style='background-color: "+redBlue(studentsList[i][10])+";' id=" + i+10 + "></td>";
result += "<td style='background-color: "+redBlue(studentsList[i][11])+";' id=" + i+11 + "></td>";
result += "<td style='background-color: "+redBlue(studentsList[i][12])+";' id=" + i+12 + "></td>";
result += "<td style='background-color: "+redBlue(studentsList[i][13])+";' id=" + i+13 + "></td>";
result += "<td style='background-color: "+redBlue(studentsList[i][14])+";' id=" + i+14 + "></td>";
result += "<td style='background-color: "+redBlue(studentsList[i][15])+";' id=" + i+15 + "></td>";
result += "<td style='background-color: "+redBlue(studentsList[i][16])+";' id=" + i+16 + "></td>";
result += "<td style='background-color: "+redBlue(studentsList[i][17])+";' id=" + i+17 + "></td>";
result += "<td style='background-color: "+redBlue(studentsList[i][18])+";' id=" + i+18 + "></td>";
result += "<td style='background-color: "+redBlue(studentsList[i][19])+";' id=" + i+19 + "></td>";
result += "<td style='background-color: "+redBlue(studentsList[i][20])+";' id=" + i+20 + "></td>";
result += "</tr>";
}
result += "</tbody></table>";
dataTable.innerHTML = result;
What have I done wrong?
result += "<td title='"+ studentsList[i][4] +"' style='background-color: "+redBlue(studentsList[i][4])+";' id=" + i+4 + "></td>";
you've messed quotations, please replace this with the older ones
also, no need to repeat stuff just add another for loop inside the for:
for (var i = 0; i < studentsList.length; i++) {
result += "<tr>";
result += "<td>" + studentsList[i][0] + "</td>";
result += "<td title='"+ studentsList[i][3] +"' style='background-color: "+redBlue(studentsList[i][3])+";' id=" + i+3 + "></td>";
result += "<td title='"+ studentsList[i][4] +"' style='background-color: "+redBlue(studentsList[i][4])+";' id=" + i+4 + "></td>";
for (var j = 4; j = < 20; i++) {
result += "<td style='background-color: " + redBlue(studentsList[i][j]) + ";' id=" + i + j + "></td>";
}
result += "</tr>";
}
I have a grouped/sorted array based on its "Program" attribute which is great. But now I need to sort by a different attribute (Deliverable) inside of that grouping, is that possible? And if so how can I accomplish that?
Here is a picture of my table.
See how it is organized by Program? Inside of the Program grouping, I want to also sort/group based on the Deliverable item, since there will be way more than two within each Program. Also, if it isn't too much work I would also love to make those rows clickable (expand/collapse) so the table isn't 100 rows long once it is loaded.
Here is my expected output:
Expected Result
+------------+----------------------+-----------+------------+--------------+---------------------+
| Program | Deliverable | Date | Approved | Notes | To |
+------------+----------------------+-----------+------------+--------------+---------------------+
| Program 1 | |
+------------+----------------------+-----------+------------+--------------+---------------------+
| | Monthly Status Report| |
+------------+----------------------+-----------+------------+--------------+---------------------+
| | | 05/10/2020| Yes | Example Notes| example#example.com |
+------------+----------------------+-----------+------------+--------------+---------------------+
| | | 03/30/2020| No | Example Notes| example#example.com |
+------------+----------------------+-----------+------------+--------------+---------------------+
| | Meeting Minutes | |
+------------+----------------------+-----------+------------+--------------+---------------------+
| | | 02/10/2010| Yes | Example Notes| example#example.com |
+------------+----------------------+-----------+------------+--------------+---------------------+
| | | 03/30/2020| Yes | Example Notes| example#example.com |
+------------+----------------------+-----------+------------+--------------+---------------------+
| Program 2 | |
+------------+----------------------+-----------+------------+--------------+---------------------+
| | Monthly Status Report| |
+------------+----------------------+-----------+------------+--------------+---------------------+
| | | 05/10/2020| Yes | Example Notes| example#example.com |
+------------+----------------------+-----------+------------+--------------+---------------------+
| | | 03/30/2020| No | Example Notes| example#example.com |
+------------+----------------------+-----------+------------+--------------+---------------------+
| | Meeting Minutes | |
+------------+----------------------+-----------+------------+--------------+---------------------+
| | | 02/10/2010| Yes | Example Notes| example#example.com |
+------------+----------------------+-----------+------------+--------------+---------------------+
| | | 03/30/2020| Yes | Example Notes| example#example.com |
+------------+----------------------+-----------+------------+--------------+---------------------+
Here is my code:
.then(([r1, r2, r3]) => {
const objItems = r1.concat(r2,r3);
console.log(JSON.stringify(objItems));
console.log(objItems);
var tableContent =
'<table id="deliverablesTable" style="width:100%" border="1 px"><thead><tr colspan = "5"><td><strong>Program</strong></td>' +
"<td><strong>To</strong></td>" +
"<td><strong>Date Submitted</strong></td>" +
"<td><strong>Approved</strong></td>" +
"<td><strong>Notes</strong></td>" +
"<td><strong>Deliverable</strong></td>" +
"</tr></thead><tbody>";
var sortedObj = {}
objItems.forEach(item => {
var program = item.Program;
delete(item.Program); //remove this line to keep the program in the item data
if (!sortedObj[program]) {
sortedObj[program] = [];
}
sortedObj[program].push(item);
});
Object.keys(sortedObj).forEach(key => {
tableContent += "<tr>";
tableContent += "<td>" + key + "</td>";
tableContent += "</tr>";
sortedObj[key].forEach(obj => {
tableContent += "<tr>";
tableContent += "<td> </td>";
tableContent += "<td>" + obj.To + "</td>";
tableContent += "<td>" + obj.Date + "</td>";
tableContent += "<td>" + obj.Approved + "</td>";
tableContent += "<td>" + obj.Notes + "</td>";
tableContent += "<td>" + obj.Deliverable + "</td>";
tableContent += "</tr>";
});
});
$("#deliverables").append(tableContent);
})
.catch((err) => {
alert("Error: " + err);
console.error(err);
});
});
Just sort the result that you have.
Object.keys(sortedObj).forEach(key => {
tableContent += "<tr>";
tableContent += "<td>" + key + "</td>";
tableContent += "</tr>";
sortedObj[key].sort((a,b)=>{
if (a.Deliverable > b.Deliverable) return 1;
if (a.Deliverable < b.Deliverable) return -1;
return 0;
}).forEach(obj => {
tableContent += "<tr>";
tableContent += "<td> </td>";
tableContent += "<td>" + obj.To + "</td>";
tableContent += "<td>" + obj.Date + "</td>";
tableContent += "<td>" + obj.Approved + "</td>";
tableContent += "<td>" + obj.Notes + "</td>";
tableContent += "<td>" + obj.Deliverable + "</td>";
tableContent += "</tr>";
});
});
Here is the code:
var sortedObj = {}
objItems.forEach(item => {
var program = item.Program;
var deliverable = item.Deliverable;
delete (item.Program); //remove this line to keep the program in the item data
delete (item.Deliverable); //remove this line to keep the deliverable in the item data
if(!sortedObj[program]){
sortedObj[program] = {};
}
if(!sortedObj[program][deliverable]){
sortedObj[program][deliverable] = [];
}
sortedObj[program][deliverable].push(item);
});
Object.keys(sortedObj).forEach((program, index) => {
tableContent += "<tr class='breakrow'>";
tableContent += "<td>" + program + "</td>";
tableContent += "</tr>";
Object.keys(sortedObj[program]).forEach((deliverable, index) => {
tableContent += "<tr class='datarow'>";
tableContent += "<td> </td>";
tableContent += "<td>" + deliverable + "</td>";
tableContent += "</tr>";
sortedObj[program][deliverable].forEach(obj => {
tableContent += "<tr class='subdatarow'>";
tableContent += "<td> </td>";
tableContent += "<td> </td>";
tableContent += "<td>" + obj.To + "</td>";
tableContent += "<td>" + obj.Date + "</td>";
tableContent += "<td>" + obj.Approved + "</td>";
tableContent += "<td>" + obj.Notes + "</td>";
tableContent += "</tr>";
});
});
});
$("#deliverables").append(tableContent);
$('.datarow').hide();
$('.subdatarow').hide();
$('#deliverablesTable').on('click', 'tr.breakrow', function(){
console.log('hello');
$(this).nextUntil('tr.breakrow').slideToggle(200);
});
$(document).on('click','#deliverablesTable tr.datarow', function(){
$(this).nextUntil('tr.breakrow, tr.datarow').slideToggle(200);
});
})
I have a code that automatically creates a table for me. It gathers information from a saved file, however, I have two of these files and currently can call one at the time. How can I possibly wrap this code in a function so that there are two calls on the same code with different information that will be put in it? So right now I am using getElementById on file "house-data" but I also want to have this same js on a file "senate-data"
I thought of creating some sort of if statement where if(you have one file): do this
else
do that. But this method doesnt work.
var table = "";
var cols = 1;
var members = data.results[0].members;
var rows = members.length;
table += "<tr>" +
"<th>" + "Full Name" + "</th>" +
"<th>" + "Party" + "</th>" +
"<th>" + "State" + "</th>" +
"<th>" + "Seniority"+ "</th>" +
"<th>" + "Total Votes"+ "</th>" + "</tr>";
for (var r = 0; r < rows; r++) {
table += "<tr>";
for (var c = 0; c < cols; c++) {
table +=
"<td>" + members[r].first_name +", "+
(members[r].middle_name || " ") +" "+
members[r].last_name + "</td>";
table += "<td>" + members[r].party + "</td>" + "<td>" + members[r].state + "</td>" + "<td>" + members[r].seniority + "</td>";
if (members[r].votes_with_party_pct === undefined) {
table += "<td>" + "-" + "</td>"
} else {
table += "<td>" + members[r].votes_with_party_pct + "%" + "</td>"
}
}
table += "<tr>";
}
document.getElementById("house-data").innerHTML = JSON.stringify(table);
function tableCreator(elementID, data) {
[...]
document.getElementById(elementID)[...]
}
above will work for you and keep in mind to check
var members = data.results[0].members;
is available before going to for loop
This is my current table-
txt += "<table border='2'>";
for (x in myObj) {
txt += "<tr>"
txt += "<td>" + myObj[x].friend_id + "</td>";
txt += "<td>" + myObj[x].birth_date + "</td>";
txt += "<td>" + myObj[x].first_name + "</td>";
txt += "<td>" + myObj[x].last_name + "</td>";
txt += "<td>" + myObj[x].gender + "</td>";
txt += "<td>" + myObj[x].phone+ "</td>";
txt += "</tr>"
I'm populating it with JSON output, which works fine. However, I don't know how to add the header to the table. I tried adding the header out of the for loop, but it wouldn't align with the table in the loop. How do I connect both?
Current table- https://imgur.com/a/Fo7OdfX
txt += "<table border='2'>";
txt += "<tr>"
txt += "<th>Friend Id</th>";
txt += "<th>Birth Date</th>";
txt += "<th>First Name</th>";
txt += "<th>Last Name</th>";
txt += "<th>Gender</th>";
txt += "<th>Phone</th>";
txt += "</tr>"
for (x in myObj) {
txt += "<tr>"
txt += "<td>" + myObj[x].friend_id + "</td>";
txt += "<td>" + myObj[x].birth_date + "</td>";
txt += "<td>" + myObj[x].first_name + "</td>";
txt += "<td>" + myObj[x].last_name + "</td>";
txt += "<td>" + myObj[x].gender + "</td>";
txt += "<td>" + myObj[x].phone+ "</td>";
txt += "</tr>"
}
I fixed the problem by calling a function, that graps the id of the table row it is placed in :)
I have this piece of code sorting some different stuff into a table, that works fine. The problem is to pass data into a function called inside HTML tags, like so:
See reference here
$.when(document, getTournamentsData()).done(function(){
var output = "";
$.each(tournamentsData, function(key, data){
output += "<tr class='data_row "+data.isOpen+"' id='"+data._id+"'>";
output += "<td>" + (key+1) + "</td>";
output += "<td><b>" + data.name + "</b></td>";
output += "<td>Start: " + data.begintime + "<br>Slut: " + data.endtime + "</td>";
output += "<td><input class='btn btn-primary' type='button' value='Se beskrivelse' onclick='showTourDescription(data.description)'/></td>";
output += "<td><input class='btn btn-primary' type='button' value='Se billede' onclick='showPic(data.image)'/></td>";
output += "<td>Max antal: "+ data.max_teams +"<br>Tilmeldte: "+ data.teams.length +"</td><br>";
output += "<td><input class='btn btn-primary' type='button' value='Se deltagere' onclick='showMembers(data.teams)'/></td>";
output += "<td>" + prizes(data.prices) + "</td>";
output += "</tr>";
});
output += "";
$('#data_insert').append(output);
});
All I do in the function is to console the data, and I get error "data is not defined"
This is the full script https://github.com/Jakobtottrup/OptekSemester2/blob/master/Web/public/js/tournaments_admin.js
// list tournaments
$.when(document, getTournamentsData()).done(function(){
var output = "";
$.each(tournamentsData, function(key, data){
output += "<tr class='data_row "+convertBoolean(data.isOpen)+"' id='"+data._id+"'>";
output += "<td>" + (key+1) + "</td>"; // index
output += "<td><b>" + data.name + "</b></td>"; // navn
output += "<td>Start: " + data.begintime + "<br>Slut: " + data.endtime + "</td>"; // start/slut
output += "<td><input class='btn btn-primary' type='button' value='Se beskrivelse' onclick='showTourDescription("+data.description+")'/></td>"; // beskrivelse TODO
output += "<td><input class='btn btn-primary' type='button' value='Se billede' onclick='showPic("+data.description+")'/></td>"; // billede
output += "<td>Max antal: "+ data.max_teams +"<br>Tilmeldte: "+ data.teams.length +"</td><br>"; // hold
output += "<td><input class='btn btn-primary' type='button' value='Se deltagere' onclick='showMembers("+data.teams"+)'/></td>"; // medlemmer
output += "<td>" + prizes(data.prices) + "</td>"; // præmier
output += "</tr>";
});
I've taken your code, and as you've done in the HTML strings themselves, concatenated in the event handlers too. Should be all you need to do.
UPDATE: Looks like you are passing data as string. See if that works
$.each(tournamentsData, function(data) {
onclick='showTourDescription(" + data.description + ")