Highlighting selected fields in dynamically added rows makes them disappear - javascript

NOTE: Please no Jquery answers, need to get my head around Javascript first.
So I have added some rows to my table through insertRow(-1).
When I try to look up that table via getElementById and change the background color of a field, it works fine for the first added row:
"dates[4].style.backgroundColor = '#FF0000';"
But not for the second added row or thereafter, they just disappear:
"dates[7].style.backgroundColor = '#FF0000';
I am trying to highlight the current day (will replace the numbers 4/7 with a variable) I'm not sure whats happening, could anyone shed some light please?
Javascript
<script type="text/javascript">
var currentTime = new Date()
var month = currentTime.getMonth() + 1
var day = currentTime.getDate()
var year = currentTime.getFullYear()
var hour = currentTime.getHours()
var min = currentTime.getMinutes()
//document.write(month + "/" + day + "/" + year)
var test = currentTime.getDay();
var day = currentTime.getDate()+1;
var month = currentTime.getMonth();
var full_year = currentTime.getFullYear();
var total_days = (daysInMonth(month,full_year));
var d=1;
function daysInMonth(month,year) {
return new Date(year, month, 0).getDate();
}
var temp = test+1;
for(i=0; i<5; i++){
var table = document.getElementById("calendar");
var row = table.insertRow(-1);
row.setAttribute("id", "rowClassName", 0);
for(c=1;c<8; c++){
if(d<test){
var newCell = row.insertCell(-1);
newCell.innerHTML = '0';
d++;
} else if ((temp-test)<=total_days){
var newCell = row.insertCell(-1);
newCell.innerHTML = (temp-test);
temp = temp+1;
if(temp==day){
var table1 = document.getElementById("rowClassName");
var dates = table1.getElementsByTagName('td');
dates[7].style.backgroundColor = '#FF0000';
}
}
}
}
HTML
<table id="calendar">
<tr>
<td>Mon</td>
<td>Tue</td>
<td>Wed</td>
<td>Thu</td>
<td>Fri</td>
<td>Sat</td>
<td>Sun</td>
</tr>
</table>

Change:
var table1 = document.getElementById("rowClassName");
To:
var table1 = document.getElementById("calendar");
Explanation:
You are only getting the cells for the current row using "rowClassName". Each row only consists of 7 elements (Mon-Sun). [7] means you are selecting the 8th cell in that row, which doesn't exist (JavaScript arrays are 0-based - the first element starts from 0).
So now what you want to do is count the number of table cells from the start of the table, inclusive of those in the first row.
Also, if you do it this way, the table cell you are trying to reference may not been created by the loop yet. You should set the red color outside of the two loops, or set a class to the cell, and use CSS to style the background color.
Snippet:
var currentTime = new Date()
var month = currentTime.getMonth() + 1
var day = currentTime.getDate()
var year = currentTime.getFullYear()
var hour = currentTime.getHours()
var min = currentTime.getMinutes()
//document.write(month + "/" + day + "/" + year)
var test = currentTime.getDay();
var day = currentTime.getDate() + 1;
var month = currentTime.getMonth();
var full_year = currentTime.getFullYear();
var total_days = (daysInMonth(month, full_year));
var d = 1;
function daysInMonth(month, year) {
return new Date(year, month, 0).getDate();
}
var temp = test + 1;
for (i = 0; i < 5; i++) {
var table = document.getElementById("calendar");
var row = table.insertRow(-1);
row.setAttribute("id", "rowClassName"+1, 0);
for (c = 1; c < 8; c++) {
if (d < test) {
var newCell = row.insertCell(-1);
newCell.innerHTML = '0';
d++;
} else if ((temp - test) <= total_days) {
var newCell = row.insertCell(-1);
newCell.innerHTML = (temp - test);
temp = temp + 1;
if (temp == day) {
newCell.className = "current";
}
}
}
}
.current {
background-color: red;
}
<table id="calendar">
<tr>
<td>Mon</td>
<td>Tue</td>
<td>Wed</td>
<td>Thu</td>
<td>Fri</td>
<td>Sat</td>
<td>Sun</td>
</tr>
</table>

Related

How to execute value from <td> element

I'm not familiar with js, can you give me any tips. So basically I have calendar which generates dynamically. And I need to mark current day for example in "red". You can use my codepen for more detailed information.
When I try to execute value from this table I get the array which looks like this ~>
https://codepen.io/david_jons/pen/aPXeaK
<div id="calendar-container">
<div id="calendar-header">
<span id="calendar-month-year"></span>
</div>
<div id="calendar-dates">
</div>
</div>
JS:
window.onload = function(){
var d = new Date();
var month_name = ['January','February','March','April','May','June','July','August','September','October','November','December'];
var month = d.getMonth();
var year = d.getFullYear();
var first_date = month_name[month] + " " + 1 + " " + year;
var tmp = new Date(first_date).toDateString();
var first_day = tmp.substring(0, 3);
var day_name = ['Sun','Mon','Tue','Wed','Thu','Fri','Sat'];
var day_no = day_name.indexOf(first_day);
var days = new Date(year, month+1, 0).getDate();
var calendar = get_calendar(day_no, days);
document.getElementById("calendar-month-year").innerHTML = month_name[month]+" "+year;
document.getElementById("calendar-dates").appendChild(calendar);
var tr = document.getElementById("calendar-dates");
var tds = tr.getElementsByTagName("td");
var current_date = d.getDate();
}
function get_calendar(day_no, days){
var table = document.createElement('table');
var tr = document.createElement('tr');
//row for the day letters
for(var c=0; c<=6; c++){
var li = document.createElement('li');
li.innerHTML = "SMTWTFS"[c];
tr.appendChild(li);
}
table.appendChild(tr);
//create 2nd row
tr = document.createElement('tr');
var c;
for(c=0; c<=6; c++){
if(c == day_no){
break;
}
var td = document.createElement('td');
td.innerHTML = "";
tr.appendChild(td);
}
var count = 1;
for(; c<=6; c++){
var td = document.createElement('td');
td.innerHTML = count;
count++;
tr.appendChild(td);
}
table.appendChild(tr);
//rest of the date rows
for(var r=3; r<=7; r++){
tr = document.createElement('tr');
for(var c=0; c<=6; c++){
if(count > days){
table.appendChild(tr);
return table;
}
var td = document.createElement('td');
td.innerHTML = count;
count++;
tr.appendChild(td);
}
table.appendChild(tr);
}
return table;
}
You can iterate over an HTML collection using Array.prototype.filter called with the HTML collection as a context.
The following snippet may be of some help:
var cells = document.getElementById("calendar-dates").getElementsByTagName("td");
var current_date = d.getDate();
var matchingElement = Array.prototype.filter.call(cells, function(cell) {
return +current_date === +cell.textContent;
})[0];
matchingElement.style.backgroundColor = 'red';
Basically you got to check if the current date date that you are pasting is the same as today (new Date()).
function isToday(day, month, year){
const today = new Date();
return today.getDate() === day && today.getMonth() === month && today.getFullYear()===year;
}
https://codepen.io/kwiniarski97/pen/magPKV?editors=1111
it can be done in other ways this is just one

How to get week numbers in month in Javascript?

I need to generate year calendar with week numbers which should look like this image:
However it is not trivial to get week numbers in each month so they wouldn't overlap or be missing. I am using weekCount() function from this SO question. And for displaying calendar I have written this code:
var year = parseInt($(this).text());
var months = {1:'leden',2:'únor',3:'březen',4:'duben',5:'květen',6:'červen',7:'červenec',8:'srpen',9:'září',10:'říjen',11:'listopad',12:'prosinec'};
var calendar = $('<div id="summary_search_form_menu"></div>');
calendar.offset({top:$(this).offset().top + $(this).height() + 10}).css({right: '0px'});
var cur_week = 0;
for (var i=1;i<=12;i++) {
var row = $('<div class="row"></div>');
row.append('<div class="month button dark-blue">'+months[i]+'</div>');
var week_count = weekCount(year, i);
for (var week=1;week<week_count;week++) {
cur_week++;
row.append('<div class="week button blue">'+cur_week+'</div>');
}
calendar.append(row);
}
$('body').append(calendar);
Any way how to display week numbers correctly ?
OK, I have finally solved this on my own. In case somebody would find it helpful, I post my final code which works as I needed.
function weekCount(year, month_number) {
var firstOfMonth = new Date(year, month_number-1, 1);
var lastOfMonth = new Date(year, month_number, 0);
var used = firstOfMonth.getDay() + lastOfMonth.getDate();
return Math.ceil( used / 7);
}
Date.prototype.getWeekNumber = function(){
var d = new Date(+this);
d.setHours(0,0,0);
d.setDate(d.getDate()+4-(d.getDay()||7));
return Math.ceil((((d-new Date(d.getFullYear(),0,1))/8.64e7)+1)/7);
};
var year = parseInt($(this).text());
var months = {1:'leden',2:'únor',3:'březen',4:'duben',5:'květen',6:'červen',7:'červenec',8:'srpen',9:'září',10:'říjen',11:'listopad',12:'prosinec'};
var calendar = $('<div id="summary_search_form_menu"></div>');
calendar.offset({top:$(this).offset().top + $(this).height() + 10}).css({right: '15px'});
var cur_week = 0;
var col1 = $('<div id="summary_search_form_menu_col1"></div>');
var col2 = $('<div id="summary_search_form_menu_col2"></div>');
calendar.append(col1);
calendar.append(col2);
var col2_table = $('<div id="summary_search_form_menu_col2_table"></div>');
col2.append(col2_table);
for (var i=1;i<=12;i++) {
var row = $('<div class="row"></div>');
col1.append('<div class="month button dark-blue">'+months[i]+'</div>');
var week_count = weekCount(year, i);
var d = new Date(year, i-1, 1, 0,0,0);
var first_week_in_month = d.getWeekNumber();
for (var week=(cur_week == first_week_in_month ? 2 : 1);week<=week_count;week++) {
cur_week++;
row.append('<div class="week button blue">'+cur_week+'</div>');
}
col2_table.append(row);
}
$('body').append(calendar);

Javascript: Create new Object doesn't work if is in another files

I'm building a small calendar with OOP, which is work but whenever I call my new Calendar() in another js file, it complain it Calendar isn't defined and I can't understand why is that.
Some code:
Index.html
<html>
<head>
<script src="monthData.js"></script>
<script src="month.js"></script>
</head>
<body>
<table>
<tbody id="table">
<tr id="year"></tr>
<tr>
<td id="prev-month"> Prev</td>
<td id="month"></td>
<td id="next-month"> Next</td>
</tr>
<tr id="days-of-week"></tr>
</tbody>
</table>
<script src="currentCal.js"></script>
</body>
</html>
month.js
window.wca = {}
};
(function() {
wca.today = new Date();
wca.currentYear = wca.today.getFullYear();
wca.currentMonth = wca.today.getMonth();
function Calendar(year, month){
this.year = wca.currentYear;
this.month = wca.currentMonth;
}
wca.Calendar.prototype.createCalendar = function(){
wca.currentDayOfWeek = wca.today.getDay();
wca.firstDay = new Date(wca.currentYear, wca.currentMonth, 1); //first day of current month
wca.firstDayOfWeek = daysLabel[wca.firstDay.getDay() - 1]; // first dayOfTheWeek of current month
wca.firstDayOfWeekNumber = wca.firstDay.getDay();
wca.showMonth = monthNamesArray[wca.currentMonth]; //current month string
wca.showWeekDay = daysLabel[wca.currentDayOfWeek - 1]; //current day of the week
wca.totDayInMonth = daysPerMonth[wca.currentMonth]; //how many days are in the current month
//Leap years
if (wca.currentMonth == 1) {
if((wca.currentYear % 4 == 0 && wca.currentYear % 100 != 0) || wca.currentYear % 400 == 0){
wca.totDayInMonth = 29;
}
}
var Htmltable = document.getElementById('table');
var year = document.getElementById('year');
var month = document.getElementById('month');
var daysOfWeek = document.getElementById('days-of-week');
year.innerHTML = '<td>'+ wca.currentYear +'</td>';
month.innerHTML = '<td>'+ wca.showMonth +'</td>';
for(i = 0; i < daysLabel.length; i++)
daysOfWeek.innerHTML = daysOfWeek.innerHTML + '<td>'+ daysLabel[i] +'</td>';
var html = '';
var day = 1;
for(i = 1; i <= 6; i++){ //6 rows
html += '<tr id="days-row">';
for(j = 1; j <= 7; j++){ //7 coloumns
html += '<td>';
if(day <= wca.totDayInMonth && (i > 1 || j >= wca.firstDayOfWeekNumber )){
html += day;
day++;
} else {
html += ' ';
}
html += '</td>';
}
if(day >= wca.totDayInMonth){
break;
}
html += '</tr>';
}
Htmltable.innerHTML += html + '</tr>';
}
})();
currentCal.js
window.wca = {};
(function() {
var currentCal = new Calendar(wca.currentYear, wca.currentMonth);
currentCal.createCalendar();
})();
So if I put what is in currentCal in month.js everything works, otherwise I get the undefined error.
Why is that?
Since in my Html i'm linking before month.js and then currentCal.js I thought it should already knows what Calendar(); is.
It looks like a scope problem. Can you try putting "var wca = {};" in month.js and just using it (without window.wca = {};) in currentCal.js?
Edit: He was calling "new Calendar" which was inside a closure in the other file so it was out of the global scope for the other file. He had to remove the closure "(function() {...})" to declare this variables on a global scope and be accesible from the other file.

JQuery dynamic table totals

I have this table:
The table has data from every month, but only shows the selected date.
So, the question is: How can I do a total of Actual Hours and Extra Hours per month (visible data)?
This is how I build the table:
var total = 0 ;
var actualTotal = 0 ;
var totalEH = 0;
var table=document.getElementById("fbody");
for (var i=0;i<user.length;i++)
{
var row=table.insertRow(-1);
var cellDate = row.insertCell(-1);
var cell2 = row.insertCell(-1);
var cell3 = row.insertCell(-1);
var cell4 = row.insertCell(-1);
var cell5 = row.insertCell(-1);
var cell7 = row.insertCell(-1);
var cell8 = row.insertCell(-1);
var startAM = user[i].reg_start_worktime_am;
var finishAM = user[i].reg_finish_worktime_am;
var startPM = user[i].reg_start_worktime_pm;
var finishPM = user[i].reg_finish_worktime_pm;
cellDate.innerHTML = user[i].reg_date;
cell2.innerHTML = user[i].reg_start_worktime_am;
cell3.innerHTML = user[i].reg_finish_worktime_am;
cell4.innerHTML = user[i].reg_start_worktime_pm;
cell5.innerHTML = user[i].reg_finish_worktime_pm;
cell7.innerHTML = calcTimeDifference(startAM.substring(0,2), startAM.substring(3,5), finishAM.substring(0,2), finishAM.substring(3,5), startPM.substring(0,2), startPM.substring(3,5), finishPM.substring(0,2), finishPM.substring(3,5));
cell8.innerHTML = (calcTimeDifference(startAM.substring(0,2), startAM.substring(3,5), finishAM.substring(0,2), finishAM.substring(3,5), startPM.substring(0,2), startPM.substring(3,5), finishPM.substring(0,2), finishPM.substring(3,5))-user[i].worktime_fullhours).toFixed(2);
if (cell8.innerHTML != "NaN")
{
totalEH += parseFloat((calcTimeDifference(startAM.substring(0,2), startAM.substring(3,5), finishAM.substring(0,2), finishAM.substring(3,5), startPM.substring(0,2), startPM.substring(3,5), finishPM.substring(0,2), finishPM.substring(3,5))-user[i].worktime_fullhours).toFixed(2));
total = (document.getElementById('box-table-a').rows.length-1)*user[0].worktime_fullhours;
actualTotal += parseFloat(calcTimeDifference(startAM.substring(0,2), startAM.substring(3,5), finishAM.substring(0,2), finishAM.substring(3,5), startPM.substring(0,2), startPM.substring(3,5), finishPM.substring(0,2), finishPM.substring(3,5)));
}
}
Thanks
EDIT:
Fixed:
var totalActuals = 0,
totalExtras = 0;
var totalHours = 0;
var trs = $("#fbody tr").each(function(e) {
if($(this).css('display')!='none')
if( $("td:eq(6)", this).text() != 'NaN' ) {
// alert("Horro! "+$("td:eq(6)", this).text() );
totalActuals += parseFloat( $("td:eq(5)", this).text() );
totalExtras += parseFloat($("td:eq(6)", this).text());
totalHours++;
}
});
totalHours = totalHours*8;
If I understand you correctly, your table will have some rows that are visible, and some will be hidden. And, you want to calculate the totals for rows that are visible.
You can do this by looping through only the visible rows and accessing the columns required for calculating the totals.
var totalActuals = 0;
var totalExtras = 0;
$.each($('table tr:visible',function() {
totalActuals += $(this).find(".actualHours").val();
totalExtras += $(this).find(".totalExtras").val();
};)
But this will also return the header row. So I think you should assign a class to the rows of the table, and use the class in the jquery selector - $('table .tableRow:visible')
Edit
Here I had assumed that you have given the class "actualHours", "totalExtras" to the div's in which the actual hours and total extra hours are shown in each row of the table. If you haven't done so, you can use -
totalActuals += $(this).find("td").eq(5).text();
totalActuals += $(this).find("td").eq(6).text();
This will select the 5th and 6th columns of the row.

Generate random numbers into a table

I am trying to generate random numbers as well as the current minute into a table.
How do I have the script write into the table?
getElementbyClass()?
d = new Date();
var random=Math.floor(Math.random()*60)
document.writeln(random);
var Minutes = d.getMinutes();
document.writeln(Minutes);
You could do something like:
var d = new Date();
var random= Math.floor(Math.random()*60);
var td1 = document.createElement("td");
td1.innerHTML = random;
var Minutes = d.getMinutes();
var td2 = document.createElement("td");
td2.innerHTML = random;
var table = document.getElementById("tblResult");
var row = document.createElement("tr");
row.appendChild(td1);
row.appendChild(td2);
table.appendChild(row);
And int the HTML:
<table id="tblResult">
<tr>
<td>Random</td>
<td>Minutes</td>
</tr>
</table>
Result can be seen in this fiddle
Is there a set number of rows/column in the table? Do you need to update the table in run-time (e.g. will you change the contents in the columns after the page has been loaded)?
If you just want to create a table with those values when loading the page, you could create your table in JavaScript:
var table = document.createElement('table'),
row,
minCol,
ranCol;
function addRow(minutes, rand) {
row = document.createElement('tr');
minCol = document.createElement('td');
ranCol = document.createElement('td');
minCol.innerHTML = minutes;
ranCol.innerHTML = rand;
row.appendChild(minCol);
row.appendChild(ranCol);
table.appendChild(row);
}
for (var i = 0; i < 10; i++) {
addRow((new Date()).getMinutes(), Math.floor(Math.random() * 60));
}
document.body.appendChild(table);
Note that this script must be after the <body> tag for it to work.
If you need to add rows after the page has loaded (e.g. the user clicks a button) just call addRow().

Categories

Resources