datepicker: improvements - jscancer - Javascript crap (relatively small) | |
git clone git://git.codemadness.org/jscancer | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit c1e9571c2fd4147beef18ae61f97206f8b9a29eb | |
parent 9e1bb1464a150fa8b9d1d253ccd5ca571b105c53 | |
Author: Hiltjo Posthuma <[email protected]> | |
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(-) | |
--- | |
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… | |
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) ==… | |
+ 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() +… | |
}; | |
- 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) + starti… | |
(!datepicker_isoweekdate && !((i + startidx - 1) %… | |
- 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… | |
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")) ||… | |
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.b… | |
+ /* NOTE: onmousedown is handled before input.b… | |
td.addEventListener("mousedown", function(e) { | |
input.value = this.getAttribute("data-… | |
curdate = seldate = datepicker_datepar… | |
@@ -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 && n… | |
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.… | |
} | |
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.ty… | |
var els = document.getElementsByClassName && document.getElementsByCla… | |
for (var i = 0; i < els.length; i++) |