datepicker.js - jscancer - Javascript crap (relatively small)
(HTM) git clone git://git.codemadness.org/jscancer
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
datepicker.js (6550B)
---
1 function datepicker_init(input) {
2 input.className += " datepicker";
3
4 var datepicker_mons = [
5 "January", "February", "March", "April", "May", "June",
6 "July", "August", "September", "October", "November", "December"
7 ];
8 var datepicker_days = [ "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa" ];
9 var datepicker_isoweekdate = true;
10
11 var parsedateutc = function(s) {
12 var l = (s || "").split("-"), d;
13 if (l.length < 3)
14 return NaN;
15 d = new Date(l[0], parseInt(l[1]) - 1, l[2], 0, 0, 0);
16 return d.getTime() - (d.getTimezoneOffset() * 60000);
17 };
18
19 var table = document.createElement("table");
20 table.className = "datepicker";
21
22 var curdate = new Date();
23 var mindate = parsedateutc(input.min);
24 var maxdate = parsedateutc(input.max);
25 var seldate = NaN;
26
27 var td = document.createElement("td");
28 td.className = "prev";
29 td.innerHTML = "<";
30 td.addEventListener("mousedown", function(e) {
31 datepicker_nextmon(-1);
32 datepicker_render();
33 return !!e.stopPropagation();
34 }, false);
35 var tr = document.createElement("tr");
36 tr.className = "yearmons";
37 tr.appendChild(td);
38 td = document.createElement("td");
39 td.colSpan = 5;
40 td.className = "name";
41 var header = td; // set header.
42 tr.appendChild(td);
43 td = document.createElement("td");
44 td.className = "next";
45 td.innerHTML = ">";
46 td.addEventListener("mousedown", function(e) {
47 datepicker_nextmon(1);
48 datepicker_render();
49 return !!e.stopPropagation();
50 }, false);
51 tr.appendChild(td);
52 var thead = document.createElement("thead");
53 thead.appendChild(tr);
54 tr = document.createElement("tr");
55 tr.className = "days";
56 for (var i = 0; i < 7; i++) {
57 td = document.createElement("td");
58 td.appendChild(document.createTextNode(
59 datepicker_days[datepicker_isoweekdate ? (i + 1) % 7 : i]));
60 tr.appendChild(td);
61 }
62 thead.appendChild(tr);
63 table.appendChild(thead);
64 var tbodyel = table.appendChild(document.createElement("tbody"));
65
66 var datepicker_dateparse = function(s) {
67 var v = (s || "").split(/-/);
68 if (v.length == 3)
69 return new Date(v[0], parseInt(v[1]) - 1, parseInt(v[2]) || 1);
70 return NaN;
71 };
72 var datepicker_hide = function() {
73 table.hidden = true;
74 table.style.display = "none";
75 };
76 var datepicker_show = function() {
77 table.hidden = false;
78 table.style.display = "table";
79 table.style.position = "absolute";
80 var r = input.getClientRects() || [];
81 if (r.length) {
82 table.style.left = String(r[0].left + window.pageXOffset) + "px";
83 table.style.top = String(r[0].top + input.offsetHeight + window.pageYOffset) + "px";
84 }
85 // scroll if outside window.
86 input.scrollIntoView();
87 };
88 var datepicker_nextmon = function(n) {
89 curdate = new Date(curdate.getFullYear(), curdate.getMonth() + n, 1);
90 };
91 var datepicker_render = function() {
92 datepicker_nextmon(0); // fix date.
93 var y = curdate.getFullYear(), m = curdate.getMonth();
94 header.innerHTML = datepicker_mons[m] + " " + String(y);
95
96 var startidx = curdate.getDay();
97 if (datepicker_isoweekdate)
98 startidx = (startidx + 6) % 7;
99
100 var tr = document.createElement("tr");
101 for (var i = 0; i < startidx; i++)
102 tr.appendChild(document.createElement("td"));
103
104 var endday = 0;
105 for (var i = 27; (new Date(y, m, i)).getMonth() == m; i++)
106 endday = i;
107
108 var pad0 = function(n) {
109 return (n < 10 ? "0" : "") + String(n);
110 };
111 var now = new Date();
112 var tbody = document.createElement("tbody");
113 var sel = !isNaN(seldate) ? (seldate.getTime() - seldate.getTimezoneOffset() * 60000) : NaN;
114 for (var i = 1; i <= endday; i++) {
115 if ((datepicker_isoweekdate && !(((i - 1 % 7) + startidx) % 7)) ||
116 (!datepicker_isoweekdate && !((i + startidx - 1) % 7))) {
117 if (tr.childNodes.length) {
118 tbody.appendChild(tr);
119 tr = document.createElement("tr");
120 }
121 }
122 var td = document.createElement("td");
123 td.setAttribute("data-value", String(y) + "-" + pad0(m + 1) + "-" + pad0(i));
124 td.appendChild(document.createTextNode(String(i)));
125
126 // check if valid date (enabled or disabled).
127 var classes = [];
128 var d = parsedateutc(td.getAttribute("data-value")) || 0;
129 if ((!isNaN(mindate) && d < mindate) ||
130 (!isNaN(maxdate) && d > maxdate)) {
131 classes.push("d");
132 } else {
133 classes.push("v");
134 // NOTE: onmousedown is handled before input.blur event.
135 td.addEventListener("mousedown", function(e) {
136 input.value = this.getAttribute("data-value");
137 curdate = seldate = datepicker_dateparse(input.value);
138 datepicker_hide();
139 return !!e.stopPropagation();
140 }, false);
141 }
142 // selected date?
143 if (!isNaN(sel) && sel >= d && sel < d + 86400000)
144 classes.push("sel");
145 // is date today?
146 if (now.getFullYear() == y && now.getMonth() == m && now.getDate() == i)
147 classes.push("today");
148 td.className = classes.join(" ");
149 tr.appendChild(td);
150 }
151 for (var i = endday; (startidx + i) % 7; i++)
152 tr.appendChild(document.createElement("td"));
153 tbody.appendChild(tr);
154
155 tbodyel.parentNode.replaceChild(tbody, tbodyel);
156 tbodyel = tbody;
157 };
158 var inparent = function(p, c) {
159 for (; c; c = c.parentNode)
160 if (c === p)
161 return true;
162 return false;
163 };
164 var pad0 = function(n) {
165 return (n < 10 ? "0" : "") + String(n);
166 };
167 var focuschange = function(e) {
168 if (e.which !== 27 && e.target == input) {
169 if (input.value.length) {
170 var d = datepicker_dateparse(input.value);
171 if (!isNaN(d))
172 curdate = seldate = d;
173 } else {
174 curdate = new Date();
175 }
176 datepicker_render();
177 datepicker_show();
178 } else if (!inparent(table, e.target)) {
179 // is in parent? ignore, format date onblur.
180 var d = datepicker_dateparse(this.value);
181 if (!isNaN(d)) {
182 curdate = seldate = d;
183 input.value = String(d.getFullYear()) + "-" +
184 pad0(d.getMonth() + 1) + "-" + pad0(d.getDate());
185 }
186 datepicker_hide();
187 }
188 };
189 document.addEventListener("click", focuschange, false);
190 input.addEventListener("input", focuschange, false);
191 input.addEventListener("focus", focuschange, false);
192 document.addEventListener("keyup", focuschange, false);
193
194 datepicker_render();
195 datepicker_hide();
196 document.body.appendChild(table);
197 }
198
199 // has native HTML5 date input type support? type is "text" if it isn't.
200 if (!(function() { var input = document.createElement("input"); try { input.type = "date"; return (input.type === "date"); } catch(e) {} return false; })()) {
201 var els = document.getElementsByClassName && document.getElementsByClassName("date") || [];
202 for (var i = 0; i < els.length; i++)
203 if (els[i].tagName.toLowerCase() === "input")
204 datepicker_init(els[i]);
205 }