ltpitt
asked on
How to calculate cleaning turns if every flatmate is doing a two weeks turn dynamically?
Hi all,
I am building a table that automatically shows who is the person that is in charge of cleaning the kitchen in plain Javascript.
This is what I have so far:
I cannot think how to populate dynamically the turns, given the fact that the flatmate4 started cleaning week 1 and 2 of the year.
How can I be able to make the script perpetually work?
Thanks for your help.
I am building a table that automatically shows who is the person that is in charge of cleaning the kitchen in plain Javascript.
This is what I have so far:
<style>
th, td {
padding: 15px;
text-align: left;
}
tr:hover {background-color: #f5f5f5;}
table {
width: 100%;
}
</style>
<div id="cleaningTableDiv">
</div>
<script>
Date.prototype.getWeek = function() {
var onejan = new Date(this.getFullYear(), 0, 1);
return Math.ceil((((this - onejan) / 86400000) + onejan.getDay() + 1) / 7);
}
function plainTableCreate(currentWeekNumber) {
// Table variables
var teamMembers = ["Flatmate1", "Flatmate2", "Flatmate3", "Flatmate4", "Flatmate5", "Flatmate6"];
var rowNumber = 7;
var colNumber = teamMembers.length * 2 + 1;
var headings = ["Week number"]
for (var i = 0; i < colNumber - 1; i++) {
headings.push(currentWeekNumber + i);
}
// Creating table
var body = document.getElementById('cleaningTableDiv');
var tbl = document.createElement('table');
tbl.setAttribute("id", "cleaningTable");
var tbdy = document.createElement('tbody');
for (var i = 0; i < rowNumber; i++) {
var tr = document.createElement('tr');
for (var j = 0; j < colNumber; j++) {
var td = document.createElement('td');
td.appendChild(document.createTextNode(""));
tr.appendChild(td);
}
tbdy.appendChild(tr);
}
tbl.appendChild(tbdy);
body.appendChild(tbl);
// Populating headings
for (var i=0; i < headings.length; i++){
document.getElementById("cleaningTable").rows[0].cells[i].innerHTML = headings[i];
}
// Populating 1st column with Team Members
for (var i=1; i < rowNumber; i++){
document.getElementById("cleaningTable").rows[i].cells[0].innerHTML = teamMembers[i-1];
}
// Populating X
for (var i=1; i < rowNumber; i++){
for (var j=1; j < colNumber; j++){
if (i == 4) {
// Flatmate 4 started cleaning week 1 and 2, next rotation will happen every 2
// weeks, for example flatmate 5 will clean week 3 and 4, flatmate 6 will clean
// week 5 and 6, flatmate 6 will clean week 7 and 8, flatmate 1 will clean
// week 9 and 10 and so on...
document.getElementById("cleaningTable").rows[i].cells[j].innerHTML = "X";
}
console.log(document.getElementById("cleaningTable").rows[0].cells[j].innerHTML);
}
}
}
var currentWeekNumber = (new Date()).getWeek();
plainTableCreate(currentWeekNumber);
</script>
I cannot think how to populate dynamically the turns, given the fact that the flatmate4 started cleaning week 1 and 2 of the year.
How can I be able to make the script perpetually work?
Thanks for your help.
Well, I would start by separating the table creation from the doing the calculus first.
ASKER
Ok, I see your point.
I have 6 flatmates and 52 weeks per year.
Flatmate 4 started the cleaning on the 1st week of the year, every cleaning turn lasts 2 weeks.
Now we are, for example, in week 23.
Who should clean?
23 / 2 = 11
11 users after flatmate 4?
But if I do the calculations it doesn't always work and I am a bit puzzled...
I have 6 flatmates and 52 weeks per year.
Flatmate 4 started the cleaning on the 1st week of the year, every cleaning turn lasts 2 weeks.
Now we are, for example, in week 23.
Who should clean?
23 / 2 = 11
11 users after flatmate 4?
But if I do the calculations it doesn't always work and I am a bit puzzled...
Something like this
<style>
th, td {
padding: 15px;
text-align: left;
}
tr:hover {background-color: #f5f5f5;}
table {
width: 100%;
}
</style>
<div id="cleaningTableDiv">
</div>
<script>
var teamMembers = ["Flatmate1", "Flatmate2", "Flatmate3", "Flatmate4", "Flatmate5", "Flatmate6"];
createCleaningTable(document.getElementById('cleaningTableDiv'), teamMembers, 3);
function createCleaningTable(parent, teamMembers, currentTeamMember) {
var data = [];
for(var i = 0; i < teamMembers.length; i++) {
var tm = teamMembers[currentTeamMember % teamMembers.length];
var entry = {
member: tm,
weeks: []
}
for(var wk = i; wk <= 52; wk+= teamMembers.length) {
entry.weeks.push(wk*2+1);
entry.weeks.push(wk*2+2);
}
data.push(entry);
currentTeamMember++;
}
var table = document.createElement('table');
var thead = table.createTHead();
var trow = thead.insertRow();
var th = document.createElement('th');
th.innerHTML = 'Member';
trow.appendChild(th);
for(var i = 1; i <= 52; i++){
th = document.createElement('th');
th.innerHTML = i;
trow.appendChild(th);
}
table.appendChild(thead);
var tbody = table.createTBody();
data.forEach(function(item) {
var row = tbody.insertRow();
var cell = row.insertCell();
cell.innerHTML = item.member;
for(var wk = 1; wk <= 52; wk++) {
cell = row.insertCell();
if (item.weeks.includes(wk)) {
cell.innerHTML = 'x';
}
}
});
parent.appendChild(table);
}
</script>
You can see it working here
Updated with comments and added a sort to put the table in flat mate order
<style>
th, td {
padding: 15px;
text-align: left;
}
tr:hover {background-color: #f5f5f5;}
table {
width: 100%;
}
</style>
<div id="cleaningTableDiv">
</div>
<script>
var teamMembers = ["Flatmate1", "Flatmate2", "Flatmate3", "Flatmate4", "Flatmate5", "Flatmate6"];
createCleaningTable(document.getElementById('cleaningTableDiv'), teamMembers, 3);
function createCleaningTable(parent, teamMembers, currentTeamMember) {
var data = [];
// Create our cleaning data first
// Iterate over the flatmates and create the weeks for them. We do this
// by starting with the currentTeamMember and then incrementing using the Mod to get
// the actual Team Member we are working with
// We then work out all the weeks that person will be cleaning which is jumping by 2 each time
// and then by the number of team members
for(var i = 0; i < teamMembers.length; i++) {
var tm = teamMembers[currentTeamMember % teamMembers.length];
var entry = {
member: tm,
weeks: []
}
for(var wk = i; wk <= 52; wk+= teamMembers.length) {
entry.weeks.push(wk*2+1);
entry.weeks.push(wk*2+2);
}
data.push(entry);
currentTeamMember++;
}
// Sort the data in flatmate order
data.sort(function(a,b) {
return a.member === b.member ? 0 : a.member < b.member ? -1 : 1;
});
// Data organised now we create the table
var table = document.createElement('table');
var thead = table.createTHead();
var trow = thead.insertRow();
var th = document.createElement('th');
th.innerHTML = '';
trow.appendChild(th);
// Build the THEAD section
for(var i = 1; i <= 52; i++){
th = document.createElement('th');
th.innerHTML = i;
trow.appendChild(th);
}
table.appendChild(thead);
// Now the body ...
var tbody = table.createTBody();
data.forEach(function(item) {
var row = tbody.insertRow();
var cell = row.insertCell();
cell.innerHTML = item.member;
for(var wk = 1; wk <= 52; wk++) {
cell = row.insertCell();
if (item.weeks.includes(wk)) {
cell.innerHTML = 'x';
}
}
});
parent.appendChild(table);
}
</script>
Working sample here
ASKER
Hi Julian and thanks for your input.
Your solution draws a very big table containing all the data, I wanted to make just a small list of the coming weeks and show very easily which is the current one (the 1st).
Populating the data in your case is easier because it just becomes mark two, next, mark two, next etc.
But thanks for your contribution!
Your solution draws a very big table containing all the data, I wanted to make just a small list of the coming weeks and show very easily which is the current one (the 1st).
Populating the data in your case is easier because it just becomes mark two, next, mark two, next etc.
But thanks for your contribution!
Then simply change the parameters to draw from the start week to the week you want.
<style>
th, td {
padding: 15px;
text-align: left;
}
tr:hover {background-color: #f5f5f5;}
table {
width: 100%;
}
</style>
<div id="cleaningTableDiv">
</div>
<script>
var teamMembers = ["Flatmate1", "Flatmate2", "Flatmate3", "Flatmate4", "Flatmate5", "Flatmate6"];
createCleaningTable(document.getElementById('cleaningTableDiv'), teamMembers, 3, 1,13);
function createCleaningTable(parent, teamMembers, currentTeamMember, from, to) {
var data = [];
// Create our cleaning data first
// Iterate over the flatmates and create the weeks for them. We do this
// by starting with the currentTeamMember and then incrementing using the Mod to get
// the actual Team Member we are working with
// We then work out all the weeks that person will be cleaning which is jumping by 2 each time
// and then by the number of team members
for(var i = 0; i < teamMembers.length; i++) {
var tm = teamMembers[currentTeamMember % teamMembers.length];
var entry = {
member: tm,
weeks: []
}
for(var wk = i; wk <= 52; wk+= teamMembers.length) {
entry.weeks.push(wk*2+1);
entry.weeks.push(wk*2+2);
}
data.push(entry);
currentTeamMember++;
}
// Sort the data in flatmate order
data.sort(function(a,b) {
return a.member === b.member ? 0 : a.member < b.member ? -1 : 1;
});
// Data organised now we create the table
var table = document.createElement('table');
var thead = table.createTHead();
var trow = thead.insertRow();
var th = document.createElement('th');
th.innerHTML = '';
trow.appendChild(th);
// Build the THEAD section
for(var i = from; i <= to; i++){
th = document.createElement('th');
th.innerHTML = i;
trow.appendChild(th);
}
table.appendChild(thead);
// Now the body ...
var tbody = table.createTBody();
data.forEach(function(item) {
var row = tbody.insertRow();
var cell = row.insertCell();
cell.innerHTML = item.member;
for(var wk = from; wk <= to; wk++) {
cell = row.insertCell();
if (item.weeks.includes(wk)) {
cell.innerHTML = 'x';
}
}
});
parent.appendChild(table);
}
</script>
You call the createCleaningTable with two additional parameters (from and to) and it will render the table for that set of weeks.
ASKER CERTIFIED SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
Corrected a minor issue in the render code.
Original : https://www.marcorpsa.com/ee/t3785.html
Dynamic: https//www.marcorpsa.com/ee/t3785-a.html
Original : https://www.marcorpsa.com/ee/t3785.html
Dynamic: https//www.marcorpsa.com/ee/t3785-a.html