datepicker: batch of improvements - jscancer - Javascript crap (relatively small)
HTML git clone git://git.codemadness.org/jscancer
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
DIR commit 15738be7e39f50783051f26e06d2d7f193653261
DIR parent c775b91d6b52143499e42be4939fd5a5b978c266
HTML Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Sat, 28 May 2016 20:29:11 +0200
datepicker: batch of improvements
Diffstat:
M datepicker/README | 8 ++++----
M datepicker/TODO | 4 ++++
R datepicker/style.css -> datepicker… | 0
M datepicker/datepicker.js | 105 ++++++++++++++++++-------------
M datepicker/example.html | 3 ++-
5 files changed, 71 insertions(+), 49 deletions(-)
---
DIR diff --git a/datepicker/README b/datepicker/README
@@ -8,16 +8,16 @@ FEATURES
--------
- Small:
- - Filesize: +- 5.6KB.
- - Lines: +- 186, not much code, so hopefully easy to understand.
+ - Filesize: +- 6.3KB.
+ - Lines: +- 203, not much code, so hopefully easy to understand.
- No dependencies on other libraries like jQuery.
- "Graceful" fallback to the HTML5 datepicker if it is supported.
- Permissive ISC license, see LICENSE file, feel free to contact me for
questions or other terms.
-- No support for legacy browsers, officially supported are:
+- Officially supported browsers are:
- Firefox and Firefox ESR.
- Chrome and most recent webkit-based browsers.
- - IE Edge.
+ - IE8+ (use compat.js).
USAGE
DIR diff --git a/datepicker/TODO b/datepicker/TODO
@@ -1,3 +1,7 @@
+- dont use .onmousedown and event fallback, use addEventListener and compat.js.
+
+- disabled items doesn't work in IE8.
+
- fix position when opening datepicker.
? position: fixed incorrect for pages with height bigger than screen?
DIR diff --git a/datepicker/style.css b/datepicker/datepicker.css
DIR diff --git a/datepicker/datepicker.js b/datepicker/datepicker.js
@@ -1,8 +1,4 @@
function datepicker_init(input) {
- /* no input or already initialized */
- if (input.tagName.toLowerCase() !== "input" ||
- input.className.split(/\s/).indexOf("datepicker") !== -1)
- return null;
input.className += " datepicker";
var datepicker_mons = [
@@ -12,22 +8,30 @@ function datepicker_init(input) {
var datepicker_days = [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ];
var datepicker_isoweekdate = false;
+ var parsedateutc = function(s) {
+ var l = s.split("-"), d;
+ if (l.length < 3)
+ return NaN;
+ d = new Date(l[0], parseInt(l[1]) - 1, l[2], 0, 0, 0);
+ return d.getTime() - (d.getTimezoneOffset() * 60000);
+ };
+
var table = document.createElement("table");
table.className = "datepicker";
var curdate = new Date();
- var mindate = Date.parse(input.min);
- var maxdate = Date.parse(input.max);
+ var mindate = parsedateutc(input.min);
+ var maxdate = parsedateutc(input.max);
var seldate = NaN;
var td = document.createElement("td");
td.className = "prev";
- td.textContent = "<";
- td.onmousedown = function(e) {
+ td.innerHTML = "<";
+ td.addEventListener("mousedown", function(e) {
datepicker_nextmon(-1);
datepicker_display();
return !!e.stopPropagation();
- };
+ }, false);
var tr = document.createElement("tr");
tr.className = "yearmons";
tr.appendChild(td);
@@ -38,12 +42,12 @@ function datepicker_init(input) {
tr.appendChild(td);
td = document.createElement("td");
td.className = "next";
- td.textContent = ">";
- td.onmousedown = function(e) {
+ td.innerHTML = ">";
+ td.addEventListener("mousedown", function(e) {
datepicker_nextmon(1);
datepicker_display();
return !!e.stopPropagation();
- };
+ }, false);
tr.appendChild(td);
var thead = document.createElement("thead");
thead.appendChild(tr);
@@ -51,16 +55,16 @@ function datepicker_init(input) {
tr.className = "days";
for (var i = 0; i < 7; i++) {
td = document.createElement("td");
- td.innerHTML = datepicker_days[datepicker_isoweekdate ? (i + 1) % 7 : i];
+ td.appendChild(document.createTextNode(
+ datepicker_days[datepicker_isoweekdate ? (i + 1) % 7 : i]));
tr.appendChild(td);
}
thead.appendChild(tr);
table.appendChild(thead);
- var tbodyel = document.createElement("tbody");
- table.appendChild(tbodyel);
+ var tbodyel = table.appendChild(document.createElement("tbody"));
var datepicker_dateparse = function(s) {
- var v = s.split(/-/);
+ var v = (s || "").split(/-/);
if (v.length == 3)
return new Date(v[0], parseInt(v[1]) - 1, v[2]);
return NaN;
@@ -111,23 +115,23 @@ function datepicker_init(input) {
}
var td = document.createElement("td");
td.setAttribute("data-value", String(y) + "-" + pad0(m + 1) + "-" + pad0(i));
- td.innerHTML = String(i);
+ td.appendChild(document.createTextNode(String(i)));
// check if valid date (enabled or disabled).
var classes = [];
- var d = Date.parse(td.getAttribute("data-value")) || 0;
+ var d = parsedateutc(td.getAttribute("data-value")) || 0;
if ((!isNaN(mindate) && d < mindate) ||
(!isNaN(maxdate) && d > maxdate)) {
classes.push("d");
} else {
classes.push("v");
// NOTE: onmousedown is handled before input.blur event.
- td.onmousedown = function(e) {
+ td.addEventListener("mousedown", function(e) {
input.value = this.getAttribute("data-value");
curdate = seldate = datepicker_dateparse(input.value);
datepicker_hide();
return !!e.stopPropagation();
- };
+ }, false);
}
// selected date?
if (!isNaN(sel) && sel >= d && sel < d + 86400000)
@@ -146,40 +150,53 @@ function datepicker_init(input) {
tbodyel = tbody;
};
- input.onfocus = input.onclick = input.onkeyup = function() {
- if (this.value.length) {
+ var inparent = function(p, c) {
+ for (; c; c = c.parentNode)
+ if (c === p)
+ return true;
+ return false;
+ };
+
+ var focuschange = function(e) {
+ if (e.target === input) {
+ if (input.value.length) {
+ var d = datepicker_dateparse(input.value);
+ if (!isNaN(d))
+ curdate = seldate = d;
+ } else {
+ curdate = new Date();
+ }
+ datepicker_display();
+ datepicker_show();
+ } else if (inparent(table, e.target)) {
+ // is in parent?
+ return;
+ } else {
+ // format date onblur.
var d = datepicker_dateparse(this.value);
- if (!isNaN(d))
+ if (!isNaN(d)) {
curdate = seldate = d;
- } else {
- curdate = new Date();
- }
- datepicker_display();
- datepicker_show();
- };
- // format date onblur.
- input.onblur = function() {
- 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());
+ var pad0 = function(n) {
+ return (n < 10 ? "0" : "") + String(n);
+ };
+ input.value = String(d.getFullYear()) + "-" +
+ pad0(d.getMonth() + 1) + "-" + pad0(d.getDate());
+ }
+ datepicker_hide();
}
- datepicker_hide();
};
+ document.addEventListener("keyup", focuschange, false);
+ document.addEventListener("focus", focuschange, false);
+ document.addEventListener("click", focuschange, false);
+
datepicker_display();
datepicker_hide();
input.parentNode.insertBefore(table, input.nextSibling);
}
// Has native HTML5 date input type support? type is "text" if it isn't.
-var input = document.createElement("input");
-try { input.type = "date"; } catch(e) { }
-if (input.type !== "date") {
- var els = document.getElementsByClassName("date");
+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++)
datepicker_init(els[i]);
}
DIR diff --git a/datepicker/example.html b/datepicker/example.html
@@ -3,7 +3,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>jsdatepicker</title>
- <link rel="stylesheet" type="text/css" href="style.css" />
+ <link rel="stylesheet" type="text/css" href="datepicker.css" />
</head>
<body>
@@ -89,6 +89,7 @@ aaaaaaaaaaaaaa <input type="date" class="date" min="2016-01-01" max="2016-12-31"
<br/>
<input type="date" class="date" min="2016-01-05" max="2016-01-08" />
+<!--[if lte IE 8]><script type="text/javascript" src="../compat.js"></script><![endif]-->
<script type="text/javascript" src="datepicker.js"></script>
</body>