This is a simple calendar code. And my javascript and CSS codes are literally appearing beside my calendar. Does anyone know why something like this happens? I was using an online html/css/js editor and when I made my code into an HTML file, this happened. I've spent hours looking for a fault, but I can't find anything that is problematic.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>ICSI301 - Lab 2</title>
</head>
<body>
<h1 id="year">2021 School Calendar</h1>
<div class="calendar">
</div>
</body>
</html>
<script>
var monthNamesRy = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var daysOfTheWeekRy = ["S", "M", "T", "W", "T", "F", "S"]
var d = new Date();
var year = d.getFullYear();
var thisMonth = d.getMonth();
var today = d.getDate();
//var nthday = d.getDay();
var daysOfTheMonthDiv = document.querySelectorAll(".daysOfTheMonth");
for (var month = 0; month < 12; month++) {
createCalendar(month);
}
function createCalendar(month) {
var monthDiv = createMonthHeader(month);
var firstDayOfTheMonth = getFirstDayOfTheMonth(year, month);
var daysinmonth = daysInMonth(year, month)
var counter = 0, order = 6;
for (var i = 0; i < firstDayOfTheMonth + 7; i++) {
order++;
createDay(month, " ", order, monthDiv);
}
for (var i = firstDayOfTheMonth; i < daysInMonth(year, month) + firstDayOfTheMonth; i++) {
counter++;
order++;
createDay(month, counter, order, monthDiv);
}
for (var i = firstDayOfTheMonth + daysinmonth; i < 6 * 7; i++) {
order++;
createDay(month, " ", order, monthDiv);
}
}
function createDay(month, counter, order, monthDiv) {
var day = document.createElement("div");
if (month == thisMonth && counter == today) {
day.setAttribute("class", "to day");
} else {
day.setAttribute("class", "day");
}
day.setAttribute("style", "order:" + order);
day.innerHTML = counter;
monthDiv.appendChild(day);
}
function createMonthHeader(month) {
var calendar = document.querySelector(".calendar");
var monthDiv = document.createElement("div");
monthDiv.setAttribute("class", "month");
calendar.appendChild(monthDiv);
var h4 = document.createElement("h4");
h4.innerHTML = monthNamesRy[month];
monthDiv.appendChild(h4);
for (var i = 0; i < 7; i++) {
var hday = document.createElement("div");
hday.setAttribute("class", "day OfWeek");
hday.setAttribute("style", "order:" + i);
hday.innerHTML = daysOfTheWeekRy[i].toUpperCase();
monthDiv.appendChild(hday);
}
return monthDiv;
}
function daysInMonth(year, month) {
return new Date(year, month + 1, 0).getDate();
}
function getMonthName(month) {
return monthNamesRy[month];
}
function getDayName(day) {
return daysOfTheWeekRy[day];
}
function getFirstDayOfTheMonth(y, m) {
var firstDay = new Date(y, m, 1);
return firstDay.getDay();
}
function getLastDayOfTheMonth(y, m) {
var lastDay = new Date(y, m + 1, 0);
return lastDay.getDay();
}
</script>
<style>
body * {
margin: 0;
padding: 0;
font-family: "Times New Roman";
}
.calendar, section {
max-width: 50rem;
}
.day {
width: 1.5em;
height: 1.5em;
}
.day:nth-of-type(-n+7) {
background-color: #7CFC00;
}
.to.day {
background: aquamarine;
}
.month {
width: calc(1.5em * 8);
padding: 1em;
}
h4 {
font-size: 1em;
text-transform: uppercase;
}
h1#year {
font-size: 3em;
height: 29px;
font-weight: normal;
padding: 1em 1em .5em 1em;
margin-bottom: .5em;
color: #006400;
}
body, body * {
display: flex;
justify-content: center;
}
h4 {
justify-content: center;
flex: 1 0 100%;
}
h1 {
justify-content: center;
align-self: stretch;
}
.calendar, .month {
flex-wrap: wrap;
}
.month {
align-items: flex-start;
border: 3px double black;
margin: 5px;
}
.day {
border: 1px solid black;
align-items: center;
justify-content: center;
}
</style>
Move the script and style to the head
change this
var daysOfTheMonthDiv = document.querySelectorAll(".daysOfTheMonth");
for (var month = 0; month < 12; month++) {
createCalendar(month);
}
to
window.addEventListener("load",function() { // wait for page load
var daysOfTheMonthDiv = document.querySelectorAll(".daysOfTheMonth");
for (var month = 0; month < 12; month++) {
createCalendar(month);
}
})
As Chris noticed, you have a very disruptive style entry
body,
body * {
display: flex;
justify-content: center;
}
I moved that to just under the other body style and now had to add
script,
style {
display: none
}
to stop the disruption
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>ICSI301 - Lab 2</title>
<script>
var monthNamesRy = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
var daysOfTheWeekRy = ["S", "M", "T", "W", "T", "F", "S"]
var d = new Date();
var year = d.getFullYear();
var thisMonth = d.getMonth();
var today = d.getDate();
//var nthday = d.getDay();
window.addEventListener("load", function() {
var daysOfTheMonthDiv = document.querySelectorAll(".daysOfTheMonth");
for (var month = 0; month < 12; month++) {
createCalendar(month);
}
});
function createCalendar(month) {
var monthDiv = createMonthHeader(month);
var firstDayOfTheMonth = getFirstDayOfTheMonth(year, month);
var daysinmonth = daysInMonth(year, month)
var counter = 0,
order = 6;
for (var i = 0; i < firstDayOfTheMonth + 7; i++) {
order++;
createDay(month, " ", order, monthDiv);
}
for (var i = firstDayOfTheMonth; i < daysInMonth(year, month) + firstDayOfTheMonth; i++) {
counter++;
order++;
createDay(month, counter, order, monthDiv);
}
for (var i = firstDayOfTheMonth + daysinmonth; i < 6 * 7; i++) {
order++;
createDay(month, " ", order, monthDiv);
}
}
function createDay(month, counter, order, monthDiv) {
var day = document.createElement("div");
if (month == thisMonth && counter == today) {
day.setAttribute("class", "to day");
} else {
day.setAttribute("class", "day");
}
day.setAttribute("style", "order:" + order);
day.innerHTML = counter;
monthDiv.appendChild(day);
}
function createMonthHeader(month) {
var calendar = document.querySelector(".calendar");
var monthDiv = document.createElement("div");
monthDiv.setAttribute("class", "month");
calendar.appendChild(monthDiv);
var h4 = document.createElement("h4");
h4.innerHTML = monthNamesRy[month];
monthDiv.appendChild(h4);
for (var i = 0; i < 7; i++) {
var hday = document.createElement("div");
hday.setAttribute("class", "day OfWeek");
hday.setAttribute("style", "order:" + i);
hday.innerHTML = daysOfTheWeekRy[i].toUpperCase();
monthDiv.appendChild(hday);
}
return monthDiv;
}
function daysInMonth(year, month) {
return new Date(year, month + 1, 0).getDate();
}
function getMonthName(month) {
return monthNamesRy[month];
}
function getDayName(day) {
return daysOfTheWeekRy[day];
}
function getFirstDayOfTheMonth(y, m) {
var firstDay = new Date(y, m, 1);
return firstDay.getDay();
}
function getLastDayOfTheMonth(y, m) {
var lastDay = new Date(y, m + 1, 0);
return lastDay.getDay();
}
</script>
<style>
body * {
margin: 0;
padding: 0;
font-family: "Times New Roman";
}
body,
body * {
display: flex;
justify-content: center;
}
script,
style {
display: none
}
.calendar,
section {
max-width: 50rem;
}
.day {
width: 1.5em;
height: 1.5em;
}
.day:nth-of-type(-n+7) {
background-color: #7CFC00;
}
.to.day {
background: aquamarine;
}
.month {
width: calc(1.5em * 8);
padding: 1em;
}
h4 {
font-size: 1em;
text-transform: uppercase;
}
h1#year {
font-size: 3em;
height: 29px;
font-weight: normal;
padding: 1em 1em .5em 1em;
margin-bottom: .5em;
color: #006400;
}
h4 {
justify-content: center;
flex: 1 0 100%;
}
h1 {
justify-content: center;
align-self: stretch;
}
.calendar,
.month {
flex-wrap: wrap;
}
.month {
align-items: flex-start;
border: 3px double black;
margin: 5px;
}
.day {
border: 1px solid black;
align-items: center;
justify-content: center;
}
</style>
</head>
<body>
<h1 id="year">2021 School Calendar</h1>
<div class="calendar"></div>
</body>
</html>
This is more interesting than it seems at first. It's possible to solve the problem by moving the script to the head, but the content of script tags and style tags do not normally display in browsers. The reason they are displaying in this case is that the css is forcing the content of these tags to display.
The browser's css has
script {
display: none;
}
And this is overridden by these lines:
body, body * {
display: flex;
justify-content: center;
}
Browsers pull the invalidly-positioned tags into the body when building the DOM, and then apply this display attribute... which means the code runs, but it also shows on the page.
It can be fixed by moving the script tag, but that doesn't actually address the real cause of the problem
Related
The javascript code for cookie acceptance is ok but not working, instead I find this console error :
The use of drawWindow method of CanvasRenderingContext2D is deprecated. Use the tabs.captureTab API for extensions instead https://developer.mozilla.org/fr/docs/Mozilla/Add-ons/WebExtensions/API/tabs/captureTab pagedata-script.js:1:12465
I don't know where or why it comes from but my javascript code does not run.
If someone has an idea.
Here is the code below :
HTML
<div id="consent-popup" class="hidden dark">
<img src="_images/cookie.png"/>
<p>By using this site, you agree to our Terms of Service.<br>
Please <a id="accept" href="#">Accept</a> before using the site.
</p>
</div>
CSS
#consent-popup {
position: fixed;
display: inline-flex;
bottom: 3.5rem;
right: 0;
padding: 25px 5% 25px 25px;
width: 40vw;
box-shadow: -2px 5px 10px 5px #19233e;
background-color: #FFFFFF;
transition: all 1s ease;
}
#consent-popup.hidden {
transform: translate(100%, 0);
opacity: 0;
}
#consent-popup > img {
margin: 0 25px 0 0;
width: 50px;
height: 50px;
}
#consent-popup > p {
margin: 0;
font-family: ArialLight;
font-size: 1rem;
color: #000000;
text-align: left;
}
#consent-popup > p > a {
color: #dbdce8;
}
Javascript
//accept_cookies.js
function getCookie(cname) {
let name = cname + "=";
let ca = document.cookie.split(';');
for(let i = 0; i < ca.length; i++) {
let c = ca[i];
while (c.charAt(0) == ' ') {
c = c.substring(1);
}
if (c.indexOf(name) == 0) {
return c.substring(name.length, c.length);
}
}
return "";
}
function setCookie(cname, cvalue, exdays){
const d = new Date();
d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
let expires = "expires="+d.toUTCString();
document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/;SameSite=None;secure=" + true + ";";
}
function isAccept(cname){
//console.log(getCookie(cname));
if(getCookie(cname) == "true"){
return true;
}
else{
return false;
}
}
window.onload = () => {
function acceptFn(){
setCookie("abc_consent", true, 7);
consentPopup.classList.add('hidden');
}
const consentPopup = document.getElementById('consent-popup');
const acceptBtn = document.getElementById('accept');
acceptBtn.addEventListener('click', acceptFn);
if (!isAccept("bdc_consent")) {
setTimeout(() => {
consentPopup.classList.remove('hidden');
}, 2000);
}
};
The only external scripts are those of bootstrap and ajax googleapis:
"https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"
"https://cdn.jsdelivr.net/npm/bootstrap#5.0.2/dist/js/bootstrap.bundle.min.js"
Thanks.
There was a conflict with another javascript function in another file that used the window.onload = () => {} function
to create an animation.
So I remove it.
I'm building my own version of dynamic calendar with html css and js.
I got two issues:
Small issue: The buttons of changing to the next / previous month work as expected just after the second click.
Major issue: I can't understand how to fill last month's days on the right ("from the end") direction.
This is my code:
var days = ["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];
var monthnames = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
var today = new Date();
document.querySelector('#monthChoose').value = (today.getMonth()+1);
document.querySelector('#yearChoose').value = today.getFullYear();
// next and previous buttons
document.querySelector('#nextM').addEventListener('click', function() { document.querySelector('#monthChoose').value = operator++; buildCalendar()});
document.querySelector('#prevM').addEventListener('click', function() {document.querySelector('#monthChoose').value = operator--; buildCalendar()});
// fill days of the week as title
for (var i=0; i < days.length; i++) {
document.querySelector('#weekdays').innerHTML += '<li><span>'+days[i]+'</span></li>';
}
var operator = document.querySelector('#monthChoose').value; // this will later on the function to restrict input value
function buildCalendar() {
if (operator > 12) {operator = 1};
if (operator < 1) {operator = 12};
document.querySelector('#days').innerHTML = ' '; // clear records
var month = document.querySelector('#monthChoose').value;
var year = document.querySelector('#yearChoose').value;
document.querySelector('#monthName').textContent = monthnames[month-1]; // display month name
function daysInMonth (month, year) { return new Date(year, month, 0).getDate(); } // constructor to get number of days in chosen month
var lastMonthDays = daysInMonth(month-1, year);
var currentMonthDays = daysInMonth(month, year);
var currentFirstDay = new Date(year, month-1 ,1);
currentFirstDayNum = new Date(currentFirstDay).getDay();
var currentLastDay = new Date(year, month ,1);
currentLastDayNum = new Date(currentLastDay).getDay();
// fill last month's days
// this cause issue: i need to change the content direction so it will fill from the opposite direction
for (var i=0; i < currentFirstDayNum; i++) {
document.querySelector('#days').innerHTML += '<li style="opacity: 0.5;">'+(lastMonthDays-i)+'</li>';
}
// fill the current month days
for (var i=0; i < currentMonthDays; i++) {
document.querySelector('#days').innerHTML += '<li>'+(i+1)+'</li>';
}
// fill the rest of the board
var liLength = document.querySelectorAll('#days > li').length;
var restOfBoard=0;
while (liLength < 42) {
restOfBoard+=1;
document.querySelector('#days').innerHTML += '<li style="opacity: 0.5;">'+restOfBoard+'</li>';
liLength++
}
}
buildCalendar();
ul {list-style-type: none; text-align: center; margin: 0; padding: 0;}
#month {padding: 30px 0; width: 100%; }
#month li input:first-child { display: none; } /* hide input that control months - will change with js*/
#monthName { display: block; }
#monthName { font-size: 2em; }
#month button {width: auto; padding: 0; font-size: 2em;}
#month #prevM {float: left;}
#month #nextM {float: right;}
#weekdays { padding: 10px 0; background-color: gray; }
#weekdays li {
display: inline-block;
color: white;
width: calc(100% / 7);
}
#days { padding: 10px 0; }
#days li {
display: inline-block;
width: calc(100% / 7);
height: calc(400px / 5);
}
<ul id="month">
<li><button id="prevM">❮</button> </li>
<li><button id="nextM">❯</button> </li>
<li id="monthName"></li>
<li>
<input type="number" id="monthChoose" onchange="buildCalendar()" />
<input type="number" id="yearChoose" onchange="buildCalendar()"/>
</li>
</ul>
<ul id="weekdays"></ul>
<ul id="days"></ul>
Note: will glad to hear about things i could do better with this code...
EDIT:
The expected result for the second issue is the lest days of last month. If we take October 2019: the first day is Tuesday so on this week Monday should be the 30th and Sunday the 29th. Can't understand how to fill those days in this order dynamically.
So i finally managed to solve the second problem: Gave the lastMonthDays a unique class, sort it by it content, append the sorting elements, and then proceed with the rest of code.
For this i modified this script for my needs.
Thanks everybody.
The first problem is quite easy to solve by changing
document.querySelector('#monthChoose').value = operator++;
to
document.querySelector('#monthChoose').value = ++operator;
and changing
document.querySelector('#monthChoose').value = operator--;
to
document.querySelector('#monthChoose').value = --operator;
Putting ++ after operator means you don't increase the value of operator until afer you copy its value to the "monthChoose" element, where as putting it beforehand ensures you change its value first. And of course you later use the "monthChoose" element's value to determine the actual month to be displayed.
N.B. It's unclear why you actually need two values here at all - that is just a recipe for confusion. Since operator is global, you could just use that all the way through. Alternatively you could use the "monthChoose" element to maintain state if you want to reduce your use of global variables (which generally, you should).
Here's a demo:
var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var monthnames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
var today = new Date();
document.querySelector('#monthChoose').value = (today.getMonth() + 1);
document.querySelector('#yearChoose').value = today.getFullYear();
// next and previous buttons
document.querySelector('#nextM').addEventListener('click', function() {
document.querySelector('#monthChoose').value = ++operator;
buildCalendar()
});
document.querySelector('#prevM').addEventListener('click', function() {
document.querySelector('#monthChoose').value = --operator;
buildCalendar()
});
// fill days of the week as title
for (var i = 0; i < days.length; i++) {
document.querySelector('#weekdays').innerHTML += '<li><span>' + days[i] + '</span></li>';
}
var operator = document.querySelector('#monthChoose').value; // this will later on the function to restrict input value
function buildCalendar() {
if (operator > 12) {
operator = 1
};
if (operator < 1) {
operator = 12
};
document.querySelector('#days').innerHTML = ' '; // clear records
var month = document.querySelector('#monthChoose').value;
var year = document.querySelector('#yearChoose').value;
document.querySelector('#monthName').textContent = monthnames[month - 1]; // display month name
function daysInMonth(month, year) {
return new Date(year, month, 0).getDate();
} // constructor to get number of days in chosen month
var lastMonthDays = daysInMonth(month - 1, year);
var currentMonthDays = daysInMonth(month, year);
var currentFirstDay = new Date(year, month - 1, 1);
currentFirstDayNum = new Date(currentFirstDay).getDay();
var currentLastDay = new Date(year, month, 1);
currentLastDayNum = new Date(currentLastDay).getDay();
// fill last month's days
// this cause issue: i need to change the content direction so it will fill from the opposite direction
for (var i = 0; i < currentFirstDayNum; i++) {
document.querySelector('#days').innerHTML += '<li style="opacity: 0.5;">' + (lastMonthDays - i) + '</li>';
}
// fill the current month days
for (var i = 0; i < currentMonthDays; i++) {
document.querySelector('#days').innerHTML += '<li>' + (i + 1) + '</li>';
}
// fill the rest of the board
var liLength = document.querySelectorAll('#days > li').length;
var restOfBoard = 0;
while (liLength < 42) {
restOfBoard += 1;
document.querySelector('#days').innerHTML += '<li style="opacity: 0.5;">' + restOfBoard + '</li>';
liLength++
}
}
buildCalendar();
ul {
list-style-type: none;
text-align: center;
margin: 0;
padding: 0;
}
#month {
padding: 30px 0;
width: 100%;
}
#month li input:first-child {
display: none;
}
/* hide input that control months - will change with js*/
#monthName {
display: block;
}
#monthName {
font-size: 2em;
}
#month button {
width: auto;
padding: 0;
font-size: 2em;
}
#month #prevM {
float: left;
}
#month #nextM {
float: right;
}
#weekdays {
padding: 10px 0;
background-color: gray;
}
#weekdays li {
display: inline-block;
color: white;
width: calc(100% / 7);
}
#days {
padding: 10px 0;
}
#days li {
display: inline-block;
width: calc(100% / 7);
height: calc(400px / 5);
}
<ul id="month">
<li><button id="prevM">❮</button> </li>
<li><button id="nextM">❯</button> </li>
<li id="monthName"></li>
<li>
<input type="number" id="monthChoose" onchange="buildCalendar()" />
<input type="number" id="yearChoose" onchange="buildCalendar()" />
</li>
</ul>
<ul id="weekdays"></ul>
<ul id="days"></ul>
I'm afraid I don't understand precisely what you mean by your second problem. Perhaps you can give a clearer description / diagram showing what you want to happen and then I can update this answer?
when input yyyyMMdd format in textbox, that will automatically change to yyyy/MM/dd format for example: if your type 20180428, that will change to 2018/04/28
Utilizing built-in JavaScript functions such as parseInt to get the input element from a string to an integer, you are able to apply logic with helper functions to get to the date formatting you desire. e.g. if the day value is greater than 31, default return 1 instead to automatically guide the user from inputting a day more than 31
MDN JavaScript parseInt()
Afterwards, with the use of Regex, you can manipulate the user's initial data input (YYYYmmDD) to a format you want to change it to (YYYY/mm/DD).
Regex
I found an online tutorial outlining this very process below:
Auto-format Date Input by Envato Tuts+
var date = document.getElementById('date');
function checkValue(str, max) {
if (str.charAt(0) !== '0' || str == '00') {
var num = parseInt(str);
if (isNaN(num) || num <= 0 || num > max) num = 1;
str = num > parseInt(max.toString().charAt(0)) && num.toString().length == 1 ? '0' + num : num.toString();
};
return str;
};
date.addEventListener('input', function(e) {
this.type = 'text';
var input = this.value;
if (/\D\/$/.test(input)) input = input.substr(0, input.length - 3);
var values = input.split('/').map(function(v) {
return v.replace(/\D/g, '')
});
if (values[0]) values[0] = checkValue(values[0], 12);
if (values[1]) values[1] = checkValue(values[1], 31);
var output = values.map(function(v, i) {
return v.length == 2 && i < 2 ? v + ' / ' : v;
});
this.value = output.join('').substr(0, 14);
});
date.addEventListener('blur', function(e) {
this.type = 'text';
var input = this.value;
var values = input.split('/').map(function(v, i) {
return v.replace(/\D/g, '')
});
var output = '';
if (values.length == 3) {
var year = values[2].length !== 4 ? parseInt(values[2]) + 2000 : parseInt(values[2]);
var month = parseInt(values[0]) - 1;
var day = parseInt(values[1]);
var d = new Date(year, month, day);
if (!isNaN(d)) {
document.getElementById('result').innerText = d.toString();
var dates = [d.getMonth() + 1, d.getDate(), d.getFullYear()];
output = dates.map(function(v) {
v = v.toString();
return v.length == 1 ? '0' + v : v;
}).join(' / ');
};
};
this.value = output;
});
html {
box-sizing: border-box;
font-family: 'PT Sans', sans-serif;
-webkit-font-smoothing: antialiased;
}
*,
*:before,
*:after {
box-sizing: inherit;
}
body {
background-color: #f3f3f3;
}
form {
width: 100%;
max-width: 400px;
margin: 60px auto;
}
form input {
font-size: 30px;
padding: 0 20px;
border: 2px solid #ccc;
width: 100%;
color: #666;
line-height: 3;
border-radius: 7px;
font-family: 'PT Sans', sans-serif;
font-weight: bold;
}
form input:focus {
outline: 0;
}
form input.error {
border-color: #ff0000;
}
form label.error {
background-color: #ff0000;
color: #fff;
padding: 6px;
font-size: 11px;
}
label {
color: #999;
display: block;
margin-bottom: 10px;
text-transform: uppercase;
font-size: 18px;
font-weight: bold;
letter-spacing: 0.05em
}
form small {
color: #888;
font-size: 1em;
margin-top: 10px;
display: block;
align-self: ;
}
<form id="form" method="post" action="">
<label for="amount">Date</label>
<input type="text" id="date" />
<small>Enter date as Month / Day / Year</small>
</form>
So for my JavaScript course, our book walks us through the creation of a calendar. I thought I copied everything exactly as it appeared in the book, but maybe not. For some reason, blank cells are being inserted between the names of the days of the week. This obviously should not happen. What am i doing wrong?
This is my full script:
<html>
<head>
<title>Web 240 Assignment 3</title>
<style type="text/css">
table {
background: #ccc;
border: 1px solid #999;
padding: 3px;
}
#calendar_head {
background: red;
color: white;
font-weight: bold;
text-align: center;
}
.calendar_weekdays {
background: white;
border-bottom: 5px solid #ccc;
font-weight: bold;
}
.calendar_dates {
background: white;
padding: 5px 25px 10px 5px;
}
</style>
<script type="text/javascript">
function calendar(){
document.write('<table id="calendar_table">');
var calDate = new Date();
writeCalTitle(calDate);
writeDayNames();
writeCalDays(calDate);
document.write('</table>');
}
function writeCalTitle(calendarDay){
var monthName = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");
var thisMonth = calendarDay.getMonth();
var thisYear = calendarDay.getFullYear();
document.write("<tr>");
document.write('<th id="calendar_head" colspan="7">');
document.write(monthName[thisMonth] + " " + thisYear);
document.write('</th>');
document.write('</tr>');
}
function writeDayNames(){
var dayName = new Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat");
document.write('<tr>');
for(var i = 0; i < dayName.length; i++){
document.write('<th class="calendar_weekdays">' + dayName[i] + "<th>");
}
document.write("</tr>");
}
function daysInMonth(calendarDay){
var thisYear = calendarDay.getFullYear();
var thisMonth = calendarDay.getMonth();
var dayCount = new Array(31, 28, 31, 30, 31, 30, 31,31, 30, 31, 30, 31);
if(thisYear % 4 == 0){
if((thisYear % 100 != 0) || (thisYear % 400 == 0)){
dayCount[1] = 29;
}
}
return dayCount[thisMonth];
}
function writeCalDays(calendarDay){
var dayCount = 1;
var totalDays = daysInMonth(calendarDay);
calendarDay.setDate(1);
var weekDay = calendarDay.getDay();
document.write('<tr>');
for(var i = 0; i < weekDay; i++){
document.write('<td></td>');
}
while(dayCount <= totalDays){
if(weekDay == 0) document.write('<tr>');
document.write('<td class="calendar_dates">' + dayCount + "</td>");
if(weekDay == 6) document.write('</tr>');
dayCount++;
calendarDay.setDate(dayCount);
weekDay = calendarDay.getDay();
}
}
</script>
</head>
<body>
<script type="text/javascript">calendar();</script>
</body>
</html>
This is the output:
http://imgur.com/bzDXM1R
Thanks for your time!
I have this code im using to display events from a calendar but its displaying ALL of the events for that month and I only want to display the events for the day when a user clicks on a certain day. For example, click on February 10, you get all of the events for that day.
var eventList = $('<div/>').addClass('c-event-list');
for (var i = 0; i < settings.events.length; i++) {
var d = settings.events[i].datetime;
if ((d.getMonth() - 1) == dMonth && d.getFullYear() == dYear) {
var date = lpad(d.getMonth(), 2) + '/' +
lpad(d.getDate(), 2) + ' ' +
lpad(d.getHours() %12, 2) + ':' +
lpad(d.getMinutes(), 2);
var item = $('<div/>').addClass('c-event-item');
var title = $('<div/>')
.addClass('title')
.html(date + ' ' + settings.events[i].title + '<br />');
var description = $('<div/>')
.addClass('description')
.html(settings.events[i].description + '<br />');
item.attr('data-event-day', d.getDate());
item.on('mouseover', mouseOverItem).on('mouseleave', mouseLeaveItem);
item.append(title).append(description);
eventList.append(item);
}
}
$(instance).addClass('calendar');
cEventsBody.append(eventList);
$(instance).html(cBody).append(cEvents);
}
return print();
}
Thanks in advance for any assistance.
What I can see from your code is that this condition determines the month and year that events should be held on:
((d.getMonth() - 1) == dMonth && d.getFullYear() == dYear)
So when you want to display events only on a certain day you have to extend this condition like:
(d.getDate() == dDay && (d.getMonth() - 1) == dMonth && d.getFullYear() == dYear)
dDay is a new varibale that holds the day that events should be held on.
Following your request within last answer to show "no events" when a month is selected and there are none available.
I have modified this plugin so that it shows a "text"(for instance "no events") when the list on the right side is empty. I have tested it and it works.
This modification is ok because it is MIT licensed.
(function($) {
var eCalendar = function(options, object) {
// Initializing global variables
var adDay = new Date().getDate();
var adMonth = new Date().getMonth();
var adYear = new Date().getFullYear();
var dDay = adDay;
var dMonth = adMonth;
var dYear = adYear;
var instance = object;
var settings = $.extend({}, $.fn.eCalendar.defaults, options);
function lpad(value, length, pad) {
if (typeof pad == 'undefined') {
pad = '0';
}
var p;
for (var i = 0; i < length; i++) {
p += pad;
}
return (p + value).slice(-length);
}
var mouseOver = function() {
$(this).addClass('c-nav-btn-over');
};
var mouseLeave = function() {
$(this).removeClass('c-nav-btn-over');
};
var mouseOverEvent = function() {
$(this).addClass('c-event-over');
var d = $(this).attr('data-event-day');
$('div.c-event-item[data-event-day="' + d + '"]').addClass('c-event-over');
};
var mouseLeaveEvent = function() {
$(this).removeClass('c-event-over')
var d = $(this).attr('data-event-day');
$('div.c-event-item[data-event-day="' + d + '"]').removeClass('c-event-over');
};
var mouseOverItem = function() {
$(this).addClass('c-event-over');
var d = $(this).attr('data-event-day');
$('div.c-event[data-event-day="' + d + '"]').addClass('c-event-over');
};
var mouseLeaveItem = function() {
$(this).removeClass('c-event-over')
var d = $(this).attr('data-event-day');
$('div.c-event[data-event-day="' + d + '"]').removeClass('c-event-over');
};
var nextMonth = function() {
if (dMonth < 11) {
dMonth++;
} else {
dMonth = 0;
dYear++;
}
print();
};
var previousMonth = function() {
if (dMonth > 0) {
dMonth--;
} else {
dMonth = 11;
dYear--;
}
print();
};
var checkEventsOnCurrentMonth = function() {
var eventNum = $('.c-event-list').find('.c-event-item') ? $('.c-event-list').find('.c-event-item').length : 0;
if (!eventNum) {
$('.c-event-list').html($.fn.eCalendar.defaults.noEventText);
}
};
function loadEvents() {
if (typeof settings.url != 'undefined' && settings.url != '') {
$.ajax({
url: settings.url,
async: false,
success: function(result) {
settings.events = result;
}
});
}
}
function print() {
loadEvents();
var dWeekDayOfMonthStart = new Date(dYear, dMonth, 1).getDay();
var dLastDayOfMonth = new Date(dYear, dMonth + 1, 0).getDate();
var dLastDayOfPreviousMonth = new Date(dYear, dMonth + 1, 0).getDate() - dWeekDayOfMonthStart + 1;
var cBody = $('<div/>').addClass('c-grid');
var cEvents = $('<div/>').addClass('c-event-grid');
var cEventsBody = $('<div/>').addClass('c-event-body');
cEvents.append($('<div/>').addClass('c-event-title c-pad-top').html(settings.eventTitle));
cEvents.append(cEventsBody);
var cNext = $('<div/>').addClass('c-next c-grid-title c-pad-top');
var cMonth = $('<div/>').addClass('c-month c-grid-title c-pad-top');
var cPrevious = $('<div/>').addClass('c-previous c-grid-title c-pad-top');
cPrevious.html(settings.textArrows.previous);
cMonth.html(settings.months[dMonth] + ' ' + dYear);
cNext.html(settings.textArrows.next);
cPrevious.on('mouseover', mouseOver).on('mouseleave', mouseLeave).on('click', previousMonth);
cNext.on('mouseover', mouseOver).on('mouseleave', mouseLeave).on('click', nextMonth);
cBody.append(cPrevious);
cBody.append(cMonth);
cBody.append(cNext);
for (var i = 0; i < settings.weekDays.length; i++) {
var cWeekDay = $('<div/>').addClass('c-week-day c-pad-top');
cWeekDay.html(settings.weekDays[i]);
cBody.append(cWeekDay);
}
var day = 1;
var dayOfNextMonth = 1;
for (var i = 0; i < 42; i++) {
var cDay = $('<div/>');
if (i < dWeekDayOfMonthStart) {
cDay.addClass('c-day-previous-month c-pad-top');
cDay.html(dLastDayOfPreviousMonth++);
} else if (day <= dLastDayOfMonth) {
cDay.addClass('c-day c-pad-top');
if (day == dDay && adMonth == dMonth && adYear == dYear) {
cDay.addClass('c-today');
}
for (var j = 0; j < settings.events.length; j++) {
var d = settings.events[j].datetime;
if (d.getDate() == day && (d.getMonth() - 1) == dMonth && d.getFullYear() == dYear) {
cDay.addClass('c-event').attr('data-event-day', d.getDate());
cDay.on('mouseover', mouseOverEvent).on('mouseleave', mouseLeaveEvent);
}
}
cDay.html(day++);
} else {
cDay.addClass('c-day-next-month c-pad-top');
cDay.html(dayOfNextMonth++);
}
cBody.append(cDay);
}
var eventList = $('<div/>').addClass('c-event-list');
for (var i = 0; i < settings.events.length; i++) {
var d = settings.events[i].datetime;
if ((d.getMonth() - 1) == dMonth && d.getFullYear() == dYear) {
var date = lpad(d.getDate(), 2) + '/' + lpad(d.getMonth(), 2) + ' ' + lpad(d.getHours(), 2) + ':' + lpad(d.getMinutes(), 2);
var item = $('<div/>').addClass('c-event-item');
var title = $('<div/>').addClass('title').html(date + ' ' + settings.events[i].title + '<br/>');
var description = $('<div/>').addClass('description').html(settings.events[i].description + '<br/>');
item.attr('data-event-day', d.getDate());
item.on('mouseover', mouseOverItem).on('mouseleave', mouseLeaveItem);
item.append(title).append(description);
eventList.append(item);
}
}
$(instance).addClass('calendar');
cEventsBody.append(eventList);
$(instance).html(cBody).append(cEvents);
checkEventsOnCurrentMonth();
}
return print();
}
$.fn.eCalendar = function(oInit) {
return this.each(function() {
return eCalendar(oInit, $(this));
});
};
// plugin defaults
$.fn.eCalendar.defaults = {
weekDays: ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab'],
months: ['Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro'],
textArrows: {
previous: '<',
next: '>'
},
eventTitle: 'Eventos',
noEventText: 'no events',
url: '',
events: [{
title: 'Brasil x Croácia',
description: 'Abertura da copa do mundo 2014',
datetime: new Date(2014, 6, 12, 17)
}, {
title: 'Brasil x México',
description: 'Segundo jogo da seleção brasileira',
datetime: new Date(2014, 6, 17, 16)
}, {
title: 'Brasil x Camarões',
description: 'Terceiro jogo da seleção brasileira',
datetime: new Date(2014, 6, 23, 16)
}]
};
}(jQuery));
.calendar * {
box-sizing: border-box;
font-family: Tahoma;
font-size: 14px;
}
.calendar-sm {
cursor: default;
width: 800px;
height: 370px;
}
.calendar {
cursor: default;
width: 600px;
height: 270px;
}
.calendar-sm .c-pad-top {
padding-top: 2%;
}
.calendar .c-pad-top {
padding-top: 3%;
}
.c-grid {
box-shadow: 2px 2px 5px #888888;
height: inherit;
}
.c-day {
width: 14.28%;
height: 13%;
background-color: #EFF4F9;
float: left;
text-align: center;
}
.c-day-previous-month {
width: 14.28%;
height: 13%;
background-color: #F9FBFD;
float: left;
text-align: center;
color: gray;
}
.c-day-next-month {
width: 14.28%;
height: 13%;
background-color: #F9FBFD;
float: left;
text-align: center;
color: gray;
}
.c-week-day {
width: 14.28%;
height: 10.38%;
background-color: rgb(145, 172, 203);
color: white;
float: left;
text-align: center;
font-weight: bold;
padding-top: 1%;
}
.c-next {
width: 12.5%;
height: 12%;
padding: 2% 2% 0 2%;
text-align: right;
cursor: pointer;
}
.c-previous {
width: 12.5%;
height: 12%;
padding: 2% 2% 0 2%;
text-align: left;
cursor: pointer;
}
.c-month {
width: 75%;
height: 12%;
text-align: center;
}
.c-nav-btn-over {
background-color: rgb(137, 163, 192) !important;
font-weight: bold;
}
.c-today {
background-color: #D8EAF1;
}
.c-event {
background-color: rgb(166, 166, 166);
color: white;
font-weight: bold;
cursor: pointer;
}
.c-grid {
float: left;
width: 50%;
}
.c-event-grid {
margin-left: 1px;
height: inherit;
width: 49%;
float: left;
box-shadow: 2px 2px 5px #888888;
}
.c-grid-title {
font-weight: bold;
float: left;
background-color: rgb(112, 145, 183);
color: white;
}
.c-event-title {
width: 100%;
height: 12%;
text-align: center;
font-weight: bold;
background-color: rgb(135, 155, 188);
color: white;
}
.c-event-body {
background-color: #EFF4F9;
height: 88.1%;
}
.c-event-list {
padding: 7 0 0 0;
overflow: auto;
height: 95%;
}
.c-event-item > .title {
font-weight: bold;
}
.c-event-item > div {
text-overflow: ellipsis;
width: inherit;
overflow: hidden;
white-space: nowrap;
}
.c-event-item {
padding-left: 10px;
margin-bottom: 10px;
}
.c-event-over {
background-color: lightgray;
font-weight: bold;
color: black;
}
.c-event-over > .description {
font-weight: normal;
}
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>jQuery e-calendar Plugin Demo</title>
<link href="http://www.jqueryscript.net/css/jquerysctipttop.css" rel="stylesheet" type="text/css">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type="text/javascript" src="../js/jquery.e-calendar.js"></script>
<script type="text/javascript" src="index.js"></script>
<link rel="stylesheet" href="../css/jquery.e-calendar.css" />
</head>
<body>
<div id="jquery-script-menu">
<div class="jquery-script-center">
<ul>
<li>Download This Plugin
</li>
<li>Back To jQueryScript.Net
</li>
</ul>
<div class="jquery-script-ads">
<script type="text/javascript">
<!--
google_ad_client = "ca-pub-2783044520727903";
/* jQuery_demo */
google_ad_slot = "2780937993";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
</div>
<div class="jquery-script-clear"></div>
</div>
</div>
<h1 style="margin-top:150px;">jQuery e-calendar Plugin Demo</h1>
<div id="calendar"></div>
</body>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-36251023-1']);
_gaq.push(['_setDomainName', 'jqueryscript.net']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
})();
</script>
<script>
$(document).ready(function() {
$.fn.eCalendar.defaults.noEventText = '<br/>there are no events available';
$('#calendar').eCalendar({
weekDays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
textArrows: {
previous: '<',
next: '>'
},
eventTitle: 'Events',
url: '',
events: [{
title: 'Event 1',
description: 'Description 1',
datetime: new Date(2014, 7, 15, 17)
}, {
title: 'Event 2',
description: 'Description 2',
datetime: new Date(2014, 7, 14, 16)
}, {
title: 'Event 3',
description: 'jQueryScript.Net',
datetime: new Date(2014, 7, 10, 16)
}]
});
});
</script>
</html>
This is the function that check whether the event-list is empty and show a text if it's true. Put this function after previousMonth-function or somewhere within the library:
var checkEventsOnCurrentMonth = function(){
var eventNum = $('.c-event-list').find('.c-event-item') ? $('.c-event-list').find('.c-event-item').length : 0;
if(!eventNum){
$('.c-event-list').html('no events');
}
};
This function you have to call at the end of print:
function print() {
...
...
...
$(instance).addClass('calendar');
cEventsBody.append(eventList);
$(instance).html(cBody).append(cEvents);
// this is the function you have to call at the end of print:
checkEventsOnCurrentMonth();
}
Furthermore you can define the text in another fashion.
There are default values or settings at the bottom of the library.
$.fn.eCalendar.defaults = {
weekDays: ['Dom', 'Seg', 'Ter', 'Qua', 'Qui', 'Sex', 'Sab'],
...
...
noEventText: 'no events',
...
...
};
I've defined a new property "noEventText" to be used as text when no events are available.
The function checkEventsOnCurrentMonth has to be altered for this new default-value(noEventText) to be taken into consideration:
var checkEventsOnCurrentMonth = function(){
var eventNum = $('.c-event-list').find('.c-event-item') ? $('.c-event-list').find('.c-event-item').length : 0;
if(!eventNum){
$('.c-event-list').html($.fn.eCalendar.defaults.noEventText);
}
};
At the end you can define the text before the plugin has been started:
$(document).ready(function () {
// here you can define the text and put some html into it.
$.fn.eCalendar.defaults.noEventText = 'there are no events available';
$('#calendar').eCalendar({
...
...
});
});
As mentioned I've tested it but only with the download-version you can find here: http://www.jqueryscript.net/time-clock/Create-A-Simple-Event-Calendar-with-jQuery-e-calendar.html
Image: