简体   繁体   中英

Javascript Date Picker Calendar

I would like to be able to specify a default date in the date box before the user input.

The JavaScript for the calendar is:

/* ********************************************************************
 * Calendar Date Selector - v1.1
 *   Copyright (c) 2011 - GreyWyvern
 *
 *  - Licenced for free distribution under the BSDL
 *          http://www.opensource.org/licenses/bsd-license.php
 *
 * The Calendar Date Selector is the simplest date selection calendar
 * you will ever use! No need to insert any javascript into your HTML;
 * the script will automatically transform <input> elements with
 * attribute type="date" (HTML5) into calendar inputs, respecting both
 * min and max attributes as well. Your users then just click the input
 * to invoke the calendar input. Works in all major browsers.
 *
 * Customize the CSS, or date format used (see below), or not! This
 * script is completely ready to use as-is. Be sure to include the
 * calendar.css stylesheet in your HTML document as well.
 *
 */

(function calendarSelector() {
  var self = this;

  /* ******************************************************************
   * Select a Date Format
   *
   * The calendar script uses the same syntax as the PHP date()
   * function, however only the code characters listed below are
   * supported; mix and match them as you please with the following
   * caveat: The format you use MUST include one (and only one) value
   * from each of the Day, Month and Year lists or the calendar will
   * not function properly.
   *
   * Supported date format codes (see http://www.php.net/date): 
   *
   * Day: d, j
   * Month: m, n, F, M
   * Year: Y, y
   * Optional: D, l, S, w
   *
   * For the day name and month name codes, only the English language
   * representations are supported.
   *
   * Regardless of the date format you choose, the HTML5 date input
   * element only accepts source code values in the "Y-m-d" format, so
   * be sure to write them as such in your form HTML code.  This script
   * will rewrite the displayed value using the format given below,
   * which will also be the format sent to the server on submission.
   *
   * NOTE: If a user has javascript disabled, the value will default
   * to the Y-m-d format, so it's good practice to allow your server
   * side script to accept both.
   *
   * Example formats:
   *   - "Y-m-d"     => 2010-12-31 (script default)
   *   - "F jS, Y"   => December 31st, 2010
   *   - 'm/j/y"     => 12/31/10
   *   - 'Y-M-j"     => 2010-Dec-31
   *   - "D M j, Y"  => Fri Dec 31, 2010
   *
   */
  this.format = "D j M Y";

  this.weekStart = 0;  // 0 = Sunday, 1 = Monday


  /* ******************************************************************
   * Modified PHP date() implementation in Javascript
   *  by Carlos R. L. Rodrigues and co. - Much thanks!
   *    - http://phpjs.org/functions/date
   *
   */
  this.date = function(format, ts) {
    var jsd = (typeof ts === 'undefined') ? new Date() : (ts instanceof Date) ? new Date(ts) : new Date(ts * 1000);
    var fChr = /\\?([a-z])/gi, fChrCb = function (t, s) { return f[t] ? f[t]() : s; };
    var _pad = function (n, c) { return ((n = n + "").length < c) ? new Array((++c) - n.length).join("0") + n : n; };
    var txt_words = [
     "Sun", "Mon", "Tues", "Wednes", "Thurs", "Fri", "Satur",
     "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
    ], txt_ordin = {1: "st", 2: "nd", 3: "rd", 21: "st", 22: "nd", 23: "rd", 31: "st"};
    var f = { // Day
      d: function() { return _pad(f.j(), 2); },
      D: function() { return f.l().slice(0, 3); },
      j: function() { return jsd.getDate(); },
      l: function() { return txt_words[f.w()] + 'day'; },
      S: function() { return txt_ordin[f.j()] || 'th'; },
      w: function() { return jsd.getDay(); },
      // Month
      F: function() { return txt_words[6 + f.n()]; },
      m: function() { return _pad(f.n(), 2); },
      M: function() { return f.F().slice(0, 3); },
      n: function() { return jsd.getMonth() + 1; },
      // Year
      Y: function() { return jsd.getFullYear(); },
      y: function() { return (f.Y() + "").slice(-2); }
    };
    return format.replace(fChr, fChrCb);
  };

  // ***** Parse a date from a string *********************************
  this.parse = function(data, rtrn, format) {
    if (!data) return rtrn;
    if (!format) format = this.format; 
    var fChr = /\\?([a-z])/gi, fChrCb = function (t, s) { return f[t] ? f[t]() : s; }, ordr = [];
    var months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
    var f = { // Day
      d: function() { ordr.push("d"); return "(\\d\\d)"; },
      D: function() { return "(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)"; },
      j: function() { ordr.push("d"); return "(\\d\\d?)"; },
      l: function() { return "(?:Mon|Tues|Wednes|Thurs|Fri|Satur|Sun)day"; },
      S: function() { return "(?:st|nd|rd|th)"; },
      w: function() { return "\\d"; },
      // Month
      F: function() { ordr.push("M"); return "(January|February|March|April|May|June|July|August|September|October|November|December)"; },
      m: function() { ordr.push("m"); return "(\\d\\d)"; },
      M: function() { ordr.push("M"); return "(" + months.join("|") + ")"; },
      n: function() { ordr.push("m"); return "(\\d\\d?)"; },
      // Year
      Y: function() { ordr.push("y"); return "(\\d{4})"; },
      y: function() { ordr.push("y"); return "(\\d\\d)"; }
    };
    format = format.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
    var outp = data.match(new RegExp("^\\s*" + format.replace(fChr, fChrCb) + "\\s*$", ""));
    if (outp && ordr.length == 3) {
      for (var x = 0, val = []; x < ordr.length; x++) {
        switch (ordr[x]) {
          case "d": val[2] = parseInt(outp[x + 1], 10); break;
          case "m": val[1] = parseInt(outp[x + 1], 10) - 1; break;
          case "y": val[0] = parseInt(outp[x + 1], 10); break;
          case "M":
            for (var y = 0, o = outp[x + 1].slice(0, 3); y < months.length; y++)
              if (o == months[y]) val[1] = y;
        }
      } return new Date(val[0], val[1], val[2]);
    } else return rtrn;
  };

  // ***** Show the calendar ******************************************
  this.show = function(elem) {
    if (this.cal.parentNode == document.body && elem != this.elem) this.hide(false);
    if (this.cal.parentNode != document.body || elem != this.elem) {
      this.elem = elem;
      this.point = this.parse(elem.value, new Date());
      this.build();
      var cleft = ctop = 0, obj = elem;
      do { cleft += obj.offsetLeft; ctop += obj.offsetTop; } while (obj = obj.offsetParent);
      this.cal.style.left = cleft + "px";
      this.cal.style.top = (ctop + elem.offsetHeight) + "px";
      document.body.appendChild(this.cal);
      setTimeout(function() {
        _addListener(document.documentElement, 'click', self.listener = function() {
          self.hide(false);
        }, false);
      }, 0);
    } else this.hide(false);
  };

  // ***** Hide the calendar ******************************************
  this.hide = function(value) {
    if (typeof value == "string") this.elem.value = value;
    this.cal = document.body.removeChild(this.cal);
    _removeListener(document.documentElement, 'click', this.listener, false);
  };

  // ***** Build the body of the calendar *****************************
  this.build = function() {
    var mindt = (mindt = this.parse(this.elem.getAttribute('min'), false, "Y-m-d")) ? this.date("Ymd", mindt) : "";
    var maxdt = (maxdt = this.parse(this.elem.getAttribute('max'), false, "Y-m-d")) ? this.date("Ymd", maxdt) : "";
    var slctd = (slctd = this.parse(this.elem.value, false)) ? this.date("Ymd", slctd) : "";

    this.point.setDate(15);
    if (mindt) while (this.date("Ym", this.point) < mindt.substr(0, 6)) this.point.setMonth(this.point.getMonth() + 1);
    if (maxdt) while (this.date("Ym", this.point) > maxdt.substr(0, 6)) this.point.setMonth(this.point.getMonth() - 1);

    var day = new Date(this.point.getTime()), today = this.date("Ymd");
    day.setDate(1);
    day.setDate(1 - day.getDay() + this.weekStart);

    while (this.cal.tBody.firstChild) this.cal.tBody.removeChild(this.cal.tBody.firstChild);
    do {
      var tr = document.createElement('tr');
      for (var x = 0, ymd; x < 7; x++) {
        ymd = this.date("Ymd", day);
        var td = document.createElement('td');
            td.className = "";
            td.title = this.date("l", day);
            td.date = new Date(day.getTime());
          if ((!mindt || ymd >= mindt) && (!maxdt || ymd <= maxdt)) {
              td.className = "valid";
              td.onclick = function() { self.hide(self.date(self.format, this.date)); };
          } else td.className = "";
          if (ymd == slctd) td.className += " selected";
          if (day.getMonth() == this.point.getMonth()) {
            td.className += " month";
            if (ymd == today) td.className += " today";
            if (!day.getDay() || day.getDay() == 6) td.className += " weekend";
          } td.appendChild(document.createTextNode(day.getDate()));
          tr.appendChild(td);
        day.setDate(day.getDate() + 1);
      } this.cal.tBody.appendChild(tr);
    } while (day.getMonth() == this.point.getMonth());

    if (mindt) {
      mindt = (this.point.getFullYear() - mindt.substr(0, 4)) * 12 - parseInt(mindt.substr(4, 2), 10) + this.point.getMonth() + 1;
      this.cal.tHeads[0].className = (mindt < 1) ? "disabled" : "";
      this.cal.tHeads[1].getElementsByTagName('strong')[0].className = (mindt < 1) ? "disabled" : "";
    } this.cal.tHeads[1].getElementsByTagName('span')[0].firstChild.nodeValue = this.date("F, Y", point);
    if (maxdt) {
      maxdt = (this.point.getFullYear() - maxdt.substr(0, 4)) * 12 - parseInt(maxdt.substr(4, 2), 10) + this.point.getMonth() + 1;
      this.cal.tHeads[2].className = (maxdt > -1) ? "disabled" : "";
      this.cal.tHeads[1].getElementsByTagName('em')[0].className = (maxdt > -1) ? "disabled" : "";
    }
  };

  var _addListener = function(elem, type, listener, useCapture) {
    if (elem.addEventListener) {
      elem.addEventListener(type, listener, useCapture);
    } else if (elem.attachEvent) elem.attachEvent('on' + type, listener);
  };
  var _removeListener = function(elem, type, listener, useCapture) {
    if (elem.removeEventListener) {
      elem.removeEventListener(type, listener, useCapture);
    } else if (elem.detachEvent) elem.detachEvent('on' + type, listener);
  };

  var _isIE6 = /*@cc_on@if(@_jscript_version == 5.6)!@end@*/false;

  // Build the generic calendar container
  this.elem = false;
  this.cal = document.createElement('div');
  this.cal.id = "calendarSelector";
  var table = document.createElement('table');
      table.cellSpacing = 1;
    var thead = document.createElement('thead');
      var tr = document.createElement('tr');
        var td = document.createElement('td');
            td.appendChild(document.createTextNode((_isIE6) ? "<<" : "\u25C2\u25C2"));
            td.onclick = function() {
              if (this.className != "disabled") {
                self.point.setFullYear(self.point.getFullYear() - 1);
                self.build(); } };
          tr.appendChild(td);
        var th = document.createElement('th');
            th.colSpan = 5;
          var strong = document.createElement('strong');
              strong.appendChild(document.createTextNode((_isIE6) ? "<" : "\u25C2"));
              strong.onclick = function() {
                if (this.className != "disabled") {
                  self.point.setMonth(self.point.getMonth() - 1);
                  self.build(); } };
            th.appendChild(strong);
          var em = document.createElement('em');
              em.appendChild(document.createTextNode((_isIE6) ? ">" : "\u25B8"));
              em.onclick = function() {
                if (this.className != "disabled") {
                  self.point.setMonth(self.point.getMonth() + 1);
                  self.build(); } };
            th.appendChild(em);
          var span = document.createElement('span');
              span.appendChild(document.createTextNode("\u2014"));
            th.appendChild(span);
          tr.appendChild(th);
        var td = document.createElement('td');
            td.appendChild(document.createTextNode((_isIE6) ? ">>" : "\u25B8\u25B8"));
            td.onclick = function() {
              if (this.className != "disabled") {
                self.point.setFullYear(self.point.getFullYear() + 1);
                self.build(); } };
          tr.appendChild(td);
        thead.appendChild(tr);
      table.appendChild(thead);
    var tfoot = document.createElement("tfoot");
      var tr = document.createElement('tr');
        var td = document.createElement('td');
            td.colSpan = 2;
            td.appendChild(document.createTextNode('Today'));
            td.onclick = function() { self.hide(self.date(self.format)); };
          tr.appendChild(td);
        var td = document.createElement('td');
            td.colSpan = 3;
            td.appendChild(document.createTextNode('Cancel'));
            td.onclick = function() { self.hide(false); };
          tr.appendChild(td);
        var td = document.createElement('td');
            td.colSpan = 2;
            td.appendChild(document.createTextNode('Clear'));
            td.onclick = function() { self.hide(""); };
          tr.appendChild(td);
        tfoot.appendChild(tr);
      table.appendChild(tfoot);
      table.appendChild(this.cal.tBody = document.createElement('tbody'));
  this.cal.appendChild(table);
  this.cal.tHeads = thead.rows[0].cells;
  this.cal.onselectstart = function() { return false; };
  this.cal.unselectable = "on";
  this.cal.onclick = function(e) {
    e = e || event;
    if (e.stopPropagation) { e.stopPropagation(); } else e.cancelBubble = true;
  };
  if (window.opera) this.cal.onmousedown = function() { return false; };

  // ***** Apply listeners to applicable inputs
  _addListener(window, 'load', function() {
    for (var x = 0, inputs = document.getElementsByTagName('input'), val; x < inputs.length; x++) {
      if (inputs[x].getAttribute('type') == "date") {
        inputs[x].type = "text";
        inputs[x].readOnly = "readonly";
        inputs[x].onclick = function() { self.show(this); };

        if (val = this.parse(inputs[x].value, false, "Y-m-d")) {
          var mindt = this.parse(inputs[x].getAttribute('min'), false, "Y-m-d");
          var maxdt = this.parse(inputs[x].getAttribute('max'), false, "Y-m-d");
          if (mindt && val < mindt) val = mindt;
          if (maxdt && val > maxdt) val = maxdt;
          inputs[x].value = this.date(this.format, val);
        } else inputs[x].value = "";
      }
    }
  }, false);
})();

Then the line of HTML on the page is:

<input name="FromDate" type="date" value="<?php echo 'startdate'; ?>" size="16">

However the script forces the value to be blank. When the page opens the "startdate" flashes momentarily and then reverts to blank (when the JavaScript has fully loaded). If I comment out the line to the script, "startdate" appears in the box, no problem.

So it seems that something in the JavaScript reduces the value of the input field to blank or null. As I don't understand JavaScript at all, I hope someone can guide me to the line that needs to be changed.

您可以将php变量startdate替换为Ymd格式。

I figured that there is a bug in the plugin (else it should work as @U and me mentioned).

But as you are already displaying value from php, you can simply comment out the 5th line from the last(else part).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM