I'm working on some project and im stuck with this for a while. I have table like this in database:
ProjectName | UserName | SpentDays |
---|---|---|
FirstProject | User1 | 10 |
SecondProject | User1 | 5 |
SecondProject | User2 | 3 |
ThirdProject | NULL | NULL |
Then i get that informations in js in array like this:
ProjectInfo = [{
ProjectName: 'FirstProject',
UserName: 'User1',
SpentDays: 10
}, {
ProjectName: 'SecondProject',
UserName: 'User1',
SpentDays: 5
}, {
ProjectName: 'SecondProject',
UserName: 'User2',
SpentDays: 3
}, {
ProjectName: 'ThirdProject',
UserName: NULL,
SpentDays: NULL
}]
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
How can i get HTML table like this using JS/JQUERY:
Projects | User1 | User2 |
---|---|---|
FirstProject | 10 | NULL |
SecondProject | 5 | 3 |
ThirdProject | NULL | NULL |
CodePudding user response:
We need a mix of reduce and map and template literals
const NULL = null; // or you use null in the object
ProjectInfo = [{
ProjectName: 'FirstProject',
UserName: 'User1',
SpentDays: 10
}, {
ProjectName: 'SecondProject',
UserName: 'User1',
SpentDays: 5
}, {
ProjectName: 'SecondProject',
UserName: 'User2',
SpentDays: 3
}, {
ProjectName: 'ThirdProject',
UserName: NULL,
SpentDays: NULL
}]
const users = [...new Set(ProjectInfo.map(({ UserName }) => UserName))].filter(user => user != NULL); // create a list of users
document.querySelector("table thead tr").innerHTML = users.map(user => `<th>${user}</th>`).join(""); // add them to the table head
// create a default object
const obj = JSON.stringify(users.reduce((acc, user) => {
acc[user] = "NULL";
return acc
}, {}));
// reduce to something more manageable
const rows = ProjectInfo.reduce((acc, cur) => {
acc[cur.ProjectName] = acc[cur.ProjectName] || JSON.parse(obj)
if (cur.UserName !== null) acc[cur.ProjectName][cur.UserName] = cur.SpentDays
return acc
}, {});
document.querySelector("table tbody").innerHTML = Object
.entries(rows)
.map(([name,project]) => `<tr><td>${name}</td>${Object
.values(project)
.map(val => `<td>${val}</td>`)
.join("")}</tr>`)
.join("");
<link rel="stylesheet" href="https://cdn.sstatic.net/Shared/stacks.css" />
<table class="s-table">
<thead>
<tr>
<th>Projects</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
This should do the trick.
Nevermind this answer, I misread what the OP was wanting.
projectInfo = [{
ProjectName: 'FirstProject',
UserName: 'User1',
SpentDays: 10
}, {
ProjectName: 'SecondProject',
UserName: 'User1',
SpentDays: 5
}, {
ProjectName: 'SecondProject',
UserName: 'User2',
SpentDays: 3
}, {
ProjectName: 'ThirdProject',
UserName: null,
SpentDays: null
}];
var tbody = $('#mytable tbody');
projectInfo.forEach(e => {
var row = $("<tr></tr>");
row.append($("<td></td>").text(e.ProjectName));
row.append($("<td></td>").text(e.UserName));
row.append($("<td></td>").text(e.SpentDays));
tbody.append(row);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="mytable" border=1>
<thead>
<tr>
<th>Projects</th>
<th>UserName</th>
<th>SpentDays</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>