[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/media/system/js/fields/ -> calendar.js (source)

   1  /**
   2   * @copyright  (C) 2016 Open Source Matters, Inc. <https://www.joomla.org>
   3   * @license    GNU General Public License version 2 or later; see LICENSE.txt
   4   */
   5  !(function(window, document){
   6      'use strict';
   7  
   8      var JoomlaCalendar = function (element) {
   9  
  10          // Initialize only if the element exists
  11          if (!element) {
  12              throw new Error("Calendar setup failed:\n  No valid element found, Please check your code");
  13          }
  14  
  15          if (typeof Date.parseFieldDate !== 'function') {
  16              throw new Error("Calendar setup failed:\n  No valid date helper, Please check your code");
  17          }
  18  
  19          if (element._joomlaCalendar) {
  20              throw new Error('JoomlaCalendar instance already exists for the element');
  21          }
  22  
  23          element._joomlaCalendar = this;
  24  
  25          var self = this;
  26  
  27          this.writable   = true;
  28          this.hidden     = true;
  29          this.params     = {};
  30          this.element    = element;
  31          this.inputField = element.getElementsByTagName('input')[0];
  32          this.button     = element.getElementsByTagName('button')[0];
  33  
  34          if (!this.inputField) {
  35              throw new Error("Calendar setup failed:\n  No valid input found, Please check your code");
  36          }
  37  
  38          // Prepare the parameters
  39          this.params = {
  40              debug: false,
  41              clicked: false,
  42              element: {style: {display: "none"}},
  43              writable: true,
  44          };
  45  
  46          // Localisation strings
  47          var _t = Joomla.Text._;
  48          this.strings = {
  49              today: _t('JLIB_HTML_BEHAVIOR_TODAY', 'Today'),
  50              wk: _t('JLIB_HTML_BEHAVIOR_WK', 'wk'),
  51              // ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
  52              days: ['SUNDAY', 'MONDAY', 'TUESDAY', 'WEDNESDAY', 'THURSDAY', 'FRIDAY', 'SATURDAY'],
  53              // ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
  54              shortDays: ['SUN', 'MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT'],
  55              // ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
  56              months: ['JANUARY', 'FEBRUARY', 'MARCH', 'APRIL', 'MAY', 'JUNE', 'JULY', 'AUGUST', 'SEPTEMBER', 'OCTOBER', 'NOVEMBER', 'DECEMBER'],
  57              // ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
  58              shortMonths: ['JANUARY_SHORT', 'FEBRUARY_SHORT', 'MARCH_SHORT', 'APRIL_SHORT', 'MAY_SHORT', 'JUNE_SHORT',
  59                  'JULY_SHORT', 'AUGUST_SHORT', 'SEPTEMBER_SHORT', 'OCTOBER_SHORT', 'NOVEMBER_SHORT', 'DECEMBER_SHORT',],
  60              am: _t('JLIB_HTML_BEHAVIOR_AM', 'am'),
  61              pm: _t('JLIB_HTML_BEHAVIOR_PM', 'pm'),
  62              exit: _t('JCLOSE', 'Close'),
  63              clear: _t('JCLEAR', 'Clear')
  64          };
  65  
  66          // Translate lists of Days, Months
  67          this.strings.days = this.strings.days.map(function (c){
  68              return _t(c);
  69          });
  70          this.strings.shortDays = this.strings.shortDays.map(function (c){
  71              return _t(c);
  72          });
  73          this.strings.months = this.strings.months.map(function (c){
  74              return _t(c);
  75          });
  76          this.strings.shortMonths = this.strings.shortMonths.map(function (c){
  77              return _t(c);
  78          });
  79  
  80          var btn = this.button,
  81              instanceParams = {
  82                  inputField      : this.inputField,
  83                  dateType        : btn.dataset.dateType || 'gregorian',
  84                  direction       : document.dir ? document.dir : document.getElementsByTagName("html")[0].getAttribute("dir"),
  85                  firstDayOfWeek  : btn.dataset.firstday ? parseInt(btn.dataset.firstday, 10) : 0,
  86                  dateFormat      : btn.dataset.dateFormat || "%Y-%m-%d %H:%M:%S",
  87                  weekend         : [0,6],
  88                  minYear         : 1000,
  89                  maxYear         : 2100,
  90                  time24          : true,
  91                  showsOthers     : true,
  92                  showsTime       : true,
  93                  weekNumbers     : true,
  94                  showsTodayBtn   : true,
  95                  compressedHeader: false,
  96              };
  97  
  98          if ('showOthers' in btn.dataset) {
  99              instanceParams.showsOthers = parseInt(btn.dataset.showOthers, 10) === 1;
 100          }
 101  
 102          if ('weekNumbers' in btn.dataset) {
 103              instanceParams.weekNumbers = parseInt(btn.dataset.weekNumbers, 10) === 1;
 104          }
 105  
 106          if ('onlyMonthsNav' in btn.dataset) {
 107              instanceParams.compressedHeader = parseInt(btn.dataset.onlyMonthsNav, 10) === 1;
 108          }
 109  
 110          if ('time24' in btn.dataset) {
 111              instanceParams.time24 = parseInt(btn.dataset.time24 , 10) === 24;
 112          }
 113  
 114          if ('showTime' in btn.dataset) {
 115              instanceParams.showsTime = parseInt(btn.dataset.showTime, 10) === 1;
 116          }
 117  
 118          if ('todayBtn' in btn.dataset) {
 119              instanceParams.showsTodayBtn = parseInt(btn.dataset.todayBtn, 10) === 1;
 120          }
 121  
 122          // Merge the parameters
 123          for (var param in instanceParams) {
 124              this.params[param] = instanceParams[param];
 125          }
 126  
 127          // Evaluate the min year
 128          if (btn.dataset.minYear) {
 129              self.params.minYear = parseInt(btn.dataset.minYear, 10);
 130          }
 131          // Evaluate the max year
 132          if (btn.dataset.maxYear) {
 133              self.params.maxYear = parseInt(btn.dataset.maxYear, 10);
 134          }
 135          // Evaluate the weekend days
 136          if (btn.dataset.weekend) {
 137              self.params.weekend = btn.dataset.weekend.split(',').map(function(item) { return parseInt(item, 10); });
 138          }
 139  
 140          // Legacy thing, days for RTL is reversed
 141          if (this.params.direction === 'rtl') {
 142              this.strings.days = this.strings.days.reverse();
 143              this.strings.shortDays = this.strings.shortDays.reverse();
 144          }
 145  
 146          // Other calendar may have a different order for months
 147          this.strings.months = Date.monthsToLocalOrder(this.strings.months, this.params.dateType);
 148          this.strings.shortMonths = Date.monthsToLocalOrder(this.strings.shortMonths, this.params.dateType);
 149  
 150          // Event handler need to define here, to be able access in current context
 151          this._dayMouseDown = function(event) {
 152              return self._handleDayMouseDown(event);
 153          };
 154          this._calKeyEvent = function(event) {
 155              return self._handleCalKeyEvent(event);
 156          };
 157          this._documentClick = function(event) {
 158              return self._handleDocumentClick(event);
 159          };
 160  
 161          // Set it up
 162          this.checkInputs();
 163  
 164          // For the fields with readonly tag calendar will not initiate fully
 165          if (this.inputField.getAttribute('readonly')) {
 166              return;
 167          }
 168  
 169          this._create();
 170          this._bindEvents();
 171      };
 172  
 173      JoomlaCalendar.prototype.checkInputs = function () {
 174          // Get the date from the input
 175          var inputAltValueDate = Date.parseFieldDate(this.inputField.getAttribute('data-alt-value'), this.params.dateFormat, 'gregorian', this.strings);
 176  
 177          if (this.inputField.value !== '') {
 178              this.date = inputAltValueDate;
 179              this.inputField.value = inputAltValueDate.print(this.params.dateFormat, this.params.dateType, true, this.strings);
 180          } else {
 181              this.date = new Date();
 182          }
 183      };
 184  
 185      /** Removes the calendar object from the DOM tree and destroys it and then recreates it. */
 186      JoomlaCalendar.prototype.recreate = function () {
 187          var element = this.element, el = element.querySelector('.js-calendar');
 188          if (el) {
 189              element._joomlaCalendar = null;
 190              el.parentNode.removeChild(el);
 191              new JoomlaCalendar(element);
 192          }
 193      };
 194  
 195      /** Time Control */
 196      JoomlaCalendar.prototype.updateTime = function (hours, mins, secs) {
 197          var self = this,
 198              date = self.date;
 199  
 200          var d = self.date.getLocalDate(self.params.dateType),
 201              m = self.date.getLocalMonth(self.params.dateType),
 202              y = self.date.getLocalFullYear(self.params.dateType),
 203              ampm = this.inputField.parentNode.parentNode.querySelectorAll('.time-ampm')[0];
 204  
 205          if (!self.params.time24) {
 206              if (/pm/i.test(ampm.value) && hours < 12) {
 207                  hours = parseInt(hours) + 12;
 208              } else if (/am/i.test(ampm.value) && hours == 12) {
 209                  hours = 0;
 210              }
 211          }
 212  
 213          date.setHours(hours);
 214          date.setMinutes(parseInt(mins, 10));
 215          date.setSeconds(date.getSeconds());
 216          date.setLocalFullYear(self.params.dateType, y);
 217          date.setLocalMonth(self.params.dateType, m);
 218          date.setLocalDate(self.params.dateType, d);
 219          self.dateClicked = false;
 220  
 221          this.callHandler();
 222      };
 223  
 224      /** Method to set the date to the given date object */
 225      JoomlaCalendar.prototype.setDate = function (date) {
 226          if (!date.equalsTo(this.date)) {
 227              this.date = date;
 228              this.processCalendar(this.params.firstDayOfWeek, date);
 229          }
 230      };
 231  
 232      /** Method to set the current date by a number, step */
 233      JoomlaCalendar.prototype.moveCursorBy = function (step) {
 234          var date = new Date(this.date);
 235          date.setDate(date.getDate() - step);
 236          this.setDate(date);
 237      };
 238  
 239      /** Reset select element */
 240      JoomlaCalendar.prototype.resetSelected = function (element) {
 241          var options = element.options;
 242          var i = options.length;
 243          while (i--) {
 244              var current = options[i];
 245              if (current.selected) {
 246                  current.selected = false;
 247              }
 248          }
 249      };
 250  
 251      /** Method to set the value for the input field */
 252      JoomlaCalendar.prototype.callHandler = function () {
 253          /** Output the date **/
 254          this.inputField.setAttribute('data-alt-value', this.date.print(this.params.dateFormat, 'gregorian', false, this.strings));
 255  
 256          if (this.inputField.getAttribute('data-alt-value') && this.inputField.getAttribute('data-alt-value') !== '0000-00-00 00:00:00') {
 257              this.inputField.value = this.date.print(this.params.dateFormat, this.params.dateType, true, this.strings);
 258              if (this.params.dateType !== 'gregorian') {
 259                  this.inputField.setAttribute('data-local-value', this.date.print(this.params.dateFormat, this.params.dateType, true, this.strings));
 260              }
 261          }
 262          this.inputField.value = this.date.print(this.params.dateFormat, this.params.dateType, true, this.strings);
 263  
 264          if (this.dateClicked && typeof this.params.onUpdate === "function") {
 265              this.params.onUpdate(this);
 266          }
 267  
 268          this.inputField.dispatchEvent(new CustomEvent('change', {bubbles: true, cancelable: true}));
 269  
 270          if (this.dateClicked) {
 271              this.close();
 272          } else {
 273              this.processCalendar();
 274          }
 275      };
 276  
 277      /** Method to close/hide the calendar */
 278      JoomlaCalendar.prototype.close = function () {
 279          this.hide();
 280      };
 281  
 282      /** Method to show the calendar. */
 283      JoomlaCalendar.prototype.show = function () {
 284          this.checkInputs();
 285          this.inputField.focus();
 286          this.dropdownElement.classList.add('open');
 287          this.dropdownElement.removeAttribute('hidden');
 288          this.hidden = false;
 289  
 290          document.addEventListener("keydown", this._calKeyEvent, true);
 291          document.addEventListener("keypress", this._calKeyEvent, true);
 292          document.addEventListener("mousedown", this._documentClick, true);
 293  
 294          /** Move the calendar to top position if it doesn't fit below. */
 295          var containerTmp = this.element.querySelector('.js-calendar');
 296  
 297          if (window.innerHeight < containerTmp.getBoundingClientRect().bottom + 20) {
 298              containerTmp.style.marginTop = - (containerTmp.getBoundingClientRect().height + this.inputField.getBoundingClientRect().height) + "px";
 299          }
 300  
 301          this.processCalendar();
 302      };
 303  
 304      /** Method to hide the calendar. */
 305      JoomlaCalendar.prototype.hide = function () {
 306          document.removeEventListener("keydown", this._calKeyEvent, true);
 307          document.removeEventListener("keypress", this._calKeyEvent, true);
 308          document.removeEventListener("mousedown", this._documentClick, true);
 309  
 310          this.dropdownElement.classList.remove('open');
 311          this.dropdownElement.setAttribute('hidden', '');
 312          this.hidden = true;
 313      };
 314  
 315      /** Method to catch clicks outside of the calendar (used as close call) */
 316      JoomlaCalendar.prototype._handleDocumentClick = function (ev) {
 317          var el = ev.target;
 318  
 319          if (el !== null && !el.classList.contains('time')) {
 320              for (; el !== null && el !== this.element; el = el.parentNode);
 321          }
 322  
 323          if (el === null) {
 324              document.activeElement.blur();
 325              this.hide();
 326              return stopCalEvent(ev);
 327          }
 328      };
 329  
 330      /** Method to handle mouse click events (menus, buttons) **/
 331      JoomlaCalendar.prototype._handleDayMouseDown = function (ev) {
 332          var self = this,
 333              el = ev.currentTarget,
 334              target = ev.target || ev.srcElement;
 335  
 336          if (target && target.hasAttribute('data-action')) {
 337              return;
 338          }
 339  
 340          if (el.nodeName !== 'TD') {                         // A bootstrap inner button was pressed?
 341              var testel = el.getParent('TD');
 342              if (testel.nodeName === 'TD') {                 // Yes so use that element's td
 343                  el = testel;
 344              } else {                                        // No - try to find the table this way
 345                  el = el.getParent('TD');
 346                  if (el.classList.contains('js-calendar')) {
 347                      el = el.getElementsByTagName('table')[0];
 348                  }
 349              }
 350          } else {                                            // Check that doesn't have a button and is not a day td
 351              if (!(target.classList.contains('js-btn')) && !el.classList.contains('day') && !el.classList.contains('title')) {
 352                  return;
 353              }
 354          }
 355  
 356          if (!el || el.disabled) {
 357              return false;
 358          }
 359  
 360          if (typeof el.navtype === "undefined" || el.navtype !== 300) {
 361              if (el.navtype === 50) { el._current = el.innerHTML; }
 362  
 363              if (target === el || target.parentNode === el) { self.cellClick(el, ev); }
 364  
 365              var mon = null;
 366              if (typeof el.month !== "undefined") {
 367                  mon = el;
 368              }
 369              if (typeof el.parentNode.month !== "undefined") {
 370                  mon = el.parentNode;
 371              }
 372              var date = null;
 373              if (mon) {
 374                  date = new Date(self.date);
 375                  if (mon.month !== date.getLocalMonth(self.params.dateType)) {
 376                      date.setLocalMonth(self.params.dateType, mon.month);
 377                      self.setDate(date);
 378                      self.dateClicked = false;
 379                      this.callHandler();
 380                  }
 381              } else {
 382                  var year = null;
 383                  if (typeof el.year !== "undefined") {
 384                      year = target;
 385                  }
 386                  if (typeof el.parentNode.year !== "undefined") {
 387                      year = target.parentNode;
 388                  }
 389                  if (year) {
 390                      date = new Date(self.date);
 391                      if (year.year !== date.getLocalFullYear(self.params.dateType)) {
 392                          date.setFullYear(self.params.dateType, year.year);
 393                          self.setDate(date);
 394                          self.dateClicked = false;
 395                          this.callHandler();
 396                      }
 397                  }
 398              }
 399          }
 400  
 401          return stopCalEvent(ev);
 402      };
 403  
 404      /** Method to handle mouse click events (dates) **/
 405      JoomlaCalendar.prototype.cellClick = function (el, ev) {
 406          var self = this,
 407              closing = false,
 408              newdate = false,
 409              date = null;
 410  
 411          if (typeof el.navtype === "undefined") {
 412              if (self.currentDateEl) {
 413                  el.classList.add("selected");
 414                  self.currentDateEl = el.caldate;
 415                  closing = (self.currentDateEl === el.caldate);
 416                  if (!closing) {
 417                      self.currentDateEl = el.caldate;
 418                  }
 419              }
 420              self.date.setLocalDateOnly('gregorian', el.caldate);
 421              var other_month = !(self.dateClicked = !el.otherMonth);
 422              if (self.currentDateEl) { newdate = !el.disabled; }
 423              if (other_month) {
 424                  this.processCalendar();
 425              }
 426          } else {
 427              date = new Date(self.date);
 428              self.dateClicked = false;
 429              var year = date.getOtherFullYear(self.params.dateType), mon = date.getLocalMonth(self.params.dateType);
 430              switch (el.navtype) {
 431                  case 400:
 432                      break;
 433                  case -2:                                                                             // Prev year
 434                      if (!self.params.compressedHeader) {
 435                          if (year > self.params.minYear) {
 436                              date.setOtherFullYear(self.params.dateType, year - 1);
 437                          }
 438                      }
 439                      break;
 440                  case -1:                                                                             // Prev month
 441                      var day = date.getLocalDate(self.params.dateType);
 442                      if (mon > 0) {
 443                          var max = date.getLocalMonthDays(self.params.dateType, mon - 1);
 444                          if (day > max) {
 445                              date.setLocalDate(self.params.dateType, max);
 446                          }
 447                          date.setLocalMonth(self.params.dateType, mon - 1);
 448                      } else if (year-- > self.params.minYear) {
 449                          date.setOtherFullYear(self.params.dateType, year);
 450                          var max = date.getLocalMonthDays(self.params.dateType, 11);
 451                          if (day > max) {
 452                              date.setLocalDate(self.params.dateType, max);
 453                          }
 454                          date.setLocalMonth(self.params.dateType, 11);
 455                      }
 456                      break;
 457                  case 1:                                                                             // Next month
 458                      var day = date.getLocalDate(self.params.dateType);
 459                      if (mon < 11) {
 460                          var max = date.getLocalMonthDays(self.params.dateType, mon + 1);
 461                          if (day > max) {
 462                              date.setLocalDate(self.params.dateType, max);
 463                          }
 464                          date.setLocalMonth(self.params.dateType, mon + 1);
 465                      } else if (year < self.params.maxYear) {
 466                          date.setOtherFullYear(self.params.dateType, year + 1);
 467                          var max = date.getLocalMonthDays(self.params.dateType, 0);
 468                          if (day > max) {
 469                              date.setLocalDate(self.params.dateType, max);
 470                          }
 471                          date.setLocalMonth(self.params.dateType, 0);
 472                      }
 473                      break;
 474                  case 2:                                                                             // Next year
 475                      if (!self.params.compressedHeader)
 476                          if (year < self.params.maxYear) {
 477                              date.setOtherFullYear(self.params.dateType, year + 1);
 478                          }
 479                      break;
 480                  case 0:                                                                             // Today
 481                      break;
 482              }
 483  
 484              if (!date.equalsTo(self.date)) {
 485                  this.setDate(date);
 486                  newdate = true;
 487              } else if (el.navtype === 0) {
 488                  newdate = closing = true;
 489              }
 490          }
 491  
 492          if (newdate) {
 493              if (self.params.showsTime) {
 494                  this.dateClicked = false;
 495              }
 496              ev && this.callHandler();
 497          }
 498  
 499          el.classList.remove("hilite");
 500  
 501          if (closing && !self.params.showsTime) {
 502              self.dateClicked = false;
 503              ev && this.close();
 504          }
 505      };
 506  
 507      /** Method to handle keyboard click events **/
 508      JoomlaCalendar.prototype._handleCalKeyEvent = function (ev) {
 509          var self = this,
 510              K = ev.keyCode;
 511  
 512          // Get value from input
 513          if (ev.target === this.inputField && (K === 13 || K === 9)) {
 514              this.close();
 515          }
 516  
 517          if (self.params.direction === 'rtl') {
 518              if (K === 37) {
 519                  K = 39;
 520              } else if (K === 39) {
 521                  K = 37;
 522              }
 523          }
 524  
 525          if (K === 32) {                                // KEY Shift + space (now)
 526              if (ev.shiftKey) {
 527                  ev.preventDefault();
 528                  this.cellClick(self._nav_now, ev);
 529                  self.close();
 530              }
 531          }
 532          if (K === 27) {                                // KEY esc (close);
 533              this.close();
 534          }
 535          if (K === 38) {                                // KEY up (previous week)
 536              this.moveCursorBy(7);
 537          }
 538          if (K === 40) {                                // KEY down (next week)
 539              this.moveCursorBy( -7);
 540          }
 541          if (K === 37) {                                // KEY left (previous day)
 542              this.moveCursorBy(1);
 543          }
 544          if (K === 39) {                                // KEY right (next day)
 545              this.moveCursorBy( -1);
 546          }
 547          if (ev.target === this.inputField && !(K>48 || K<57 || K===186 || K===189 || K===190 || K===32)) {
 548              return stopCalEvent(ev);
 549          }
 550      };
 551  
 552      /** Method to create the html structure of the calendar */
 553      JoomlaCalendar.prototype._create = function () {
 554          var self   = this,
 555              parent = this.element,
 556              table  = createElement("table"),
 557              div    = createElement("div");
 558  
 559          this.table = table;
 560          table.className = 'table';
 561          table.style.marginBottom = 0;
 562  
 563          this.dropdownElement = div;
 564          parent.appendChild(div);
 565  
 566          if (this.params.direction) {
 567              div.style.direction = this.params.direction;
 568          }
 569  
 570          div.className = 'js-calendar';
 571          div.style.position = "absolute";
 572          div.style.boxShadow = "0 0 70px 0 rgba(0,0,0,0.67)";
 573          div.style.minWidth = this.inputField.width;
 574          div.style.padding = '0';
 575          div.setAttribute('hidden', '');
 576          div.style.left = "auto";
 577          div.style.top = "auto";
 578          div.style.zIndex = 1060;
 579          div.style.borderRadius = "20px";
 580  
 581          this.wrapper = createElement('div');
 582          this.wrapper.className = 'calendar-container';
 583          div.appendChild(this.wrapper);
 584          this.wrapper.appendChild(table);
 585  
 586          var thead = createElement("thead", table);
 587          thead.className = 'calendar-header';
 588  
 589          var cell = null,
 590              row  = null,
 591              cal  = this,
 592              hh   = function (text, cs, navtype, node, styles, classes, attributes) {
 593                  node = node ? node : "td";
 594                  styles = styles ? styles : {};
 595                  cell = createElement(node, row);
 596                  if (cs) {
 597                      classes = classes ? 'class="' + classes + '"' : '';
 598                  cell.colSpan = cs;
 599                  }
 600  
 601                  for (var key in styles) {
 602                      cell.style[key] = styles[key];
 603                  }
 604                  for (var key in attributes) {
 605                      cell.setAttribute(key, attributes[key]);
 606                  }
 607                  if (navtype !== 0 && Math.abs(navtype) <= 2) {
 608                      cell.className += " nav";
 609                  }
 610  
 611                  if (cs) {
 612                      cell.addEventListener("mousedown", self._dayMouseDown, true);
 613                  }
 614  
 615                  cell.calendar = cal;
 616                  cell.navtype = navtype;
 617                  if (navtype !== 0 && Math.abs(navtype) <= 2) {
 618                      cell.innerHTML = Joomla.sanitizeHtml("<a " + classes + " style='display:inline;padding:2px 6px;cursor:pointer;text-decoration:none;' unselectable='on'>" + text + "</a>");
 619                  } else {
 620                      cell.innerHTML = cs ? Joomla.sanitizeHtml("<div unselectable='on'" + classes + ">" + text + "</div>") : Joomla.sanitizeHtml(text);
 621                      if (!cs && classes) {
 622                          cell.className = classes;
 623                      }
 624                  }
 625                  return cell;
 626              };
 627  
 628          if (this.params.compressedHeader === false) {                                                        // Head - year
 629              row = createElement("tr", thead);
 630              row.className = "calendar-head-row";
 631              this._nav_py = hh("&lsaquo;", 1, -2, '', {"text-align": "center", "font-size": "18px", "line-height": "18px"}, 'js-btn btn-prev-year');                   // Previous year button
 632              this.title = hh('<div style="text-align:center;font-size:18px"><span></span></div>', this.params.weekNumbers ? 6 : 5, 300);
 633              this.title.className = "title";
 634              this._nav_ny = hh(" &rsaquo;", 1, 2, '', {"text-align": "center", "font-size": "18px", "line-height": "18px"}, 'js-btn btn-next-year');                   // Next year button
 635          }
 636  
 637          row = createElement("tr", thead);                                                                   // Head - month
 638          row.className = "calendar-head-row";
 639          this._nav_pm = hh("&lsaquo;", 1, -1, '', {"text-align": "center", "font-size": "2em", "line-height": "1em"}, 'js-btn btn-prev-month');                       // Previous month button
 640          this._nav_month = hh('<div style="text-align:center;font-size:1.2em"><span></span></div>', this.params.weekNumbers ? 6 : 5, 888, 'td', {'textAlign': 'center'});
 641          this._nav_month.className = "title";
 642          this._nav_nm = hh(" &rsaquo;", 1, 1, '', {"text-align": "center", "font-size": "2em", "line-height": "1em"}, 'js-btn btn-next-month');                       // Next month button
 643  
 644          row = createElement("tr", thead);                                                                   // day names
 645          row.className = self.params.weekNumbers ? "daynames wk" : "daynames";
 646          if (this.params.weekNumbers) {
 647              cell = createElement("td", row);
 648              cell.className = "day-name wn";
 649              cell.textContent = self.strings.wk;
 650          }
 651          for (var i = 7; i > 0; --i) {
 652              cell = createElement("td", row);
 653              if (!i) {
 654                  cell.calendar = self;
 655              }
 656          }
 657          this.firstdayname = (this.params.weekNumbers) ? row.firstChild.nextSibling : row.firstChild;
 658  
 659          var fdow = this.params.firstDayOfWeek,
 660              cell = this.firstdayname,
 661              weekend = this.params.weekend;
 662  
 663          for (var i = 0; i < 7; ++i) {
 664              var realday = (i + fdow) % 7;
 665              cell.classList.add("day-name");
 666              this.params.weekNumbers ? cell.classList.add('day-name-week') : '';
 667  
 668              if (i) {
 669                  cell.calendar = self;
 670                  cell.fdow = realday;
 671              }
 672              if (weekend.indexOf(weekend) !== -1) {
 673                  cell.classList.add("weekend");
 674              }
 675  
 676              cell.textContent = this.strings.shortDays[(i + fdow) % 7];
 677              cell = cell.nextSibling;
 678          }
 679  
 680          var tbody = createElement("tbody", table);
 681          this.tbody = tbody;
 682          for (i = 6; i > 0; --i) {
 683              row = createElement("tr", tbody);
 684              if (this.params.weekNumbers) {
 685                  cell = createElement("td", row);
 686              }
 687  
 688              for (var j = 7; j > 0; --j) {
 689                  cell = createElement("td", row);
 690                  cell.calendar = this;
 691                  cell.addEventListener("mousedown", this._dayMouseDown, true);
 692              }
 693          }
 694  
 695          if (this.params.showsTime) {
 696              row = createElement("tr", tbody);
 697              row.className = "time";
 698  
 699              cell = createElement("td", row);
 700              cell.className = "time time-title";
 701              cell.colSpan = 1;
 702              cell.style.verticalAlign = 'middle';
 703              cell.innerHTML = " ";
 704  
 705              var cell1 = createElement("td", row);
 706              cell1.className = "time hours-select";
 707              cell1.colSpan = 2;
 708  
 709              var cell2 = createElement("td", row);
 710              cell2.className = "time minutes-select";
 711              cell2.colSpan = 2;
 712  
 713              (function () {
 714  				function makeTimePart(className, selected, range_start, range_end, cellTml) {
 715                      var part = createElement("select", cellTml), num;
 716                      part.calendar  = self;
 717                      part.className =  className;
 718                      part.setAttribute('data-chosen', true); // avoid Chosen, hack
 719                      part.style.width = '100%';
 720                      part.navtype = 50;
 721                      part._range = [];
 722                      for (var i = range_start; i <= range_end; ++i) {
 723                          var txt, selAttr = '';
 724                          if (i === selected) {
 725                              selAttr = true;
 726                          }
 727                          if (i < 10 && range_end >= 10) {
 728                              num = '0' + i;
 729                              txt = Date.convertNumbers('0') + Date.convertNumbers(i);
 730                          } else {
 731                              num = '' + i;
 732                              txt = '' + Date.convertNumbers(i);
 733                          }
 734                          part.options.add(new Option(txt, num, selAttr, selAttr));
 735                      }
 736                      return part;
 737                  }
 738                  var hrs  = self.date.getHours(),
 739                      mins = self.date.getMinutes(),
 740                      t12  = !self.params.time24,
 741                      pm   = (self.date.getHours() > 12);
 742  
 743                  if (t12 && pm) {
 744                      hrs -= 12;
 745                  }
 746  
 747                  var H = makeTimePart("time time-hours", hrs, t12 ? 1 : 0, t12 ? 12 : 23, cell1),
 748                      M = makeTimePart("time time-minutes", mins, 0, 59, cell2),
 749                      AP = null;
 750  
 751                  cell = createElement("td", row);
 752                  cell.className = "time ampm-select";
 753                  cell.colSpan = self.params.weekNumbers ? 1 : 2;
 754  
 755                  if (t12) {
 756                      var selAttr = true,
 757                          altDate = Date.parseFieldDate(self.inputField.getAttribute('data-alt-value'), self.params.dateFormat, 'gregorian', self.strings);
 758                      pm = (altDate.getHours() >= 12);
 759  
 760                      var part = createElement("select", cell);
 761                      part.className = "time-ampm";
 762                      part.style.width = '100%';
 763                      part.options.add(new Option(self.strings.pm, "pm", pm ? selAttr : '', pm ? selAttr : ''));
 764                      part.options.add(new Option(self.strings.am, "am", pm ? '' : selAttr, pm ? '' : selAttr));
 765                      AP = part;
 766  
 767                      // Event listener for the am/pm select
 768                      AP.addEventListener("change", function (event) {
 769                          self.updateTime(event.target.parentNode.parentNode.childNodes[1].childNodes[0].value,
 770                              event.target.parentNode.parentNode.childNodes[2].childNodes[0].value,
 771                              event.target.parentNode.parentNode.childNodes[3].childNodes[0].value);
 772                      }, false);
 773                  } else {
 774                      cell.innerHTML = "&#160;";
 775                      cell.colSpan = self.params.weekNumbers ? 3 : 2;
 776                  }
 777  
 778                  H.addEventListener("change", function (event) {
 779                      self.updateTime(event.target.parentNode.parentNode.childNodes[1].childNodes[0].value,
 780                          event.target.parentNode.parentNode.childNodes[2].childNodes[0].value,
 781                          event.target.parentNode.parentNode.childNodes[3].childNodes[0].value);
 782                  }, false);
 783                  M.addEventListener("change", function (event) {
 784                      self.updateTime(event.target.parentNode.parentNode.childNodes[1].childNodes[0].value,
 785                          event.target.parentNode.parentNode.childNodes[2].childNodes[0].value,
 786                          event.target.parentNode.parentNode.childNodes[3].childNodes[0].value);
 787                  }, false);
 788              })();
 789          }
 790  
 791          row = createElement("div", this.wrapper);
 792          row.className = "buttons-wrapper btn-group";
 793  
 794          this._nav_clear = hh(this.strings.clear, '', 100, 'button', '', 'js-btn btn btn-clear', {"type": "button", "data-action": "clear"});
 795  
 796              var cleara = row.querySelector('[data-action="clear"]');
 797              cleara.addEventListener("click", function (e) {
 798                  e.preventDefault();
 799                  var days = self.table.querySelectorAll('td');
 800                  for (var i = 0; i < days.length; i++) {
 801                      if (days[i].classList.contains('selected')) {
 802                          days[i].classList.remove('selected');
 803                          break;
 804                      }
 805                  }
 806                  self.inputField.setAttribute('data-alt-value', "0000-00-00 00:00:00");
 807                  self.inputField.setAttribute('value', '');
 808                  self.inputField.value = '';
 809                  self.inputField.dispatchEvent(new CustomEvent('change', {bubbles: true, cancelable: true}));
 810              });
 811  
 812          if (this.params.showsTodayBtn) {
 813              this._nav_now = hh(this.strings.today, '', 0, 'button', '', 'js-btn btn btn-today', {"type": "button", "data-action": "today"});
 814  
 815              var todaya = this.wrapper.querySelector('[data-action="today"]');
 816              todaya.addEventListener('click', function (e) {
 817                  e.preventDefault();
 818                  self.date.setLocalDateOnly('gregorian', new Date());                                  // TODAY
 819                  self.dateClicked = true;
 820                  self.callHandler();
 821                  self.close();
 822              });
 823          }
 824  
 825          this._nav_exit = hh(this.strings.exit, '', 999, 'button', '', 'js-btn btn btn-exit', {"type": "button", "data-action": "exit"});
 826          var exita = this.wrapper.querySelector('[data-action="exit"]');
 827          exita.addEventListener('click', function (e) {
 828              e.preventDefault();
 829              if (!self.dateClicked) {
 830                  if (self.inputField.value) {
 831                      if (self.params.dateType !== 'gregorian') {
 832                          self.inputField.setAttribute('data-local-value', self.inputField.value);
 833                      }
 834                      if (typeof self.dateClicked === 'undefined') {
 835                          // value needs to be validated
 836                          self.inputField.setAttribute('data-alt-value', Date.parseFieldDate(self.inputField.value, self.params.dateFormat, self.params.dateType, self.strings)
 837                              .print(self.params.dateFormat, 'gregorian', false, self.strings));
 838                      } else {
 839                          self.inputField.setAttribute('data-alt-value', self.date.print(self.params.dateFormat, 'gregorian', false, self.strings));
 840                      }
 841                  } else {
 842                      self.inputField.setAttribute('data-alt-value', '0000-00-00 00:00:00');
 843                  }
 844                  self.date = Date.parseFieldDate(self.inputField.getAttribute('data-alt-value'), self.params.dateFormat, self.params.dateType, self.strings);
 845              }
 846              self.close();
 847          });
 848  
 849          this.processCalendar();
 850      };
 851  
 852      /** Method to append numbers to the calendar table */
 853      JoomlaCalendar.prototype.processCalendar = function () {
 854          this.table.style.visibility = "hidden";
 855  
 856          var firstDayOfWeek = this.params.firstDayOfWeek,
 857              date  = this.date,
 858              today = new Date(),
 859              TY    = today.getLocalFullYear(this.params.dateType),
 860              TM    = today.getLocalMonth(this.params.dateType),
 861              TD    = today.getLocalDate(this.params.dateType),
 862              year  = date.getOtherFullYear(this.params.dateType),
 863              hrs   = date.getHours(),
 864              mins  = date.getMinutes(),
 865              secs  = date.getSeconds(),
 866              t12   = !this.params.time24;
 867  
 868          if (year < this.params.minYear) {                                                                   // Check min,max year
 869              year = this.params.minYear;
 870              date.setOtherFullYear(this.params.dateType, year);
 871          } else if (year > this.params.maxYear) {
 872              year = this.params.maxYear;
 873              date.setOtherFullYear(this.params.dateType, year);
 874          }
 875  
 876          this.params.firstDayOfWeek = firstDayOfWeek;
 877          this.date = new Date(date);
 878  
 879          var month = date.getLocalMonth(this.params.dateType);
 880          var mday  = date.getLocalDate(this.params.dateType);
 881  
 882          // Compute the first day that would actually be displayed in the calendar, even if it's from the previous month.
 883          date.setLocalDate(this.params.dateType, 1);
 884          var day1 = (date.getLocalDay(this.params.dateType) - this.params.firstDayOfWeek) % 7;
 885  
 886          if (day1 < 0) {
 887              day1 += 7;
 888          }
 889  
 890          date.setLocalDate(this.params.dateType, - day1);
 891          date.setLocalDate(this.params.dateType, date.getLocalDate(this.params.dateType) + 1);
 892  
 893          var row = this.tbody.firstChild,
 894              ar_days = this.ar_days = new Array(),
 895              weekend = this.params.weekend,
 896              monthDays = parseInt(date.getLocalWeekDays(this.params.dateType));
 897  
 898          /** Fill the table **/
 899          for (var i = 0; i < monthDays; ++i, row = row.nextSibling) {
 900              var cell = row.firstChild;
 901              if (this.params.weekNumbers) {
 902                  cell.className = "day wn";
 903                  cell.textContent = date.getLocalWeekNumber(this.params.dateType);
 904                  cell = cell.nextSibling;
 905              }
 906  
 907              row.className = this.params.weekNumbers ? "daysrow wk" : "daysrow";
 908              var hasdays = false, iday,
 909                  dpos = ar_days[i] = [],
 910                  totalDays = monthDays + 1;
 911  
 912              for (var j = 0; j < totalDays; ++j, cell = cell.nextSibling, date.setLocalDate(this.params.dateType, iday + 1)) {
 913                  cell.className = "day";
 914                  cell.style['textAlign'] = 'center';
 915                  iday = date.getLocalDate(this.params.dateType);
 916                  var wday = date.getLocalDay(this.params.dateType);
 917                  cell.pos = i << 4 | j;
 918                  dpos[j] = cell;
 919                  var current_month = (date.getLocalMonth(this.params.dateType) === month);
 920                  if (!current_month) {
 921                      if (this.params.showsOthers) {
 922                          cell.className += " disabled othermonth ";
 923                          cell.otherMonth = true;
 924                      } else {
 925                          cell.className += " emptycell";
 926                          cell.innerHTML = "&#160;";
 927                          cell.disabled = true;
 928                          continue;
 929                      }
 930                  } else {
 931                      cell.otherMonth = false;
 932                      hasdays = true;
 933                      cell.style.cursor = "pointer";
 934                  }
 935                  cell.disabled = false;
 936                  cell.textContent = this.params.debug ? iday : Date.convertNumbers(iday); // translated day number for each cell
 937                  if (!cell.disabled) {
 938                      cell.caldate = new Date(date);
 939                      if (current_month && iday === mday) {
 940                          cell.className += " selected";
 941                          this.currentDateEl = cell;
 942                      }
 943                      if (date.getLocalFullYear(this.params.dateType) === TY && date.getLocalMonth(this.params.dateType) === TM && iday === TD) {
 944                          cell.className += " today";
 945                      }
 946                      if (weekend.indexOf(wday) !== -1)
 947                          cell.className += " weekend";
 948                  }
 949              }
 950              if (!(hasdays || this.params.showsOthers)) {
 951                  row.classList.add('hidden');
 952                  row.setAttribute('hidden', '');
 953                  row.className = "emptyrow";
 954              } else {
 955                  row.classList.remove('hidden');
 956                  row.removeAttribute('hidden', '');
 957              }
 958          }
 959  
 960          /* Set the time */
 961          if (this.params.showsTime) {
 962              if (hrs > 12 && t12) {
 963                  hrs -= 12;
 964              }
 965  
 966              hrs = (hrs < 10) ? "0" + hrs : hrs;
 967              mins = (mins < 10) ? "0" + mins : mins;
 968  
 969              var hoursEl = this.table.querySelector('.time-hours'),
 970                  minsEl = this.table.querySelector('.time-minutes');
 971  
 972              /* remove the selected class  for the hours*/
 973              this.resetSelected(hoursEl);
 974              if (!this.params.time24)
 975              {
 976                  hoursEl.value = (hrs == "00") ? "12" : hrs;
 977              }
 978              else
 979              {
 980                  hoursEl.value = hrs;
 981              }
 982  
 983              /* remove the selected class  for the minutes*/
 984              this.resetSelected(minsEl);
 985              minsEl.value = mins;
 986  
 987              if (!this.params.time24)
 988              {
 989                  var dateAlt = new Date(this.inputField.getAttribute('data-alt-value')),
 990                      ampmEl = this.table.querySelector('.time-ampm'),
 991                      hrsAlt = dateAlt.getHours();
 992  
 993                  if (hrsAlt > 12) {
 994                      /* remove the selected class  for the am-pm*/
 995                      this.resetSelected(ampmEl);
 996                      ampmEl.value = 'pm';
 997                  }
 998              }
 999          }
1000  
1001          if (!this.params.compressedHeader) {
1002              this._nav_month.getElementsByTagName('span')[0].textContent = this.params.debug ? month + ' ' + this.strings.months[month] : this.strings.months[month];
1003              this.title.getElementsByTagName('span')[0].textContent = this.params.debug ? year + ' ' +  Date.convertNumbers(year.toString()) : Date.convertNumbers(year.toString());
1004          } else {
1005              var tmpYear = Date.convertNumbers(year.toString());
1006              this._nav_month.getElementsByTagName('span')[0].textContent = !this.params.monthBefore  ? this.strings.months[month] + ' - ' + tmpYear : tmpYear + ' - ' + this.strings.months[month] ;
1007          }
1008          this.table.style.visibility = "visible";
1009      };
1010  
1011      /** Method to listen for the click event on the input button. **/
1012      JoomlaCalendar.prototype._bindEvents = function () {
1013          var self = this;
1014          this.inputField.addEventListener('blur', function(event) {
1015              var calObj = JoomlaCalendar.getCalObject(this)._joomlaCalendar;
1016  
1017              // If calendar is open we will handle the event elsewhere
1018              if (!calObj.dropdownElement.hasAttribute('hidden')) {
1019                  event.preventDefault();
1020                  return;
1021              }
1022  
1023              if (calObj) {
1024                  if (calObj.inputField.value) {
1025                      if (typeof calObj.params.dateClicked === 'undefined') {
1026                          calObj.inputField.setAttribute('data-local-value', calObj.inputField.value);
1027  
1028                          if (calObj.params.dateType !== 'gregorian') {
1029                              // We need to transform the date for the data-alt-value
1030                              var ndate, date = Date.parseFieldDate(calObj.inputField.value, calObj.params.dateFormat, calObj.params.dateType, calObj.strings);
1031                              ndate = Date.localCalToGregorian(date.getFullYear(), date.getMonth(), date.getDate());
1032                              date.setFullYear(ndate[0]);
1033                              date.setMonth(ndate[1]);
1034                              date.setDate(ndate[2]);
1035                              calObj.inputField.setAttribute('data-alt-value', date.print(calObj.params.dateFormat, 'gregorian', false, calObj.strings));
1036                          } else {
1037                              calObj.inputField.setAttribute('data-alt-value', Date.parseFieldDate(calObj.inputField.value, calObj.params.dateFormat, calObj.params.dateType, calObj.strings)
1038                                  .print(calObj.params.dateFormat, 'gregorian', false, calObj.strings));
1039                          }
1040                      } else {
1041                          calObj.inputField.setAttribute('data-alt-value', calObj.date.print(calObj.params.dateFormat, 'gregorian', false, calObj.strings));
1042                      }
1043                  } else {
1044                      calObj.inputField.setAttribute('data-alt-value', '0000-00-00 00:00:00');
1045                  }
1046                  calObj.date = Date.parseFieldDate(calObj.inputField.getAttribute('data-alt-value'), calObj.params.dateFormat, calObj.params.dateType, calObj.strings);
1047              }
1048  
1049              self.close();
1050          }, true);
1051          this.button.addEventListener('click', function() {
1052              self.show();
1053          }, false);
1054      };
1055  
1056      /** Helpers **/
1057      var stopCalEvent = function (ev) { ev || (ev = window.event);  ev.preventDefault(); ev.stopPropagation(); return false; };
1058      var createElement = function (type, parent) { var el = null; el = document.createElement(type); if (typeof parent !== "undefined") { parent.appendChild(el); } return el; };
1059      var isInt = function (input) { return !isNaN(input) && (function(x) { return (x | 0) === x; })(parseFloat(input)) };
1060      var getBoundary = function (input, type) { var date = new Date(); var y = date.getLocalFullYear(type); return y + input; };
1061  
1062      /** Method to get the active calendar element through any descendant element. */
1063      JoomlaCalendar.getCalObject = function(element) {
1064          if (!element) {
1065              return false;
1066          }
1067          while (element.parentNode) {
1068              element = element.parentNode;
1069              if (element.classList.contains('field-calendar')) {
1070                  return element;
1071              }
1072          }
1073          return false;
1074      };
1075  
1076      /**
1077       * Method to change input values with the data-alt-value values. This method is e.g. being called
1078       * by the onSubmit handler of the calendar fields form.
1079       */
1080      JoomlaCalendar.prototype.setAltValue = function() {
1081          var input = this.inputField;
1082          if (input.getAttribute('disabled')) return;
1083  
1084          // Set the value to the data-alt-value attribute, but only if it really has a value.
1085          input.value = (
1086              input.getAttribute('data-alt-value') && input.getAttribute('data-alt-value') !== '0000-00-00 00:00:00'
1087              ? input.getAttribute('data-alt-value')
1088              : ''
1089          );
1090      };
1091  
1092      /** Method to change the inputs before submit. **/
1093      JoomlaCalendar.onSubmit = function() {
1094          Joomla = window.Joomla || {};
1095          if (!Joomla.calendarProcessed) {
1096              Joomla.calendarProcessed = true;
1097              var elements = document.querySelectorAll(".field-calendar");
1098  
1099              for (var i = 0; i < elements.length; i++) {
1100                  var element  = elements[i],
1101                      instance = element._joomlaCalendar;
1102  
1103                  if (instance) {
1104                      instance.setAltValue();
1105                  }
1106              }
1107          }
1108      };
1109  
1110      /**
1111       * Init the Calendars on the page
1112       *
1113       * @param {Node}        element    The element node
1114       * @param {HTMLElement} container  The field container (optional)
1115       */
1116      JoomlaCalendar.init = function (element, container) {
1117  
1118          var instance = element._joomlaCalendar;
1119          if (!instance) {
1120              new JoomlaCalendar(element);
1121          } else {
1122              instance.recreate();
1123          }
1124  
1125          if (element && element.getElementsByTagName('input')[0] && element.getElementsByTagName('input')[0].form && !element.getElementsByTagName('input')[0].disabled) {
1126              element.getElementsByTagName('input')[0].form.addEventListener('submit', JoomlaCalendar.onSubmit);
1127          }
1128      };
1129  
1130      window.JoomlaCalendar = JoomlaCalendar;
1131  
1132      /**
1133       * Instantiate all the calendar fields when the document is ready/updated
1134       * @param {Event} event
1135       * @private
1136       */
1137  	function _initCalendars(event) {
1138          var elements = event.target.querySelectorAll(".field-calendar");
1139  
1140          for (var i = 0, l = elements.length; i < l; i++) {
1141              JoomlaCalendar.init(elements[i]);
1142          }
1143      }
1144      document.addEventListener("DOMContentLoaded", _initCalendars);
1145      document.addEventListener("joomla:updated", _initCalendars);
1146  
1147          /** B/C related code
1148           *  @deprecated 4.0.0
1149           */
1150          window.Calendar = {};
1151  
1152          /** B/C related code
1153           *  @deprecated 4.0.0
1154           */
1155          Calendar.setup = function(obj) {
1156  
1157              if (obj.inputField && document.getElementById(obj.inputField)) {
1158                  var element = document.getElementById(obj.inputField),
1159                      cal = element.parentNode.querySelectorAll('button')[0];
1160  
1161                  for (var property in obj) {
1162                      if (obj.hasOwnProperty(property)) {
1163                          switch (property) {
1164                              case 'ifFormat':
1165                                  if (cal) cal.setAttribute('data-dayformat', obj.ifFormat);
1166                                  break;
1167  
1168                              case 'firstDay':
1169                                  if (cal) cal.setAttribute('data-firstday', parseInt(obj.firstDay));
1170                                  break;
1171  
1172                              case 'weekNumbers':
1173                                  if (cal) cal.setAttribute('data-week-numbers', (obj.weekNumbers === "true" || obj.weekNumbers === true) ? '1' : '0');
1174                                  break;
1175  
1176                              case 'showOthers':
1177                                  if (cal) cal.setAttribute('data-show-others', (obj.showOthers === "true" || obj.showOthers === true) ? '1' : '0');
1178                                  break;
1179  
1180                              case 'showsTime':
1181                                  if (cal) cal.setAttribute('data-show-time', (obj.showsTime === "true" || obj.showsTime === true) ? '1' : '0');
1182                                  break;
1183  
1184                              case 'timeFormat':
1185                                  if (cal) cal.setAttribute('data-time-24', parseInt(obj.timeFormat));
1186                                  break;
1187  
1188                              case 'displayArea':
1189                              case 'inputField':
1190                              case 'button':
1191                              case 'eventName':
1192                              case 'daFormat':
1193                              case 'disableFunc':
1194                              case 'dateStatusFunc':
1195                              case 'dateTooltipFunc':
1196                              case 'dateText':
1197                              case 'align':
1198                              case 'range':
1199                              case 'flat':
1200                              case 'flatCallback':
1201                              case 'onSelect':
1202                              case 'onClose':
1203                              case 'onUpdate':
1204                              case 'date':
1205                              case 'electric':
1206                              case 'step':
1207                              case 'position':
1208                              case 'cache':
1209                              case 'multiple':
1210                                  break;
1211                          }
1212  
1213  
1214                      }
1215                  }
1216                  JoomlaCalendar.init(element.parentNode.parentNode);
1217              }
1218              return null;
1219          };
1220  
1221  })(window, document);


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer