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 = "&lt;";
           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 = "&gt;";
           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] + "&nbsp;" + 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 }