I'm supposed to build a calendar with only html, css, and javascript - no php, no jquery, nothing. I have been working on a bug in my code all weekend, but I don't know where it comes from. I don't know what to do. This is my code:
"use strict";
window.onload = init;
function init() {
var day = new Date();
var month = day.getMonth() + 1;
var year = day.getYear() + 1900;
var next = document.getElementById("next");
var previous = document.getElementById("previous");
next.onclick = nextMonth(month);
previous.onclick = previousMonth(month);
generateCalendar(month, year);
}
function generateCalendar(_month, _year) {
var table = document.getElementById("calendar");
var month = ["Januar", "Februar", "März", "April", "Mai", "Juni",
"Juli", "August", "September", "Oktober", "November", "Dezember"];
var day = ["Mo", "Di", "Mi", "Do", "Fr", "Sa", "So"];
var totaldays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
//determining the first day of the month
var firstday = new Date(_year, _month + 1, 1);
var start = firstday.getDay() + 1;
var end = totaldays[_month - 1]; //determining the length of the month
//February
if (end === totaldays[1]) {
//leap years (% means modulo)
if ((_year % 4 === 0 && _year % 100 !== 0) || _year % 400 === 0) {
end = 29;
}
}
//tale header
var head = month[_month - 1] + " " + _year;
var caption = table.createCaption();
caption.innerHTML = head;
var cell;
var row = table.insertRow(0);
for (var i = 0; i <= 6; i++) {
cell = row.insertCell(i);
cell.innerHTML = day[i];
}
var days = 1;
for (var i = 0; i <= 5; i++) { //started week in a month
row = table.insertRow(i + 1);
for (var j = 0; j <= 6; j++) { //days of a week
//regular calendar days
if (days <= end && (i > 0 || j >= start)) {
cell = row.insertCell(j);
cell.innerHTML = days;
days++;
} else {
//Days that aren't in the current month are shown as empty
cell = row.insertCell(j);
cell.innerHTML = "";
}
}
}
}
function nextMonth(_month) {
//contruction site
}
function previousMonth(_month) {
//construction site
}
My html file pretty much only has a <table> with the id named above.
So the calendar is in German obviously. As you can see (I hope) I tried to put the first day of the month on a field in an array from 0-6 for my week days which is very basic and it works!
Until December. The first day of December is supposed to be a Friday, but in my calendar it's on a Saturday and I have no idea why it jumps a day ahead. I debugged it and all I see is it skips a day in my array. I suppose it has something to do with the +1 at firstday.getDay() but I need that because all the Date functions are so inconsistent.
Related
How to can I make this sequence of date with tri-monthly. for eg. the input is `"2022-03-14" the input is dynamic it depends on the user input... I'm trying add + 10 days but isn't working
The output I want
[
"2022-03-24",
"2022-04-04",
"2022-04-14",
"2022-04-24",
"2022-05-04",
"2022-05-14",
"2022-05-24",
"2022-06-04",
"2022-06-14",
"2022-06-24",
]
My code output which is worng
[
"2022-03-24",
"2022-04-14",
"2022-04-24",
"2022-05-14",
"2022-05-24",
"2022-06-14",
"2022-06-24",
"2022-07-14",
"2022-07-24",
]
function createSchedule(date, count){
date = new Date(date);
let day = date.getDate();// Get day in given date
let k = 0;
let days = k? [day - 10, day , day + 10] : [day, day + 10, day- 10];
let result = [];
if(day > 10){
k = +0
}else{
if(day > 20 ){
k = +1
}else{
k= +2
}
}
for(let i = 0; i < count; i++){
k= 1-k;
date.setDate(days[k]);
// When date overflows into next month, take last day of month
if (date.getDate() !== days[k]) date.setDate(0);
if (!k) date.setMonth(date.getMonth() + 1);
result.push(date.toLocaleDateString("en-SE"));
}
return result
}
var dateRelease = new Date("03-14-2022");
var result = createSchedule(dateRelease, 9);
console.log(result)
A few issues in your attempt:
After let k = 0, the conditional operator on k? will always evaluate the first expression after ?, which is [day - 10, day , day + 10].
That array could have dates that are greater than 31 (day + 10)
That other array [day, day + 10, day- 10] is not sorted, but should be.
The constants +0 and +1 and +2 are OK, but it looks odd that you use the unary plus here. It could just be 0, 1 and 2.
The assignment k = 1 - k assumes you only have two entries in your days array, but you have three, so use modular arithmetic: k = (k + 1) % 3
Here is a correction:
function createSchedule(date, count) {
date = new Date(date);
let day = date.getDate();
let firstDay = 1 + (day - 1) % 10;
let days = [firstDay, firstDay + 10, firstDay + 20];
let k = days.indexOf(day);
let result = [];
for (let i = 0; i < count; i++) {
k = (k + 1) % 3;
date.setDate(days[k]);
// When date overflows into next month, take last day of month
if (date.getDate() !== days[k]) date.setDate(0);
if (!k) date.setMonth(date.getMonth() + 1);
result.push(date.toLocaleDateString("en-SE"));
}
return result;
}
var dateRelease = new Date("2022-03-14");
var result = createSchedule(dateRelease, 25);
console.log(result);
I'm taking a college course on JavaScript and am trying to follow one of the Chapter Hands-On Activites (using the textbook JavaScript: The Web Warrior Series By Sasha Vodnik and Don Gosselin in Chapter 7). It's supposed to create a calendar widget which isn't showing up. My end goal is to show the time elapsed from the date entered by the user.
This is the code provided in the textbook. I've copied it as exactly as is, double checked for errors, and used debugging tools. Google Chrome developer tools doesn't indicate any errors.
JS Code:
var dateObject = new Date();
function displayCalendar(whichMonth) {
var dateObject = new Date();
var date;
var dateToday = newDate();
var dayOfWeek;
var daysInMonth;
var dateCells;
var captionValue;
var month;
var year;
var monthArray = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "Decemeber"];
if (whichMonth === -1) {
dateObject.setMonth(dateObject.getMonth() - 1);
} else if (whichMonth === 1) {
dateObject.setMonth(dateObject.getMonth() + 1);
}
month = dateObject.getMonth();
year = dateObject.getFullYear();
dateObject.setDate(1);
dayOfWeek = dateObject.getDay();
captionValue = monthArray[month] + " " + year;
document.querySelector("#cal table caption").innerHTML = captionValue;
if(month === 0 || month === 2 || month === 4 || month === 6 || month === 7 || month === 9 || month === 11) { // Jan, Mar, May, Jul, Aug, Oct, Dec
daysInMonth = 31;
} else if (month === 1) { // Feb
if (year % 4 === 0) { //leap year test
if (year % 100 === 0) {
// year ending in 00 not a leap year unless
// divisible by 400
if (year % 400 === 0) {
daysInMonth = 29;
} else {
daysInMonth = 28;
}
} else {
daysInMonth = 29;
}
} else {
daysInMonth = 28;
}
} else { //Apr, Jun, Sep, Nov
daysInMonth = 30;
}
dateCells = document.getElementsByTagName("td");
for (var i = 0; i < dateCells.length; i++) {
// clear existing table dates
dateCells[i].innerHTML = "";
dateCells[i].className = "";
}
for (var i = dayOfWeek; i < daysInMonth + dayOfWeek; i++) {
// add dates to days cells
dateCells[i].innerHTML = dateObject.getDate();
dateCells[i].className = "date";
if (dateToday < dateObject) {
dateCells[i].className = "futuredate";
}
date = dateObject.getDate() + 1;
dateObject.setDate(date);
dateObject.setMonth(dateObject.getMonth() -1);
// reset month to month shown
document.getElementById("cal").style.display = "block";
// display calendar if it's not already visible
}
function selectDate(event) {
if (event === undefined) { //get caller element in IE8
event = window.event;
}
var callerElement = event.target || event.srcElement;
if (callerElement.innerHTML === "") {
//cell contains no date, so don't close the calendar
document.getElementById("cal").style.display = "block";
return false;
}
dateObject.setDate(callerElement.innerHTML);
var fullDateToday = new Date();
var dateToday = Date.UTC(fullDateToday.getFullYear(), fullDateToday.getMonth(), dateObject.getDate());
if (selectedDate <= dateToday) {
document.getElementById("cal").style.display = "block";
return false;
}
document.getElementById("tripDate").value = dateObject.toLocaleDateString();
}
function CreateEventListeners() {
var dateField = document.getElementById("tripDate");
if (dateField.addEventListener) {
dateField.addEventListener("click", displayCalendar, false);
} else if (dateField.attachEvent) {
dateField.attachEvent("onclick", displayCalendar);
}
if (window.addEventListener) {
window.addEventListener("load", createEventListeners, false);
} else if (window.attachEvent) {
window.attachEvent("onload", createEventListeners);
}
var dateCells = document.getElementsByTagName("td");
if (dateCells[0].addEventListener) {
for (var i = 0; i < dateCells.length; i++) {
dateCells[i].addEventListener("click", selectDate, false);
}
} else if (dateCells[0].attachEvent) {
for (var i = 0; i < dateCells.length; i++) {
dateCells[i].attachEvent("onclick", selectDate);
}
}
}
I have this function, that gives the user the correct amount of buttons depending on the month. So if the user loads the page, Februari will show up, and 28 buttons aswell. If the user changes to March, there will be 31 buttons. The user is able to click on the button, and the corresponding button will be added to the mySql database. So if the user chooses Februari, and the button 3, the value in the database will say 2018-02-03. The problem is, and what I need help with, is if the user changes the month on the page, it does not change the value in the database. The month value in the database is always the current month of the year. Tried different solutions but nothing works. The value of the month is in a h2 with the id "displayingMonth".
Function:
function drawTable(daysInMonth) {
var cellsToDraw = daysInMonth;
var table = document.getElementById("table");
var dateObj = new Date();
var month = dateObj.getMonth()+1;
var day = dateObj.getDate();
var year = dateObj.getFullYear();
newdate = year + "-" + month;
table.innerHTML = "";
for (r = 0; r < (daysInMonth / 7); r++) {
var newRow = document.createElement("tr");
table.appendChild(newRow);
for (c = 0; c < 31 && cellsToDraw > 0; c++) {
v = c +1;
//var newCell = document.createElement("td");
var newCell = document.createElement("input");
newCell.setAttribute("type", "radio");
newCell.setAttribute("name", "day");
newCell.setAttribute("value", newdate + "-" + v);
newRow.appendChild(newCell);
newCell.innerHTML =
cellsToDraw--;
}
}
}
to get the month displayed:
function daysInMonth(month, year) {
var days;
switch (month) {
case 1:
var leapYear = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
days = leapYear ? 29 : 28;
break;
case 3:
case 5:
case 8:
case 10:
days = 30;
break;
default:
days = 31;
}
return days;
}
To get the month:
window.onload = function() {
var month = new Date();
var index = month.getMonth();
var months = ["Januari", "Februari", "March", "April", "May", "June", "July", "Augusti", "September", "October", "November", "December"];
document.getElementById("todayField").innerHTML = months[month.getMonth()];
// Draws a table for the current month
drawTable(daysInMonth(index, 2018));
}
to get the next month
function next() {
var months = ["Januari", "Februari", "March", "April", "May", "June", "July", "Augusti", "September", "October", "November", "December"];
var weeks = ["Sunday", "Monday", "Tuseday", "Wednesday", "Thursday", "Friday", "Saturday"];
var nextMonth = index + 1 > 11 ? 0 : index + 1;
index = nextMonth;
document.getElementById("displayingMonth").innerHTML = months[nextMonth];
drawTable(daysInMonth(index, 2018));
}
HTML
<input id="newCell"type="hidden"name="day" value="">
All help is appriciated!
Alright, some slight adjustments here. This is highly specific to your code, so bear with the changes. The issue lies with the use of var dateObj = new Date(); and then pulling the month from it to add to each 'day' radio input a user chooses.
Each input is using the 'current date' for that, and thus pulls the wrong month for what its passing.
Instead, you'll need to push the selected month date into the drawTable function, so it can build properly from that. And example of such would be:
function drawTable(daysInMonth,selectedMonth) {
...
// selectedMonth has the proper index for the Date() function
// setting 2018 here, because your code isnt inc years yet
var dateObj = new Date(2018, selectedMonth, 1, 0, 0, 0, 0);
...
}
window.onload = function() {
...
drawTable(daysInMonth(index, 2018), month.getMonth());
}
function next() {
// you may want to deal with looping to the next year here too
...
drawTable(daysInMonth(index, 2018), nextMonth);// nextMonth holds proper index
}
I think I should note that this passes the "month index", because new Date() takes a month index of 0 - 11. So passing it straight from a .getMonth() is the most compatible (no need to add +1 or -1 to them).
Here is also full chunk of your code with many changes applied to reduce some complexity and allow for years to roll as next month loops. There are a lot of changes in here, but mainly, it relies a lot more on the Date() object. No need for the daysInMonth() function you have.
// set as global
var showDate = new Date();
var months = ["Januari", "Februari", "March", "April", "May", "June",
"July", "Augusti", "September", "October", "November", "December"];
var weeks = ["Sunday","Monday","Tuseday","Wednesday","Thursday","Friday","Saturday"];
function drawTable(forDate) {
var daysInMonth = new Date(forDate.getFullYear(),forDate.getMonth()+1,0).getDate();
// ^^^ magic way to get number of days!
var cellsToDraw = daysInMonth;
// for a zero-padded non-index YYYY-MM prefix value:
var newdate = forDate.getFullYear() +"-"+ ("0"+ (forDate.getMonth() + 1)).slice(-2);
var table = document.getElementById("table");
table.innerHTML = "";
for (var r = 0; r < (daysInMonth / 7); r++) {
var newRow = document.createElement("tr");
table.appendChild(newRow);
for (var c = 0; c < 31 && cellsToDraw > 0; c++) {
// for a zero-padded day to tack onto newdate
var day = ("0" + (c + 1)).slice(-2);
var newCell = document.createElement("input");
newCell.setAttribute("type", "radio");
newCell.setAttribute("name", "day");
newCell.setAttribute("value", newdate + "-" + day);// makes YYYY-MM-DD
newRow.appendChild(newCell);
newCell.innerHTML = '';
cellsToDraw--;
}
}
}
window.onload = function() {
document.getElementById("todayField").innerHTML = months[showDate.getMonth()];
drawTable( showDate );
};
function next() {
if (showDate.getMonth() == 11) {
showDate.setMonth( 0 );
showDate.setFullYear( showDate.getFullYear()+1 );
} else {
showDate.setMonth( showDate.getMonth()+1 );
}
document.getElementById("displayingMonth").innerHTML = months[showDate.getMonth()];
drawTable( showDate );
}
function prev() {
if (showDate.getMonth() === 0) {
showDate.setMonth( 11 );
showDate.setFullYear( showDate.getFullYear()-1 );
} else {
showDate.setMonth( showDate.getMonth()-1 );
}
document.getElementById("displayingMonth").innerHTML = months[showDate.getMonth()];
drawTable( showDate );
}
I am trying to code a function that when given a past date will calculate years, months, and days since then in a trickle down remainder fashion. As in "2 years, 1 month, and 3 days.", not total time in all 3 formats (2 years = 24 months = 730 days).
Code:
//Function to tell years/months/days since birthday to today
var ageID = function(date){
var nowDate = new Date();
//current date
var nowYear = nowDate.getFullYear();
var nowMonth = nowDate.getMonth();
var nowDay = nowDate.getDay();
//input birthday
var year = date[0];
var month = date[1];
var day = date[2];
var longMonth = [1, 3, 5, 7, 8, 10, 12];
var shortMonth = [4, 6, 9, 11];
var febMonth = [2];
var specfMonth = 0;
//finding month that corresponds to 28, 30, or 31 days in length
for (i = 0; i < longMonth.length; i++){
if (longMonth[i] === month){
specfMonth = 31;
}
}
for (i = 0; i < shortMonth.length; i++){
if (shortMonth[i] === month){
specfMonth = 30;
}
}
for (i = 0; i < febMonth.length; i++){
if (febMonth[i] === month){
specfMonth = 28;
}
}
//Reduced input and current date
var redYear = nowYear - year - 1;
var redMonth = 0;
var redDay = 0;
//The following 2 if/else are to produce positive output instead of neg dates.
if (nowMonth < month){
redMonth = month - nowMonth;
}else{
redMonth = nowMonth - month;
}
if (nowDay < day){
redDay = day - nowDay;
}else{
redDay= nowDay - day;
}
var adjMonth = 12 - redMonth;
var adjDay = specfMonth - redDay;
if (redYear < 1){
return adjMonth + " months, " + adjDay + " days ago.";
}else{
return redYear + " years, " + adjMonth + " months, " + adjDay + " days ago.";
}
};
console.log(ageID([2001, 9, 11]));
Output:
13 years, 10 months, 20 days ago.
However, the accurate output would be:
13 years, 10 months, 30 days ago.
Your issue is : var nowDay = nowDate.getDay();
You should use: nowDate = nowDate.getDate(); instead.
getDay() return the number of day in the week.
Monday is "1", Tuesday is "2", etc.
I have a function that works out the past 3 months and displays the name by using an array.
I've just realised that when the new year comes round, for January, February & March, it won't be able to get the correct month.
I want to be able to do this without having to add in a hack (which is the only way I've seen to do this)
function getMonths()
{
var today = new Date();
var month = 0;
var currMonth = month-3;
var monthArray = new Array("January","February","March","April","May","June",
"July","August","September","October","November","December");
var menuMonths = new Array();
var count = 4;
var buffer = 10;
while(count >0)
{
var month = monthArray[currMonth];
alert(currMonth);
menuMonths.push(month);
currMonth = currMonth +1;
count = count -1;
}
return menuMonths;
}
Modulus is your friend. Try:
function getMonths()
{
var today = new Date();
var month = 1;
var monthArray = new Array("January","February","March","April","May","June",
"July","August","September","October","November","December");
var menuMonths = new Array();
for(var count = 3; count >= 0; count--)
menuMonths.push(monthArray[((12 + month - count) % 12)]);
return menuMonths;
}
alert(getMonths());
This little addition to your while-loop will ensure that currMonth is always a valid index of your monthArray:
while(count >0)
{
if (currMonth < 0)
currMonth += 12;
if (currMonth >=12 )
currMonth -= 12;
var month = monthArray[currMonth];
menuMonths.push(month);
currMonth = currMonth +1;
count = count -1;
}
working example: http://jsfiddle.net/RWhN4/
This is a bit hackish, but it should do what you want.
To figure out which month was 3 months ago you could do the following:
var d = new Date();
d.setMonth(d.getMonth() - 3);
var monthIndex = d.getMonth() //(0-11)
Let standard javascript methods do the calculations for you.
Here is your function updated to use the javascript methods to do the calculations for you:
function getMonths() {
var date = new Date();
//subttract 3 months
date.setMonth(0 - 3);
var monthArray = new Array("January", "February", "March", "April", "May", "June",
"July", "August", "September", "October", "November", "December");
var menuMonths = new Array();
var count = 4;
var buffer = 10;
while (count > 0) {
var month = monthArray[date.getMonth()];
alert(month);
menuMonths.push(month);
date.setMonth(date.getMonth() + 1);
count -= 1;
}
return menuMonths;
}
I did something similar to what you guys did, but I did it for the Trailing Twelve Months basically, in it's form format I used the following code:
$(".monthly_usage").val('');
var monthArray = new Array("January","February","March","April","May","June","July","August","September","October","November","December");
var today = new Date();
var month = today.getMonth();
var year = today.getFullYear();
var output = "Enter Trailing Twelve Months Usage<br/><center><table border=1 cellpadding=10 cellspacing=0><thead><th>Month - Year</th><th>Usage</th></thead><tbody>";
for(var i = 0; i < 12; i++) {
output += "<tr><td>" + monthArray[today.getMonth()] + " " + year + "</td><td><input type=text class=monthly_usage name=usage[]></td></tr>";
var month = today.setMonth(today.getMonth() - 1);
var year = today.getFullYear();
}
output += "</tbody></table>"+
"<button id=submit_ttm>Submit Monthly Usage</button></center>";
return output;
function lastMonths(count,month,order) {
var arr = [];
//defaults
month = typeof month !== 'undefined' ? month : new Date().getMonth();
count = typeof count !== 'undefined' ? count : 3;
order = typeof order !== 'undefined' ? order : "asc";
while (count-- > 0) {
month = (--month < 0) ? 11 : month;
arr.push(["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"][month]);
}
return ( order === "asc" ) ? arr.reverse() : arr;
}
the function has defaults for the number of months to show, the start month, and the order
demo