datepicker: improvements - jscancer - Javascript crap (relatively small)
(HTM) git clone git://git.codemadness.org/jscancer
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
(DIR) commit c1e9571c2fd4147beef18ae61f97206f8b9a29eb
(DIR) parent 9e1bb1464a150fa8b9d1d253ccd5ca571b105c53
(HTM) Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Thu, 2 Jun 2016 18:45:33 +0200
datepicker: improvements
- rename display to render (show vs display is more confusing), render only
inserts the nodes.
- fix relative positioning of datepicker dialog: for example in a table.
- escape key closes dialog.
- fix empty row on certain months (where the first day of the month is the same
as the day to start the week.
- use "1" as day when a date is partially input to highlight the date, else a
date like: 2015-01-0 would display december 2015.
Diffstat:
M datepicker/datepicker.js | 62 ++++++++++++++++---------------
1 file changed, 33 insertions(+), 29 deletions(-)
---
(DIR) diff --git a/datepicker/datepicker.js b/datepicker/datepicker.js
@@ -29,7 +29,7 @@ function datepicker_init(input) {
td.innerHTML = "<";
td.addEventListener("mousedown", function(e) {
datepicker_nextmon(-1);
- datepicker_display();
+ datepicker_render();
return !!e.stopPropagation();
}, false);
var tr = document.createElement("tr");
@@ -45,7 +45,7 @@ function datepicker_init(input) {
td.innerHTML = ">";
td.addEventListener("mousedown", function(e) {
datepicker_nextmon(1);
- datepicker_display();
+ datepicker_render();
return !!e.stopPropagation();
}, false);
tr.appendChild(td);
@@ -66,7 +66,7 @@ function datepicker_init(input) {
var datepicker_dateparse = function(s) {
var v = (s || "").split(/-/);
if (v.length == 3)
- return new Date(v[0], parseInt(v[1]) - 1, v[2]);
+ return new Date(v[0], parseInt(v[1]) - 1, parseInt(v[2]) || 1);
return NaN;
};
var datepicker_hide = function() {
@@ -77,15 +77,20 @@ function datepicker_init(input) {
table.hidden = false;
table.style.display = "table";
table.style.position = "absolute";
- table.style.left = String(input.offsetLeft) + "px";
- // scroll if outside window.
+ var left = 0;
+ for (var c = input; c; c = c.offsetParent) {
+ if (["absolute", "fixed"].indexOf(c.style.position) == -1)
+ left += c.offsetLeft;
+ }
+ table.style.left = String(left) + "px";
+ /* scroll if outside window. */
input.scrollIntoView();
};
var datepicker_nextmon = function(n) {
curdate = new Date(curdate.getFullYear(), curdate.getMonth() + n, 1);
};
- var datepicker_display = function() {
- datepicker_nextmon(0); // fix date
+ var datepicker_render = function() {
+ datepicker_nextmon(0); /* fix date */
var y = curdate.getFullYear(), m = curdate.getMonth();
header.innerHTML = datepicker_mons[m] + " " + String(y);
@@ -110,14 +115,16 @@ function datepicker_init(input) {
for (var i = 1; i <= endday; i++) {
if ((datepicker_isoweekdate && !(((i - 1 % 7) + startidx) % 7)) ||
(!datepicker_isoweekdate && !((i + startidx - 1) % 7))) {
- tbody.appendChild(tr);
- tr = document.createElement("tr");
+ if (tr.childNodes.length) {
+ tbody.appendChild(tr);
+ tr = document.createElement("tr");
+ }
}
var td = document.createElement("td");
td.setAttribute("data-value", String(y) + "-" + pad0(m + 1) + "-" + pad0(i));
td.appendChild(document.createTextNode(String(i)));
- // check if valid date (enabled or disabled).
+ /* check if valid date (enabled or disabled). */
var classes = [];
var d = parsedateutc(td.getAttribute("data-value")) || 0;
if ((!isNaN(mindate) && d < mindate) ||
@@ -125,7 +132,7 @@ function datepicker_init(input) {
classes.push("d");
} else {
classes.push("v");
- // NOTE: onmousedown is handled before input.blur event.
+ /* NOTE: onmousedown is handled before input.blur event. */
td.addEventListener("mousedown", function(e) {
input.value = this.getAttribute("data-value");
curdate = seldate = datepicker_dateparse(input.value);
@@ -133,10 +140,10 @@ function datepicker_init(input) {
return !!e.stopPropagation();
}, false);
}
- // selected date?
+ /* selected date? */
if (!isNaN(sel) && sel >= d && sel < d + 86400000)
classes.push("sel");
- // is date today?
+ /* is date today? */
if (now.getFullYear() == y && now.getMonth() == m && now.getDate() == i)
classes.push("today");
td.className = classes.join(" ");
@@ -149,16 +156,17 @@ function datepicker_init(input) {
tbodyel.parentNode.replaceChild(tbody, tbodyel);
tbodyel = tbody;
};
-
var inparent = function(p, c) {
for (; c; c = c.parentNode)
if (c === p)
return true;
return false;
};
-
+ var pad0 = function(n) {
+ return (n < 10 ? "0" : "") + String(n);
+ };
var focuschange = function(e) {
- if (e.target === input) {
+ if (e.which !== 27 && e.target == input) {
if (input.value.length) {
var d = datepicker_dateparse(input.value);
if (!isNaN(d))
@@ -166,35 +174,31 @@ function datepicker_init(input) {
} else {
curdate = new Date();
}
- datepicker_display();
+ datepicker_render();
datepicker_show();
- } else if (inparent(table, e.target)) {
- // is in parent?
- return;
- } else {
- // format date onblur.
+ } else if (!inparent(table, e.target)) {
+ /* is in parent? ignore */
+ /* format date onblur. */
var d = datepicker_dateparse(this.value);
if (!isNaN(d)) {
curdate = seldate = d;
- var pad0 = function(n) {
- return (n < 10 ? "0" : "") + String(n);
- };
input.value = String(d.getFullYear()) + "-" +
pad0(d.getMonth() + 1) + "-" + pad0(d.getDate());
}
datepicker_hide();
}
};
- document.addEventListener("keyup", focuschange, false);
- document.addEventListener("focus", focuschange, false);
document.addEventListener("click", focuschange, false);
+ input.addEventListener("input", focuschange, false);
+ input.addEventListener("focus", focuschange, false);
+ document.addEventListener("keyup", focuschange, false);
- datepicker_display();
+ datepicker_render();
datepicker_hide();
input.parentNode.insertBefore(table, input.nextSibling);
}
-// Has native HTML5 date input type support? type is "text" if it isn't.
+/* has native HTML5 date input type support? type is "text" if it isn't. */
if (!(function() { var input = document.createElement("input"); try { input.type = "date"; return (input.type === "date"); } catch(e) {} return false; })()) {
var els = document.getElementsByClassName && document.getElementsByClassName("date") || [];
for (var i = 0; i < els.length; i++)