[Calendar Date Picker] Bug where Initial Date < today

[Calendar Date Picker] Bug where Initial Date < today

  
Forge Component
(0)
Published on 2017-04-03 by Ravi Kumar Vakkalanka
0 votes
Published on 2017-04-03 by Ravi Kumar Vakkalanka

Hi,

I've discovered that there is a bug in this component. Any chance you could have a look at it?

If you set the initial date parameter for the calendar date picker to a date earlier than today, when the user clicks on it, it doesn't allow you to select another date within the month. You have to change the month and go back to today to then be able to select a date again.

To replicate the issue, open the HomeScreen from the project and change the settings of the Select Date (Disable all dates less than today) input widget. (Id date3.Id)

Change the InitialDate property to be AddDays(CurrDate(), -1) then publish, open the web page and try and change the date of the third text box.

I think I've found a fix.

Cutting and pasting the javascript in to an editor with line numbers, if you move line 1208 to below 1204, then that seems to fix the problem. Whether or not it is correct, I don't know.

I believe that the init function is wrong: 

Original version - see line highlighted in orange

Calendar.prototype._init = function (firstDayOfWeek, date) {
    var today = new Date(),
        TY = today.getFullYear(),
        TM = today.getMonth(),
        TD = today.getDate();
    this.table.style.visibility = "hidden";
    var year = date.getFullYear();
    if (year < this.minYear) {
        year = this.minYear;
        date.setFullYear(year);
    } else if (year > this.maxYear) {
        year = this.maxYear;
        date.setFullYear(year);
    }
    this.firstDayOfWeek = firstDayOfWeek;
    this.date = new Date(date);
    var month = date.getMonth();
    var mday = date.getDate();
    var no_days = date.getMonthDays();

    // calendar voodoo for computing the first day that would actually be
    // displayed in the calendar, even if it's from the previous month.
    // WARNING: this is magic. ;-)
    date.setDate(1);
    var day1 = (date.getDay() - this.firstDayOfWeek) % 7;
    if (day1 < 0){
        day1 += 7;
    }
    date.setDate(-day1);
    date.setDate(date.getDate() + 1);

    var row = this.tbody.firstChild;
    var MN = Calendar._SMN[month];
    var ar_days = this.ar_days = new Array();
    var weekend = Calendar._TT["WEEKEND"];
    var dates = this.multiple ? (this.datesCells = {}) : null;
    for (var i = 0; i < 6; ++i, row = row.nextSibling) {
        var cell = row.firstChild;
        if (this.weekNumbers) {
            cell.className = "day wn";
            cell.innerHTML = date.getWeekNumber();
            cell = cell.nextSibling;
        }
        row.className = "daysrow";
        var previousDay;
        var hasdays = false, iday, dpos = ar_days[i] = [];
        for (var j = 0; j < 7; ++j, cell = cell.nextSibling, date.setDate(iday + 1)) {
            iday = date.getDate();
            if (iday == previousDay) {
                date.setDate(iday + 1);
                iday = date.getDate();
            } else if (date.getHours() != 0) {
                date.setHours(0);
            }
            var wday = date.getDay();
            cell.className = "day";
            cell.pos = i << 4 | j;
            dpos[j] = cell;
            var current_month = (date.getMonth() == month);
            if (!current_month) {
                if (this.showsOtherMonths) {
                    cell.className += " othermonth";
                    cell.otherMonth = true;
                } else {
                    cell.className = "emptycell";
                    cell.innerHTML = " ";
                    cell.disabled = true;
                    continue;
                }
            } else {
                cell.otherMonth = false;
                hasdays = true;
            }
            cell.disabled = false;
            cell.innerHTML = this.getDateText ? this.getDateText(date, iday) : iday;
            previousDay = cell.innerHTML;
            if (dates)
                dates[date.print("%Y%m%d")] = cell;
            if (this.getDateStatus) {
                var status = this.getDateStatus(date, year, month, iday);
                if (this.getDateToolTip) {
                    var toolTip = this.getDateToolTip(date, year, month, iday);
                    if (toolTip)
                        cell.title = toolTip;
                }
                if (status === true) {
                    cell.className += " disabled";
                    cell.disabled = true;
                } else {
                    if (/disabled/i.test(status))
                        cell.disabled = true;
                    cell.className += " " + status;
                }
            }
            if (!cell.disabled) {
                cell.caldate = new Date(date);
                cell.ttip = "_";
                if (!this.multiple && current_month
                    && iday == mday && this.hiliteToday) {
                    cell.className += " selected";
                    this.currentDateEl = cell;
                }
                if (date.getFullYear() == TY &&
                    date.getMonth() == TM &&
                    iday == TD) {
                    cell.className += " today";
                    cell.ttip += Calendar._TT["PART_TODAY"];
                }
                if (weekend.indexOf(wday.toString()) != -1)
                    cell.className += cell.otherMonth ? " oweekend" : " weekend";
            }
        }
        if (!(hasdays || this.showsOtherMonths))
            row.className = "emptyrow";
    }
    this.title.innerHTML = Calendar._MN[month] + ", " + year;
    this.onSetTime();
    this.table.style.visibility = "visible";
    this._initMultipleDates();
    // PROFILE
    // this.tooltips.innerHTML = "Generated in " + ((new Date()) - today) + " ms";
};

Fixed version - see line highlighted in red

Calendar.prototype._init = function (firstDayOfWeek, date) {
 var today = new Date(),
  TY = today.getFullYear(),
  TM = today.getMonth(),
  TD = today.getDate();
 this.table.style.visibility = "hidden";
 var year = date.getFullYear();
 if (year < this.minYear) {
  year = this.minYear;
  date.setFullYear(year);
 } else if (year > this.maxYear) {
  year = this.maxYear;
  date.setFullYear(year);
 }
 this.firstDayOfWeek = firstDayOfWeek;
 this.date = new Date(date);
 var month = date.getMonth();
 var mday = date.getDate();
 var no_days = date.getMonthDays();

 // calendar voodoo for computing the first day that would actually be
 // displayed in the calendar, even if it's from the previous month.
 // WARNING: this is magic. ;-)
 date.setDate(1);
 var day1 = (date.getDay() - this.firstDayOfWeek) % 7;
 if (day1 < 0){
   day1 += 7;
 }
 date.setDate(-day1);
 date.setDate(date.getDate() + 1);

 var row = this.tbody.firstChild;
 var MN = Calendar._SMN[month];
 var ar_days = this.ar_days = new Array();
 var weekend = Calendar._TT["WEEKEND"];
 var dates = this.multiple ? (this.datesCells = {}) : null;
 for (var i = 0; i < 6; ++i, row = row.nextSibling) {
  var cell = row.firstChild;
  if (this.weekNumbers) {
   cell.className = "day wn";
   cell.innerHTML = date.getWeekNumber();
   cell = cell.nextSibling;
  }
  row.className = "daysrow";
  var previousDay;
  var hasdays = false, iday, dpos = ar_days[i] = [];
  for (var j = 0; j < 7; ++j, cell = cell.nextSibling, date.setDate(iday + 1)) {
   iday = date.getDate();
   if (iday == previousDay) {
    date.setDate(iday + 1);
    iday = date.getDate();
   } else if (date.getHours() != 0) {
       date.setHours(0);
   }
   var wday = date.getDay();
   cell.className = "day";
   cell.pos = i << 4 | j;
   dpos[j] = cell;
   var current_month = (date.getMonth() == month);
   if (!current_month) {
    if (this.showsOtherMonths) {
     cell.className += " othermonth";
     cell.otherMonth = true;
    } else {
     cell.className = "emptycell";
     cell.innerHTML = " ";
     cell.disabled = true;
     continue;
    }
   } else {
    cell.otherMonth = false;
    hasdays = true;
   }
   cell.disabled = false;
   cell.innerHTML = this.getDateText ? this.getDateText(date, iday) : iday;
   previousDay = cell.innerHTML;
   if (dates)
    dates[date.print("%Y%m%d")] = cell;
   if (this.getDateStatus) {
    var status = this.getDateStatus(date, year, month, iday);
    if (this.getDateToolTip) {
     var toolTip = this.getDateToolTip(date, year, month, iday);
     if (toolTip)
      cell.title = toolTip;
    }
    if (status === true) {
     cell.className += " disabled";
     cell.disabled = true;
    } else {
     if (/disabled/i.test(status))
      cell.disabled = true;
     cell.className += " " + status;
    }
   }
   if (!cell.disabled) {
    cell.caldate = new Date(date);
    cell.ttip = "_";
    this.currentDateEl = cell;
    if (!this.multiple && current_month
        && iday == mday && this.hiliteToday) {
     cell.className += " selected";
    }
    if (date.getFullYear() == TY &&
        date.getMonth() == TM &&
        iday == TD) {
     cell.className += " today";
     cell.ttip += Calendar._TT["PART_TODAY"];
    }
    if (weekend.indexOf(wday.toString()) != -1)
     cell.className += cell.otherMonth ? " oweekend" : " weekend";
   }
  }
  if (!(hasdays || this.showsOtherMonths))
   row.className = "emptyrow";
 }
 this.title.innerHTML = Calendar._MN[month] + ", " + year;
 this.onSetTime();
 this.table.style.visibility = "visible";
 this._initMultipleDates();
 // PROFILE
 // this.tooltips.innerHTML = "Generated in " + ((new Date()) - today) + " ms";
};