Initial import
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Popup Date Picker</title>
|
||||
|
||||
<!-- (A) LOAD DATE PICKER -->
|
||||
<!-- <link href="dp-dark.css" rel="stylesheet"> -->
|
||||
<link href="dp-light.css" rel="stylesheet">
|
||||
<script defer src="datepicker.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- (B) THE HTML -->
|
||||
<input type="text" id="input-pop" placeholder="Popup"/>
|
||||
|
||||
<!-- (C) ATTACH DATE PICKER ON LOAD -->
|
||||
<script>
|
||||
window.addEventListener("load", () => {
|
||||
picker.attach({ target: "input-pop" });
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,26 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Inline Date Picker</title>
|
||||
|
||||
<!-- (A) LOAD DATE PICKER -->
|
||||
<!-- <link href="dp-dark.css" rel="stylesheet"> -->
|
||||
<link href="dp-light.css" rel="stylesheet">
|
||||
<script defer src="datepicker.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- (B) THE HTML -->
|
||||
<input type="text" id="input-inline" placeholder="Inline"/>
|
||||
<div id="pick-inline"></div>
|
||||
|
||||
<!-- (C) ATTACH DATE PICKER ON LOAD -->
|
||||
<script>
|
||||
window.addEventListener("load", () => {
|
||||
picker.attach({
|
||||
target: "input-inline",
|
||||
container: "pick-inline"
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,30 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Date Picker Options</title>
|
||||
|
||||
<!-- (A) LOAD THE LIBRARIES -->
|
||||
<!-- <link href="dp-light.css" rel="stylesheet"> -->
|
||||
<link href="dp-dark.css" rel="stylesheet">
|
||||
<script defer src="datepicker.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<!-- (B) THE HTML -->
|
||||
<input type="text" id="input-opt" placeholder="Options"/>
|
||||
<div id="pick-opt"></div>
|
||||
|
||||
<!-- (C) ATTACH DATE PICKER ON LOAD -->
|
||||
<script>
|
||||
window.addEventListener("load", () => {
|
||||
picker.attach({
|
||||
target: "input-opt",
|
||||
container: "pick-opt",
|
||||
disableday : [2, 7], // DISABLE TUE, SUN (DEFAULT NONE)
|
||||
startmon: true, // WEEK START ON MON (DEFAULT FALSE)
|
||||
yrange: 5, // ALLOW +/- 5 YEARS FROM NOW (DEFAULT 10)
|
||||
onpick: () => { alert("PICKED"); } // DO YOUR STUFF AFTER PICK
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,29 @@
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
LICENSE
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
|
||||
Copyright by Code Boxx
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
MORE
|
||||
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
|
||||
Please visit https://code-boxx.com/ for more!
|
||||
@@ -0,0 +1,247 @@
|
||||
var picker = {
|
||||
// (A) ATTACH DATEPICKER TO TARGET
|
||||
// target: field to populate
|
||||
// container: generate datepicker in here (for inline datepicker)
|
||||
// startmon: start on mon? (optional, default false)
|
||||
// yrange: year select range (optional, default 10)
|
||||
// disableday: days to disable, e.g. [2,7] to disable tue and sun (optional)
|
||||
// onpick : function to call on select date (optional)
|
||||
instances: [],
|
||||
attach: (opt) => {
|
||||
// (A1) SET DEFAULT OPTIONS & REGISTER INSTANCE
|
||||
opt.target = document.getElementById(opt.target);
|
||||
opt.target.readOnly = true; // PREVENT ONSCREEN KEYBOARD
|
||||
if (opt.container) {
|
||||
opt.container = document.getElementById(opt.container);
|
||||
}
|
||||
opt.startmon = opt.startmon ? true : false;
|
||||
opt.yrange = opt.yrange ? opt.yrange : 10;
|
||||
const id = picker.instances.length;
|
||||
picker.instances.push(opt);
|
||||
let inst = picker.instances[id];
|
||||
|
||||
// (A2) TEMP VARS + CURRENT MONTH YEAR (UTC+0)
|
||||
let months = ["Януари", "Февруари", "Март", "Април", "Май", "Юни",
|
||||
"Юли", "Август", "Септември", "Октомври", "Ноември", "Декември"],
|
||||
temp, today = new Date(),
|
||||
thisMonth = today.getUTCMonth(), // JAN IS 0
|
||||
thisYear = today.getUTCFullYear();
|
||||
|
||||
// (A3) GENERATE HTML
|
||||
// (A3-1) HTML DATEPICKER WRAPPER
|
||||
inst.hPick = document.createElement("div");
|
||||
inst.hPick.classList.add("picker");
|
||||
|
||||
// (A3-2) HTML MONTH SELECT
|
||||
inst.hMonth = document.createElement("select");
|
||||
inst.hMonth.classList.add("picker-m");
|
||||
for (let m in months) {
|
||||
temp = document.createElement("option");
|
||||
temp.value = +m + 1;
|
||||
temp.text = months[m];
|
||||
inst.hMonth.appendChild(temp);
|
||||
}
|
||||
inst.hMonth.selectedIndex = thisMonth;
|
||||
inst.hMonth.onchange = () => {
|
||||
picker.draw(id);
|
||||
};
|
||||
inst.hPick.appendChild(inst.hMonth);
|
||||
|
||||
// (A3-3) HTML YEAR SELECT
|
||||
inst.hYear = document.createElement("select");
|
||||
inst.hYear.classList.add("picker-y");
|
||||
for (let y = thisYear - inst.yrange; y < thisYear + inst.yrange; y++) {
|
||||
temp = document.createElement("option");
|
||||
temp.value = y;
|
||||
temp.text = y;
|
||||
inst.hYear.appendChild(temp);
|
||||
}
|
||||
inst.hYear.selectedIndex = inst.yrange;
|
||||
inst.hYear.onchange = () => {
|
||||
picker.draw(id);
|
||||
};
|
||||
inst.hPick.appendChild(inst.hYear);
|
||||
|
||||
// (A3-4) HTML DAYS
|
||||
inst.hDays = document.createElement("div");
|
||||
inst.hDays.classList.add("picker-d");
|
||||
inst.hPick.appendChild(inst.hDays);
|
||||
picker.draw(id);
|
||||
|
||||
// (A4) INLINE DATEPICKER - ATTACH INTO CONTAINER
|
||||
if (inst.container) {
|
||||
inst.container.appendChild(inst.hPick);
|
||||
}
|
||||
|
||||
// (A5) POPUP DATEPICKER - ATTACH INTO HTML BODY
|
||||
else {
|
||||
// (A5-1) FULL PAGE WRAPPER
|
||||
inst.hWrap = document.createElement("div");
|
||||
inst.hWrap.classList.add("picker-wrap");
|
||||
inst.hWrap.appendChild(inst.hPick);
|
||||
|
||||
// (A5-2) CLICK TO TOGGLE DATEPICKER
|
||||
inst.target.onfocus = () => {
|
||||
inst.hWrap.classList.add("show");
|
||||
};
|
||||
inst.hWrap.onclick = (evt) => {
|
||||
if (evt.target === inst.hWrap) {
|
||||
inst.hWrap.classList.remove("show");
|
||||
}
|
||||
};
|
||||
|
||||
// (A5-3) ATTACH POPUP DATEPICKER
|
||||
document.body.appendChild(inst.hWrap);
|
||||
}
|
||||
},
|
||||
|
||||
// (B) DRAW DAYS IN MONTH
|
||||
draw: (id) => {
|
||||
// (B1) CRAZY VARS & CALCULATIONS
|
||||
// (B1-1) GET INSTANCE + SELECTED MONTH YEAR
|
||||
let inst = picker.instances[id],
|
||||
month = inst.hMonth.value,
|
||||
year = inst.hYear.value;
|
||||
|
||||
// (B1-2) DATE RANGE CALCULATION (UTC+0)
|
||||
let daysInMonth = new Date(Date.UTC(year, month, 0)).getUTCDate(),
|
||||
startDay = new Date(Date.UTC(year, month - 1, 1)).getUTCDay(), // SUN IS 0
|
||||
endDay = new Date(Date.UTC(year, month - 1, daysInMonth)).getUTCDay();
|
||||
startDay = startDay == 0 ? 7 : startDay,
|
||||
endDay = endDay == 0 ? 7 : endDay;
|
||||
|
||||
// (B1-3) TODAY (FOR HIGHLIGHTING "TODAY'S DATE CELL")
|
||||
let today = new Date(), todayDate = null;
|
||||
if (today.getUTCMonth() + 1 == month && today.getUTCFullYear() == year) {
|
||||
todayDate = today.getUTCDate();
|
||||
}
|
||||
|
||||
// (B1-4) DAY NAMES
|
||||
let daynames = ["Пон", "Вт", "Сря", "Чет", "Пет", "Съб"];
|
||||
if (inst.startmon) {
|
||||
daynames.push("Нед");
|
||||
} else {
|
||||
daynames.unshift("Нед");
|
||||
}
|
||||
|
||||
// (B1-5) FOR GENERATING DATE SQUARES
|
||||
let table, row, cell, squares = [];
|
||||
|
||||
// (B2) CALCULATE DATE SQUARES ARRAY
|
||||
// (B2-1) EMPTY SQUARES BEFORE FIRST DAY OF MONTH
|
||||
if (inst.startmon && startDay !== 1) {
|
||||
for (let i = 1; i < startDay; i++) {
|
||||
squares.push("B");
|
||||
}
|
||||
}
|
||||
if (!inst.startmon && startDay !== 7) {
|
||||
for (let i = 0; i < startDay; i++) {
|
||||
squares.push("B");
|
||||
}
|
||||
}
|
||||
|
||||
// (B2-2) DAYS OF MONTH (SOME DAYS DISABLED)
|
||||
if (inst.disableday) {
|
||||
let thisDay = startDay;
|
||||
for (let i = 1; i <= daysInMonth; i++) {
|
||||
squares.push([i, inst.disableday.includes(thisDay)]);
|
||||
thisDay++;
|
||||
if (thisDay === 8) {
|
||||
thisDay = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// (B2-3) DAYS OF MONTH (ALL DAYS ENABLED)
|
||||
else {
|
||||
for (let i = 1; i <= daysInMonth; i++) {
|
||||
squares.push([i, false]);
|
||||
}
|
||||
}
|
||||
|
||||
// (B2-4) EMPTY SQUARES AFTER LAST DAY OF MONTH
|
||||
if (inst.startmon && endDay !== 7) {
|
||||
for (let i = endDay; i < 7; i++) {
|
||||
squares.push("B");
|
||||
}
|
||||
}
|
||||
if (!inst.startmon && endDay !== 6) {
|
||||
for (let i = endDay; i < (endDay === 7 ? 13 : 6); i++) {
|
||||
squares.push("B");
|
||||
}
|
||||
}
|
||||
|
||||
// (B3) DRAW HTML
|
||||
// (B3-1) HTML DAY NAMES HEADER
|
||||
table = document.createElement("table");
|
||||
row = table.insertRow();
|
||||
row.classList.add("picker-d-h");
|
||||
for (let d of daynames) {
|
||||
cell = row.insertCell();
|
||||
cell.innerHTML = d;
|
||||
}
|
||||
|
||||
// (B3-2) HTML DATE CELLS
|
||||
row = table.insertRow();
|
||||
for (let i = 0; i < squares.length; i++) {
|
||||
if (i !== squares.length && i % 7 === 0) {
|
||||
row = table.insertRow();
|
||||
}
|
||||
cell = row.insertCell();
|
||||
if (squares[i] === "B") {
|
||||
cell.classList.add("picker-d-b");
|
||||
} else {
|
||||
// CELL DATE
|
||||
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 (squares[i][0] === todayDate) {
|
||||
cell.classList.add("picker-d-td");
|
||||
}
|
||||
cell.classList.add("picker-d-d");
|
||||
cell.onclick = () => {
|
||||
console.log(id);
|
||||
picker.pick(id, squares[i][0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// (B4) ATTACH DAYS TO DATEPICKER
|
||||
inst.hDays.innerHTML = "";
|
||||
inst.hDays.appendChild(table);
|
||||
},
|
||||
|
||||
// (C) CHOOSE A DATE
|
||||
pick: (id, day) => {
|
||||
// (C1) GET MONTH YEAR
|
||||
let inst = picker.instances[id],
|
||||
month = inst.hMonth.value,
|
||||
year = inst.hYear.value;
|
||||
|
||||
// (C2) FORMAT & SET SELECTED DAY (YYYY-MM-DD)
|
||||
if (+month < 10) {
|
||||
month = "0" + month;
|
||||
}
|
||||
if (+day < 10) {
|
||||
day = "0" + day;
|
||||
}
|
||||
inst.target.value = `${year}-${month}-${day}`;
|
||||
|
||||
// (C3) POPUP ONLY - CLOSE
|
||||
if (inst.container === undefined) {
|
||||
inst.hWrap.classList.remove("show");
|
||||
}
|
||||
|
||||
// (C4) CALL ON PICK IF DEFINED
|
||||
if (inst.onpick) {
|
||||
inst.onpick();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,71 @@
|
||||
/* (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;
|
||||
border: 1px solid #000;
|
||||
background: #444;
|
||||
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;
|
||||
background: #a33c3c;
|
||||
}
|
||||
/* UNPICKABLE DATES */
|
||||
.picker-d-dd {
|
||||
color: #888;
|
||||
background: #4e4e4e;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/* (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 {
|
||||
min-width: 280px;
|
||||
max-width: 280px;
|
||||
border: 1px solid var(--base-background-middle-bright);
|
||||
background: var(--base-background-ultra-bright);
|
||||
padding: 10px;
|
||||
display: flex !important;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.picker select {
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
/* (C) MONTH + YEAR */
|
||||
.picker-m, .picker-y {
|
||||
padding: 5px;
|
||||
box-sizing: border-box;
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.picker-m {
|
||||
width: calc(100% - 90px) !important;
|
||||
}
|
||||
.picker-y {
|
||||
width: 80px !important;
|
||||
}
|
||||
/* (D) DAY */
|
||||
.picker-d table {
|
||||
color: #333;
|
||||
border-collapse: separate;
|
||||
width: 100%;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.picker-d table td {
|
||||
width: 14.28%; /* 7 EQUAL COLUMNS */
|
||||
padding: 5px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* HEADER */
|
||||
.picker-d-h td {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* BLANK DATES */
|
||||
.picker-d-b {
|
||||
background: var(--base-background-ultra-bright);
|
||||
}
|
||||
|
||||
/* TODAY */
|
||||
.picker-d-td {
|
||||
background: #ffe0d4;
|
||||
}
|
||||
|
||||
/* PICKABLE DATES */
|
||||
.picker-d-d:hover {
|
||||
cursor: pointer;
|
||||
background: #2d68c4;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
/* UNPICKABLE DATES */
|
||||
.picker-d-dd {
|
||||
color: #aaa;
|
||||
background: #ddd;
|
||||
}
|
||||
Reference in New Issue
Block a user