I'm trying to add a datepicker to a page I'm creating. Since I don't know much at all about Javascript I'm modifying an example I've found at https://code-boxx.com/simple-datepicker-pure-javascript-css/. I don't want any extra pages or files as I need the form I'm creating to be entirely self-contained. I've condensed it down to this:
<!DOCTYPE html>
<html>
<head>
<title>Simple Date Picker Example</title>
<style>
/* (A) POPUP */
.picker-wrap {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: rgba(0,0,0,0.5);
opacity: 0;
visibility: hidden;
transition: opacity 0.2s;
}
.picker-wrap.show {
opacity: 1;
visibility: visible;
}
.picker-wrap .picker {
margin: 50vh auto 0 auto;
transform: translateY(-50%);
}
/* (B) CONTAINER */
.picker {
max-width: 300px;
background: #444444;
padding: 10px;
}
/* (C) MONTH + YEAR */
.picker-m, .picker-y {
width: 50%;
padding: 5px;
box-sizing: border-box;
font-size: 16px;
}
/* (D) DAY */
.picker-d table {
color: #fff;
border-collapse: separate;
width: 100%;
margin-top: 10px;
}
.picker-d table td {
width: 14.28%; /* 7 EQUAL COLUMNS */
padding: 5px;
text-align: center;
}
/* HEADER CELLS */
.picker-d-h td {
font-weight: bold;
}
/* BLANK DATES */
.picker-d-b {
background: #4e4e4e;
}
/* TODAY */
.picker-d-td {
background: #d84f4f;
}
/* PICKABLE DATES */
.picker-d-d:hover {
cursor: pointer;
/* UNPICKABLE DATES */
.picker-d-dd {
color: #888;
background: #4e4e4e;
}
</style>
<!-- (A) LOAD DATE PICKER -->
<!--<link href="dp-dark.css" rel="stylesheet">-->
<link href="dp-light.css" rel="stylesheet" />
<script src="datepicker.js"></script>
</head>
<body>
<!-- (B) THE HTML -->
<!-- (B1) INLINE DATE PICKER -->
<input type="text" id="input-inline" placeholder="Inline" />
<div id="pick-inline"></div>
<!-- (B2) POPUP DATE PICKER -->
<input type="text" id="input-pop" placeholder="Popup" />
<!-- (C) ATTACH DATE PICKER ON LOAD -->
<script>
window.addEventListener("load", function () {
// (C1) INLINE DATE PICKER
picker.attach({
target: "input-inline",
container: "pick-inline",
});
// (C2) POPUP DATE PICKER
picker.attach({
target: "input-pop",
});
});
</script>
</body>
<script>
var picker = {
// (A) ATTACH DATEPICKER TO TARGET
// target : datepicker will populate this field
// container : datepicker will be generated in this container
// startmon : start on Monday (default false)
// disableday : array of days to disable, e.g. [2,7] to disable Tue and Sun
attach: function (opt) {
// (A1) CREATE NEW DATEPICKER
var dp = document.createElement("div");
dp.dataset.target = opt.target;
dp.dataset.startmon = opt.startmon ? "1" : "0";
dp.classList.add("picker");
if (opt.disableday) {
dp.dataset.disableday = JSON.stringify(opt.disableday);
}
// (A2) DEFAULT TO CURRENT MONTH + YEAR - NOTE: UTC+0!
var today = new Date(),
thisMonth = today.getUTCMonth(), // Note: Jan is 0
thisYear = today.getUTCFullYear(),
months = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
];
// (A3) MONTH SELECT
var select = document.createElement("select"),
option = null;
select.classList.add("picker-m");
for (var mth in months) {
option = document.createElement("option");
option.value = parseInt(mth) + 1;
option.text = months[mth];
select.appendChild(option);
}
select.selectedIndex = thisMonth;
select.addEventListener("change", function () {
picker.draw(this);
});
dp.appendChild(select);
// (A4) YEAR SELECT
var yRange = 10; // Year range to show, I.E. from thisYear-yRange to thisYear+yRange
select = document.createElement("select");
select.classList.add("picker-y");
for (var y = thisYear - yRange; y < thisYear + yRange; y++) {
option = document.createElement("option");
option.value = y;
option.text = y;
select.appendChild(option);
}
select.selectedIndex = yRange;
select.addEventListener("change", function () {
picker.draw(this);
});
dp.appendChild(select);
// (A5) DAY SELECT
var days = document.createElement("div");
days.classList.add("picker-d");
dp.appendChild(days);
// (A6) ATTACH DATE PICKER TO TARGET CONTAINER + DRAW THE DATES
picker.draw(select);
// (A6-I) INLINE DATE PICKER
if (opt.container) {
document.getElementById(opt.container).appendChild(dp);
}
// (A6-P) POPUP DATE PICKER
else {
// (A6-P-1) MARK THIS AS A "POPUP"
var uniqueID = 0;
while (document.getElementById("picker-" + uniqueID) != null) {
uniqueID = Math.floor(Math.random() * (100 - 2)) + 1;
}
dp.dataset.popup = "1";
dp.dataset.dpid = uniqueID;
// (A6-P-2) CREATE WRAPPER
var wrapper = document.createElement("div");
wrapper.id = "picker-" + uniqueID;
wrapper.classList.add("picker-wrap");
wrapper.appendChild(dp);
// (A6-P-3) ATTACH ONCLICK TO SHOW/HIDE DATEPICKER
var target = document.getElementById(opt.target);
target.dataset.dp = uniqueID;
target.readOnly = true; // Prevent onscreen keyboar on mobile devices
target.onfocus = function () {
document
.getElementById("picker-" + this.dataset.dp)
.classList.add("show");
};
wrapper.addEventListener("click", function (evt) {
if (evt.target.classList.contains("picker-wrap")) {
this.classList.remove("show");
}
});
// (A6-P-4) ATTACH POPUP DATEPICKER TO BODY
document.body.appendChild(wrapper);
}
},
// (B) DRAW THE DAYS IN MONTH
// el : HTML reference to either year or month selector
draw: function (el) {
// (B1) GET DATE PICKER COMPONENTS
var parent = el.parentElement,
year = parent.getElementsByClassName("picker-y")[0].value,
month = parent.getElementsByClassName("picker-m")[0].value,
days = parent.getElementsByClassName("picker-d")[0];
// (B2) DATE RANGE CALCULATION - NOTE: UTC+0!
var daysInMonth = new Date(Date.UTC(year, month, 0)).getUTCDate(),
startDay = new Date(Date.UTC(year, month - 1, 1)).getUTCDay(), // Note: Sun = 0
endDay = new Date(Date.UTC(year, month - 1, daysInMonth)).getUTCDay(),
startDay = startDay == 0 ? 7 : startDay,
endDay = endDay == 0 ? 7 : endDay;
// (B3) GENERATE DATE SQUARES (IN ARRAY FIRST)
var squares = [],
disableday = null;
if (parent.dataset.disableday) {
disableday = JSON.parse(parent.dataset.disableday);
}
// (B4) EMPTY SQUARES BEFORE FIRST DAY OF MONTH
if (parent.dataset.startmon == "1" && startDay != 1) {
for (var i = 1; i < startDay; i++) {
squares.push("B");
}
}
if (parent.dataset.startmon == "0" && startDay != 7) {
for (var i = 0; i < startDay; i++) {
squares.push("B");
}
}
// (B5) DAYS OF MONTH
// (B5-1) ALL DAYS ENABLED, JUST ADD
if (disableday == null) {
for (var i = 1; i <= daysInMonth; i++) {
squares.push([i, false]);
}
}
// (B5-2) SOME DAYS DISABLED
else {
var thisday = startDay;
for (var i = 1; i <= daysInMonth; i++) {
// CHECK IF DAY IS DISABLED
var disabled = disableday.includes(thisday);
// DAY OF MONTH, DISABLED
squares.push([i, disabled]);
// NEXT DAY
thisday++;
if (thisday == 8) {
thisday = 1;
}
}
}
// (B6) EMPTY SQUARES AFTER LAST DAY OF MONTH
if (parent.dataset.startmon == "1" && endDay != 7) {
for (var i = endDay; i < 7; i++) {
squares.push("B");
}
}
if (parent.dataset.startmon == "0" && endDay != 6) {
for (var i = endDay; i < (endDay == 7 ? 13 : 6); i++) {
squares.push("B");
}
}
// (B7) DRAW HTML
var daynames = ["Mon", "Tue", "Wed", "Thur", "Fri", "Sat"];
if (parent.dataset.startmon == "1") {
daynames.push("Sun");
} else {
daynames.unshift("Sun");
}
// (B7-1) HTML DATE HEADER
var table = document.createElement("table"),
row = table.insertRow(),
cell = null;
row.classList.add("picker-d-h");
for (let d of daynames) {
cell = row.insertCell();
cell.innerHTML = d;
}
// (B7-2) HTML DATE CELLS
var total = squares.length,
row = table.insertRow(),
today = new Date(),
todayDate = null;
if (
today.getUTCMonth() + 1 == month &&
today.getUTCFullYear() == year
) {
todayDate = today.getUTCDate();
}
for (var i = 0; i < total; i++) {
if (i != total && i % 7 == 0) {
row = table.insertRow();
}
cell = row.insertCell();
if (squares[i] == "B") {
cell.classList.add("picker-d-b");
} else {
cell.innerHTML = squares[i][0];
// NOT ALLOWED TO CHOOSE THIS DAY
if (squares[i][1]) {
cell.classList.add("picker-d-dd");
}
// ALLOWED TO CHOOSE THIS DAY
else {
if (i == todayDate) {
cell.classList.add("picker-d-td");
}
cell.classList.add("picker-d-d");
cell.addEventListener("click", function () {
picker.pick(this);
});
}
}
}
// (B7-3) ATTACH NEW CALENDAR TO DATEPICKER
days.innerHTML = "";
days.appendChild(table);
},
// (C) CHOOSE A DATE
// el : HTML reference to selected date cell
pick: function (el) {
// (C1) GET ALL COMPONENTS
var parent = el.parentElement;
while (!parent.classList.contains("picker")) {
parent = parent.parentElement;
}
// (C2) GET FULL SELECTED YEAR MONTH DAY
var year = parent.getElementsByClassName("picker-y")[0].value,
month = parent.getElementsByClassName("picker-m")[0].value,
day = el.innerHTML;
// YYYY-MM-DD FORMAT - CHANGE FORMAT HERE IF YOU WANT !
if (parseInt(month) < 10) {
month = "0" + month;
}
if (parseInt(day) < 10) {
day = "0" + day;
}
var fullDate = year + "-" + month + "-" + day;
// (C3) UPDATE SELECTED DATE
document.getElementById(parent.dataset.target).value = fullDate;
// (C4) POPUP ONLY - CLOSE THE POPUP
if (parent.dataset.popup == "1") {
document
.getElementById("picker-" + parent.dataset.dpid)
.classList.remove("show");
}
},
};
</script>
</html>
Since I don't want the inline date picker and only want the pop-up date picker, I thought all I would need to do is remove this section:
<!-- (B1) INLINE DATE PICKER -->
<input type="text" id="input-inline" placeholder="Inline"/>
<div id="pick-inline"></div>
but when I do that the pop-up stops working as well. What do I need to change to remove the inline but just keep the pop-up?
You commented the template code for the inline date picker, but you have not commented the script for inline date picker.
Comment out the below code to make your solution working.
// Comment this code block in script
picker.attach({
target: "input-inline",
container: "pick-inline",
});
Why this was throwing error?
The datepicker was trying to find a target from dom having id input-inline. Since you have commented it out, it will not be available. Thats why it was stoping the execution of javascript. The code got broken there and the lines below that is not executed. This is why your popup date picker was also not working.
Working Fiddle
window.addEventListener("load", function () {
// (C1) INLINE DATE PICKER
// picker.attach({
// target: "input-inline",
// container: "pick-inline",
// });
// (C2) POPUP DATE PICKER
picker.attach({
target: "input-pop",
});
});
var picker = {
// (A) ATTACH DATEPICKER TO TARGET
// target : datepicker will populate this field
// container : datepicker will be generated in this container
// startmon : start on Monday (default false)
// disableday : array of days to disable, e.g. [2,7] to disable Tue and Sun
attach: function (opt) {
// (A1) CREATE NEW DATEPICKER
var dp = document.createElement("div");
dp.dataset.target = opt.target;
dp.dataset.startmon = opt.startmon ? "1" : "0";
dp.classList.add("picker");
if (opt.disableday) {
dp.dataset.disableday = JSON.stringify(opt.disableday);
}
// (A2) DEFAULT TO CURRENT MONTH + YEAR - NOTE: UTC+0!
var today = new Date(),
thisMonth = today.getUTCMonth(), // Note: Jan is 0
thisYear = today.getUTCFullYear(),
months = [
"Jan",
"Feb",
"Mar",
"Apr",
"May",
"Jun",
"Jul",
"Aug",
"Sep",
"Oct",
"Nov",
"Dec",
];
// (A3) MONTH SELECT
var select = document.createElement("select"),
option = null;
select.classList.add("picker-m");
for (var mth in months) {
option = document.createElement("option");
option.value = parseInt(mth) + 1;
option.text = months[mth];
select.appendChild(option);
}
select.selectedIndex = thisMonth;
select.addEventListener("change", function () {
picker.draw(this);
});
dp.appendChild(select);
// (A4) YEAR SELECT
var yRange = 10; // Year range to show, I.E. from thisYear-yRange to thisYear+yRange
select = document.createElement("select");
select.classList.add("picker-y");
for (var y = thisYear - yRange; y < thisYear + yRange; y++) {
option = document.createElement("option");
option.value = y;
option.text = y;
select.appendChild(option);
}
select.selectedIndex = yRange;
select.addEventListener("change", function () {
picker.draw(this);
});
dp.appendChild(select);
// (A5) DAY SELECT
var days = document.createElement("div");
days.classList.add("picker-d");
dp.appendChild(days);
// (A6) ATTACH DATE PICKER TO TARGET CONTAINER + DRAW THE DATES
picker.draw(select);
// (A6-I) INLINE DATE PICKER
if (opt.container) {
document.getElementById(opt.container).appendChild(dp);
}
// (A6-P) POPUP DATE PICKER
else {
// (A6-P-1) MARK THIS AS A "POPUP"
var uniqueID = 0;
while (document.getElementById("picker-" + uniqueID) != null) {
uniqueID = Math.floor(Math.random() * (100 - 2)) + 1;
}
dp.dataset.popup = "1";
dp.dataset.dpid = uniqueID;
// (A6-P-2) CREATE WRAPPER
var wrapper = document.createElement("div");
wrapper.id = "picker-" + uniqueID;
wrapper.classList.add("picker-wrap");
wrapper.appendChild(dp);
// (A6-P-3) ATTACH ONCLICK TO SHOW/HIDE DATEPICKER
var target = document.getElementById(opt.target);
target.dataset.dp = uniqueID;
target.readOnly = true; // Prevent onscreen keyboar on mobile devices
target.onfocus = function () {
document
.getElementById("picker-" + this.dataset.dp)
.classList.add("show");
};
wrapper.addEventListener("click", function (evt) {
if (evt.target.classList.contains("picker-wrap")) {
this.classList.remove("show");
}
});
// (A6-P-4) ATTACH POPUP DATEPICKER TO BODY
document.body.appendChild(wrapper);
}
},
// (B) DRAW THE DAYS IN MONTH
// el : HTML reference to either year or month selector
draw: function (el) {
// (B1) GET DATE PICKER COMPONENTS
var parent = el.parentElement,
year = parent.getElementsByClassName("picker-y")[0].value,
month = parent.getElementsByClassName("picker-m")[0].value,
days = parent.getElementsByClassName("picker-d")[0];
// (B2) DATE RANGE CALCULATION - NOTE: UTC+0!
var daysInMonth = new Date(Date.UTC(year, month, 0)).getUTCDate(),
startDay = new Date(Date.UTC(year, month - 1, 1)).getUTCDay(), // Note: Sun = 0
endDay = new Date(Date.UTC(year, month - 1, daysInMonth)).getUTCDay(),
startDay = startDay == 0 ? 7 : startDay,
endDay = endDay == 0 ? 7 : endDay;
// (B3) GENERATE DATE SQUARES (IN ARRAY FIRST)
var squares = [],
disableday = null;
if (parent.dataset.disableday) {
disableday = JSON.parse(parent.dataset.disableday);
}
// (B4) EMPTY SQUARES BEFORE FIRST DAY OF MONTH
if (parent.dataset.startmon == "1" && startDay != 1) {
for (var i = 1; i < startDay; i++) {
squares.push("B");
}
}
if (parent.dataset.startmon == "0" && startDay != 7) {
for (var i = 0; i < startDay; i++) {
squares.push("B");
}
}
// (B5) DAYS OF MONTH
// (B5-1) ALL DAYS ENABLED, JUST ADD
if (disableday == null) {
for (var i = 1; i <= daysInMonth; i++) {
squares.push([i, false]);
}
}
// (B5-2) SOME DAYS DISABLED
else {
var thisday = startDay;
for (var i = 1; i <= daysInMonth; i++) {
// CHECK IF DAY IS DISABLED
var disabled = disableday.includes(thisday);
// DAY OF MONTH, DISABLED
squares.push([i, disabled]);
// NEXT DAY
thisday++;
if (thisday == 8) {
thisday = 1;
}
}
}
// (B6) EMPTY SQUARES AFTER LAST DAY OF MONTH
if (parent.dataset.startmon == "1" && endDay != 7) {
for (var i = endDay; i < 7; i++) {
squares.push("B");
}
}
if (parent.dataset.startmon == "0" && endDay != 6) {
for (var i = endDay; i < (endDay == 7 ? 13 : 6); i++) {
squares.push("B");
}
}
// (B7) DRAW HTML
var daynames = ["Mon", "Tue", "Wed", "Thur", "Fri", "Sat"];
if (parent.dataset.startmon == "1") {
daynames.push("Sun");
} else {
daynames.unshift("Sun");
}
// (B7-1) HTML DATE HEADER
var table = document.createElement("table"),
row = table.insertRow(),
cell = null;
row.classList.add("picker-d-h");
for (let d of daynames) {
cell = row.insertCell();
cell.innerHTML = d;
}
// (B7-2) HTML DATE CELLS
var total = squares.length,
row = table.insertRow(),
today = new Date(),
todayDate = null;
if (
today.getUTCMonth() + 1 == month &&
today.getUTCFullYear() == year
) {
todayDate = today.getUTCDate();
}
for (var i = 0; i < total; i++) {
if (i != total && i % 7 == 0) {
row = table.insertRow();
}
cell = row.insertCell();
if (squares[i] == "B") {
cell.classList.add("picker-d-b");
} else {
cell.innerHTML = squares[i][0];
// NOT ALLOWED TO CHOOSE THIS DAY
if (squares[i][1]) {
cell.classList.add("picker-d-dd");
}
// ALLOWED TO CHOOSE THIS DAY
else {
if (i == todayDate) {
cell.classList.add("picker-d-td");
}
cell.classList.add("picker-d-d");
cell.addEventListener("click", function () {
picker.pick(this);
});
}
}
}
// (B7-3) ATTACH NEW CALENDAR TO DATEPICKER
days.innerHTML = "";
days.appendChild(table);
},
// (C) CHOOSE A DATE
// el : HTML reference to selected date cell
pick: function (el) {
// (C1) GET ALL COMPONENTS
var parent = el.parentElement;
while (!parent.classList.contains("picker")) {
parent = parent.parentElement;
}
// (C2) GET FULL SELECTED YEAR MONTH DAY
var year = parent.getElementsByClassName("picker-y")[0].value,
month = parent.getElementsByClassName("picker-m")[0].value,
day = el.innerHTML;
// YYYY-MM-DD FORMAT - CHANGE FORMAT HERE IF YOU WANT !
if (parseInt(month) < 10) {
month = "0" + month;
}
if (parseInt(day) < 10) {
day = "0" + day;
}
var fullDate = year + "-" + month + "-" + day;
// (C3) UPDATE SELECTED DATE
document.getElementById(parent.dataset.target).value = fullDate;
// (C4) POPUP ONLY - CLOSE THE POPUP
if (parent.dataset.popup == "1") {
document
.getElementById("picker-" + parent.dataset.dpid)
.classList.remove("show");
}
},
};
/* (A) POPUP */
.picker-wrap {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background: rgba(0, 0, 0, 0.5);
opacity: 0;
visibility: hidden;
transition: opacity 0.2s;
}
.picker-wrap.show {
opacity: 1;
visibility: visible;
}
.picker-wrap .picker {
margin: 50vh auto 0 auto;
transform: translateY(-50%);
}
/* (B) CONTAINER */
.picker {
max-width: 300px;
background: #444444;
padding: 10px;
}
/* (C) MONTH + YEAR */
.picker-m,
.picker-y {
width: 50%;
padding: 5px;
box-sizing: border-box;
font-size: 16px;
}
/* (D) DAY */
.picker-d table {
color: #fff;
border-collapse: separate;
width: 100%;
margin-top: 10px;
}
.picker-d table td {
width: 14.28%;
/* 7 EQUAL COLUMNS */
padding: 5px;
text-align: center;
}
/* HEADER CELLS */
.picker-d-h td {
font-weight: bold;
}
/* BLANK DATES */
.picker-d-b {
background: #4e4e4e;
}
/* TODAY */
.picker-d-td {
background: #d84f4f;
}
/* PICKABLE DATES */
.picker-d-d:hover {
cursor: pointer;
/* UNPICKABLE DATES */
.picker-d-dd {
color: #888;
background: #4e4e4e;
}
}
<!-- (B) THE HTML -->
<!-- (B1) INLINE DATE PICKER -->
<!-- <input type="text" id="input-inline" placeholder="Inline" />
<div id="pick-inline"></div> -->
<!-- (B2) POPUP DATE PICKER -->
<input type="text" id="input-pop" placeholder="Popup" />
Related
Here is my code.
<div class="modal-content animate" >
<div class="imgcontainer">
<span onclick="document.getElementById('Setpermissions').style.display='none'" class="close" title="Close Modal">×</span>
</div>
<script>
var nativePicker = document.querySelector('.nativeDateTimePicker');
var fallbackPicker = document.querySelector('.fallbackDateTimePicker');
var fallbackLabel = document.querySelector('.fallbackLabel');
var yearSelect = document.querySelector('#year');
var monthSelect = document.querySelector('#month');
var daySelect = document.querySelector('#day');
var hourSelect = document.querySelector('#hour');
var minuteSelect = document.querySelector('#minute');
// hide fallback initially
fallbackPicker.style.display = 'none';
fallbackLabel.style.display = 'none';
// test whether a new datetime-local input falls back to a text input or not
var test = document.createElement('input');
try {
test.type = 'datetime-local';
} catch (e) {
console.log(e.description);
}
// if it does, run the code inside the if() {} block
if(test.type === 'text') {
// hide the native picker and show the fallback
nativePicker.style.display = 'none';
fallbackPicker.style.display = 'block';
fallbackLabel.style.display = 'block';
// populate the days and years dynamically
// (the months are always the same, therefore hardcoded)
populateDays(monthSelect.value);
populateYears();
populateHours();
populateMinutes();
}
function populateDays(month) {
// delete the current set of <option> elements out of the
// day <select>, ready for the next set to be injected
while(daySelect.firstChild){
daySelect.removeChild(daySelect.firstChild);
}
// Create variable to hold new number of days to inject
var dayNum;
// 31 or 30 days?
if(month === 'January' || month === 'March' || month === 'May' || month === 'July' || month === 'August' || month === 'October' || month === 'December') {
dayNum = 31;
} else if(month === 'April' || month === 'June' || month === 'September' || month === 'November') {
dayNum = 30;
} else {
// If month is February, calculate whether it is a leap year or not
var year = yearSelect.value;
var isLeap = new Date(year, 1, 29).getMonth() == 1;
isLeap ? dayNum = 29 : dayNum = 28;
}
// inject the right number of new <option> elements into the day <select>
for(i = 1; i <= dayNum; i++) {
var option = document.createElement('option');
option.textContent = i;
daySelect.appendChild(option);
}
// if previous day has already been set, set daySelect's value
// to that day, to avoid the day jumping back to 1 when you
// change the year
if(previousDay) {
daySelect.value = previousDay;
// If the previous day was set to a high number, say 31, and then
// you chose a month with less total days in it (e.g. February),
// this part of the code ensures that the highest day available
// is selected, rather than showing a blank daySelect
if(daySelect.value === "") {
daySelect.value = previousDay - 1;
}
if(daySelect.value === "") {
daySelect.value = previousDay - 2;
}
if(daySelect.value === "") {
daySelect.value = previousDay - 3;
}
}
}
function populateYears() {
// get this year as a number
var date = new Date();
var year = date.getFullYear();
// Make this year, and the 100 years before it available in the year <select>
for(var i = 0; i <= 100; i++) {
var option = document.createElement('option');
option.textContent = year-i;
yearSelect.appendChild(option);
}
}
function populateHours() {
// populate the hours <select> with the 24 hours of the day
for(var i = 0; i <= 23; i++) {
var option = document.createElement('option');
option.textContent = (i < 10) ? ("0" + i) : i;
hourSelect.appendChild(option);
}
}
function populateMinutes() {
// populate the minutes <select> with the 60 hours of each minute
for(var i = 0; i <= 59; i++) {
var option = document.createElement('option');
option.textContent = (i < 10) ? ("0" + i) : i;
minuteSelect.appendChild(option);
}
}
// when the month or year <select> values are changed, rerun populateDays()
// in case the change affected the number of available days
yearSelect.onchange = function() {
populateDays(monthSelect.value);
}
monthSelect.onchange = function() {
populateDays(monthSelect.value);
}
//preserve day selection
var previousDay;
// update what day has been set to previously
// see end of populateDays() for usage
daySelect.onchange = function() {
previousDay = daySelect.value;
}
</script>
<form id="toDate" action="Permissions"method="post">
<div class="nativeDateTimePicker">
<label for="party">Choose a date and time for your party:</label>
<input type="datetime-local" id="party" name="toDate">
<span class="validity"></span>
</div>
</form>
Class Permissions:
public class Permissions {
private Time fromTime;
private Date fromDate;
private Time toTime;
private Date toDate;
private String reason;
private String permission;
public String getPermission() {
return permission;
}
public void setFromDate(Date fromDate) {
this.fromDate = fromDate;
}
public Date getFromDate() {
return fromDate;
}
public Date getToDate() {
return toDate;
}
public Time getFromTime() {
return fromTime;
}
public Time getToTime() {
return toTime;
}
public void setToDate(Date toDate) {
this.toDate = toDate;
}
public void setFromTime(Time from) {
this.fromTime = from;
}
public void setToTime(Time to) {
this.toTime = to;
}
public Permissions(){
reason = null;
permission = null;
fromTime=Time.valueOf("00:00:00");
toDate=Date.valueOf("2000-01-01");
toTime=Time.valueOf("00:00:00");
fromDate=Date.valueOf("2000-01-01");
}
public void setPermission(String permission) {
this.permission = permission;
}
public void setReason(String reason) {
this.reason = reason;
}
public String getReason() {
return reason;
}
}
This code displays a calender, from which a date can be selected.
I'm working on a spring mvc project, and I want to submit the date to the server. Changing form:submit is not working. So How can I do it?? Let the object be 'Permissions' (class components are given to you). Please help.
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?
I'm looking for year calendar with select range functions, but i don't found this. And I decided customize Bootstrap Year Calendar - http://www.bootstrap-year-calendar.com/
And I'm stuck, my customised version is on http://ngrdanjski.com/calendar/
and I'm looking for help!
I added:
All days are disabled by default.
You can added Price periods, in this dates period you have enabled booking.
I want to add option when first click on the day it's first day of booking range, and second click is last day of booking range. Right now when click on day you have enable start date/first day, but when you click second time on day when you want to select end date, it's again start/first date. I wan't to have function to select start and end date. First click on day is start and second is end.
Code for current behavior is:
if(this.options.enableRangeSelection) {
cells.mousedown(function (e) {
if(e.which == 1)
{
var currentDate = _this._getDate($(this));
//console.log(currentDate);
if(_this.options.allowOverlap || _this.getEvents(currentDate).length == 0)
{
_this._mouseDown = true;
_this._rangeStart = _this._rangeEnd = currentDate;
_this._refreshRange();
}
}
});
cells.mouseenter(function (e) {
//console.log(e);
if (_this._mouseDown)
{
var currentDate = _this._getDate($(this));
if(!_this.options.allowOverlap)
{
var newDate = new Date(_this._rangeStart.getTime());
if(newDate < currentDate)
{
var nextDate = new Date(newDate.getFullYear(), newDate.getMonth(), newDate.getDate() + 1);
while(newDate < currentDate)
{
if(_this.getEvents(nextDate).length > 0)
{
break;
}
newDate.setDate(newDate.getDate() + 1);
nextDate.setDate(nextDate.getDate() + 1);
}
}
else
{
var nextDate = new Date(newDate.getFullYear(), newDate.getMonth(), newDate.getDate() - 1);
while(newDate > currentDate)
{
if(_this.getEvents(nextDate).length > 0)
{
break;
}
newDate.setDate(newDate.getDate() - 1);
nextDate.setDate(nextDate.getDate() - 1);
}
}
currentDate = newDate;
}
var oldValue = _this._rangeEnd;
_this._rangeEnd = currentDate;
if (oldValue.getTime() != _this._rangeEnd.getTime())
{
_this._refreshRange();
}
}
});
/* $(window).mouseup(function (e) {
if (_this._mouseDown)
{
_this._mouseDown = false;
_this._refreshRange();
var minDate = _this._rangeStart < _this._rangeEnd ? _this._rangeStart : _this._rangeEnd;
var maxDate = _this._rangeEnd > _this._rangeStart ? _this._rangeEnd : _this._rangeStart;
_this._triggerEvent('selectRange', {
startDate: minDate,
endDate: maxDate,
events: _this.getEventsOnRange(minDate, new Date(maxDate.getFullYear(), maxDate.getMonth(), maxDate.getDate() + 1))
});
}
}); */
}
URL: https://ngrdanjski.com/calendar/js/bootstrap-year-calendar.js
Full version: https://codepen.io/NGrdanjski/pen/bQGdRb
I don't have skill for this functionality, please help.
Tnx!
I edited your code a bit. I understand that you want to set two dates, the start and the end of the range, and all that happens in two clicks. I also added a check if the second date is after the first one, if it's not they will swap places, so the earlier date is the rangeStart. The dates are stored in rangeStart and rangeEnd:
Edit: here's a pen
cells.mousedown(function (e) {
if(e.which == 1)
{
var currentDate = _this._getDate($(this));
//console.log(currentDate);
if(_this.options.allowOverlap || _this.getEvents(currentDate).length == 0)
{
if(!_this._mouseDown) {
_this._mouseDown = true;
_this._rangeStart = _this._rangeEnd = currentDate;
_this._refreshRange();
}
else {
_this._mouseDown = false;
_this._rangeEnd = currentDate;
if(_this._rangeEnd.getTime() < _this._rangeStart.getTime()) {
var tempDate = _this._rangeEnd;
_this._rangeEnd = _this._rangeStart;
_this._rangeStart = tempDate;
}
// _this._refreshRange();
}
}
if(_this._rangeStart != _this._rangeEnd) {
console.log(_this._rangeStart.getDate() + ',' + _this._rangeEnd.getDate());
}
}
});
I'm trying to figure out how to change my website's background by season using CSS and Javascript. It seems like it should be easy but I'm just not getting anywhere on it. Here's what I was trying, which doesn't work (of course, right?):
<script>
var currentTime = new Date();
var month = currentTime.getMonth() + 1;
var total = month;
// Summer
if (total >= 6 && total <= 8)
{
var season = "summer.jpg";
}
// Autumn
else if (total >= 9 && total <= 11)
{
var season = "fall.jpg";
}
// Winter
else if (total == 12 || total == 1 || total == 2)
{
var season = "winter.jpg";
}
// Spring
else if (total >= 2 && total <= 6)
{
var season = "spring.jpg";
}
else
{
var season = "summer.jpg";
}
</script>
<style type="text/css">
#maincontent{
position: fixed;
left: 200px; /*Set left value to WidthOfLeftFrameDiv*/
top: 0px; /*Set top value to HeightOfTopFrameDiv*/
right: 0;
bottom: 0;
overflow: auto;
background-image: url('season'); /*Note: I tried putting season in <scirpt> tags too with no success */
</style>
var currentTime = new Date();
var month = currentTime.getMonth() + 1;
var total = month;
switch(total) {
case (total >= 6 && total <= 8):
var season = "summer.jpg";
break;
case (total >= 9 && total <= 11):
var season = "fall.jpg";
break;
case (total == 12 || total == 1 || total == 2):
var season = "winter.jpg";
break;
default:
var season = "summer.jpg";
}
var output = "red url('" + season + "') no-repeat center center fixed";
var content= document.getElementById('maincontent');
content.style.background = output;
Use Pure Javascript to set background images according to your conditions. For reference I've added a text that shows you the current season.
Please have a look at the code below.
var currentTime = new Date();
var month = currentTime.getMonth() + 1;
var total = month;
console.log('currentTime: ', currentTime);
console.log('month: ', month);
console.log('total: ', total);
var myElement = document.querySelector("#maincontent");
var textSelector = function(divId) {
var textElement = document.getElementById(divId);
return textElement;
}
// Summer
if (total >= 6 && total <= 8)
{
var season = "summer.jpg";
myElement.style.backgroundImage = "url('http://placehold.it/500x500')";
textSelector('seasonOne').innerHTML = 'Season (Summer)';
}
// Autumn
else if (total >= 9 && total <= 11)
{
var season = "fall.jpg";
myElement.style.backgroundImage = "url('http://placehold.it/500x500')";
textSelector('seasonTwo').innerHTML = 'Season (Fall)';
}
// Winter
else if (total == 12 || total == 1 || total == 2)
{
var season = "winter.jpg";
myElement.style.backgroundImage = "url('http://placehold.it/500x500')";
textSelector('seasonThree').innerHTML = 'Season (Winter)';
}
// Spring
else if (total >= 2 && total <= 6)
{
var season = "spring.jpg";
myElement.style.backgroundImage = "url('http://placehold.it/500x500')";
textSelector('seasonThree').innerHTML = 'Season (Spring)';
}
else
{
var season = "summer.jpg";
myElement.style.backgroundImage = "url('http://placehold.it/500x500')";
textSelector('seasonThree').innerHTML = 'Season (Summer)';
}
#maincontent {
position: fixed;
left: 200px; /*Set left value to WidthOfLeftFrameDiv*/
top: 0px; /*Set top value to HeightOfTopFrameDiv*/
right: 0;
bottom: 0;
overflow: auto;
background-image: url('season');
background: #aaa;
}
.txt {
padding: 10px 40px;
font-weight: 700;
}
<div id="maincontent">
<div id="seasonOne" class="txt"></div>
<div id="seasonTwo" class="txt"></div>
<div id="seasonThree" class="txt"></div>
<div id="seasonFour" class="txt"></div>
<div id="seasonFive" class="txt"></div>
</div>
Hope this helps!
The accepted answers switch statement doesn't actually work, this really annoyed and confused me for a while, solution is to use 'true' as the switch argument:
var currentTime = new Date();
var month = currentTime.getMonth() + 1;
switch(true) {
case (month >= 6 && month <= 8):
var season = "summer.jpg";
break;
case (month >= 9 && month <= 11):
var season = "fall.jpg";
break;
case (month == 12 || month == 1 || month == 2):
var season = "winter.jpg";
break;
default:
var season = "summer.jpg";
}
Try this:
var main = document.getElementById('maincontent');
main.style.backgroundImage = "url(" + season + ")";
You should set the style inline...
var maincontent = document.getElementById("#maincontent");
var season = "summer";
if (condition) {
season = "fall"
}
// list all your conditions
maincontent.style.backgroundImage = "url(" + season + ".jpg)";
You can achieve this by using jquery,
after assigned value for season do like below,
$("#maincontent").css("background-image","url(" + season + ")");
By using javascript,
document.getElementById("maincontent").style.backgroundImage = "url(" + season + ")";
The Datepicker can only select the row to which my mouse is pointing.
Like this:
.bootstrap-datepicker-widget tr:hover {
background-color: #808080;
}
Here is the working code:
https://jsfiddle.net/owos/1mzhwykv/
However, I want to highlight the week from Thursday to Wednesday.The week is split into two rows, and that makes tr:hover not work.
Here is a way to style the right cells with JQuery
var weekStart = 4,
selectColor = "#ccc";
weekSelect = function() {
$(".day").hover(function() {
var index = $(this).index();
if (index < weekStart) {
prevSlice = index;
nextSlice = weekStart - index - 1;
prevWeek = 7;
nextWeek = 0;
} else {
prevSlice = index - weekStart;
nextSlice = 6 - index;
prevWeek = weekStart;
nextWeek = weekStart;
}
$(this).parent().next().children().slice(0, nextWeek).css('background-color', selectColor);
$(this).parent().prev().children().slice(weekStart, prevWeek).css('background-color', selectColor);
$(this).prevAll().slice(0, prevSlice).css('background-color', selectColor);
$(this).css('background-color', selectColor);
$(this).nextAll().slice(0, nextSlice).css('background-color', selectColor);
}, function() {
$(this).parent().prev().children().slice(0, prevWeek).css('background-color', '');
$(this).prevAll().slice(0, prevSlice).css('background-color', '');
$(this).css('background-color', '');
$(this).nextAll().slice(0, nextSlice).css('background-color', '');
$(this).parent().next().children().slice(0, nextWeek).css('background-color', '');
});
};
https://jsfiddle.net/link2twenty/1mzhwykv/1/