diff --git a/app/assets/javascripts/discourse/components/date-picker.js.es6 b/app/assets/javascripts/discourse/components/date-picker.js.es6 index 906724ea43f..d1c8e4fcefd 100644 --- a/app/assets/javascripts/discourse/components/date-picker.js.es6 +++ b/app/assets/javascripts/discourse/components/date-picker.js.es6 @@ -3,17 +3,17 @@ import loadScript from "discourse/lib/load-script"; import { on } from "ember-addons/ember-computed-decorators"; export default Em.Component.extend({ - tagName: "input", - classNames: ["date-picker"], + classNames: ["date-picker-wrapper"], _picker: null, @on("didInsertElement") _loadDatePicker() { - const input = this.$()[0]; + const input = this.$(".date-picker")[0]; loadScript("/javascripts/pikaday.js").then(() => { - const default_opts = { + let default_opts = { field: input, + container: this.$()[0], format: "YYYY-MM-DD", defaultDate: moment().add(1, "day").toDate(), minDate: new Date(), @@ -29,7 +29,7 @@ export default Em.Component.extend({ this._picker = null; }, - _opts: function() { + _opts() { return null; } diff --git a/app/assets/javascripts/discourse/templates/components/date-picker.hbs b/app/assets/javascripts/discourse/templates/components/date-picker.hbs new file mode 100644 index 00000000000..7d9e48080a7 --- /dev/null +++ b/app/assets/javascripts/discourse/templates/components/date-picker.hbs @@ -0,0 +1 @@ + diff --git a/app/assets/stylesheets/common/base/topic-admin-menu.scss b/app/assets/stylesheets/common/base/topic-admin-menu.scss index 651c7ba203b..667496f9232 100644 --- a/app/assets/stylesheets/common/base/topic-admin-menu.scss +++ b/app/assets/stylesheets/common/base/topic-admin-menu.scss @@ -33,6 +33,15 @@ } } +.date-picker-wrapper { + display: inline-block; + position: relative; +} + +.pika-single { + position: absolute !important; +} + .modal-body.feature-topic { padding: 5px; max-height: 500px; diff --git a/public/javascripts/pikaday.js b/public/javascripts/pikaday.js index c0596d22d3b..bc0c64474e6 100644 --- a/public/javascripts/pikaday.js +++ b/public/javascripts/pikaday.js @@ -202,6 +202,9 @@ // first day of week (0: Sunday, 1: Monday etc) firstDay: 0, + // the default flag for moment's strict date parsing + formatStrict: false, + // the minimum/earliest date that can be selected minDate: null, // the maximum/latest date that can be selected @@ -230,6 +233,9 @@ // Render the month after year in the calendar title showMonthAfterYear: false, + // Render days of the calendar grid that fall in the next or previous month + showDaysInNextAndPreviousMonths: false, + // how many months are visible numberOfMonths: 1, @@ -274,10 +280,14 @@ renderDay = function(opts) { - if (opts.isEmpty) { - return ''; - } var arr = []; + if (opts.isEmpty) { + if (opts.showDaysInNextAndPreviousMonths) { + arr.push('is-outside-current-month'); + } else { + return ''; + } + } if (opts.isDisabled) { arr.push('is-disabled'); } @@ -417,7 +427,7 @@ return; } - if (!hasClass(target.parentNode, 'is-disabled')) { + if (!hasClass(target, 'is-disabled')) { if (hasClass(target, 'pika-button') && !hasClass(target, 'is-empty')) { self.setDate(new Date(target.getAttribute('data-pika-year'), target.getAttribute('data-pika-month'), target.getAttribute('data-pika-day'))); if (opts.bound) { @@ -472,7 +482,7 @@ return; } if (hasMoment) { - date = moment(opts.field.value, opts.format); + date = moment(opts.field.value, opts.format, opts.formatStrict); date = (date && date.isValid()) ? date.toDate() : null; } else { @@ -638,9 +648,7 @@ this.setMinDate(opts.minDate); } if (opts.maxDate) { - setToStartOfDay(opts.maxDate); - opts.maxYear = opts.maxDate.getFullYear(); - opts.maxMonth = opts.maxDate.getMonth(); + this.setMaxDate(opts.maxDate); } if (isArray(opts.yearRange)) { @@ -828,6 +836,7 @@ this._o.minDate = value; this._o.minYear = value.getFullYear(); this._o.minMonth = value.getMonth(); + this.draw(); }, /** @@ -835,7 +844,11 @@ */ setMaxDate: function(value) { + setToStartOfDay(value); this._o.maxDate = value; + this._o.maxYear = value.getFullYear(); + this._o.maxMonth = value.getMonth(); + this.draw(); }, setStartRange: function(value) @@ -967,6 +980,11 @@ before += 7; } } + var previousMonth = month === 0 ? 11 : month - 1, + nextMonth = month === 11 ? 0 : month + 1, + yearOfPreviousMonth = month === 0 ? year - 1 : year, + yearOfNextMonth = month === 11 ? year + 1 : year, + daysInPreviousMonth = getDaysInMonth(yearOfPreviousMonth, previousMonth); var cells = days + before, after = cells; while(after > 7) { @@ -979,24 +997,41 @@ isSelected = isDate(this._d) ? compareDates(day, this._d) : false, isToday = compareDates(day, now), isEmpty = i < before || i >= (days + before), + dayNumber = 1 + (i - before), + monthNumber = month, + yearNumber = year, isStartRange = opts.startRange && compareDates(opts.startRange, day), isEndRange = opts.endRange && compareDates(opts.endRange, day), isInRange = opts.startRange && opts.endRange && opts.startRange < day && day < opts.endRange, isDisabled = (opts.minDate && day < opts.minDate) || (opts.maxDate && day > opts.maxDate) || (opts.disableWeekends && isWeekend(day)) || - (opts.disableDayFn && opts.disableDayFn(day)), - dayConfig = { - day: 1 + (i - before), - month: month, - year: year, + (opts.disableDayFn && opts.disableDayFn(day)); + + if (isEmpty) { + if (i < before) { + dayNumber = daysInPreviousMonth + dayNumber; + monthNumber = previousMonth; + yearNumber = yearOfPreviousMonth; + } else { + dayNumber = dayNumber - days; + monthNumber = nextMonth; + yearNumber = yearOfNextMonth; + } + } + + var dayConfig = { + day: dayNumber, + month: monthNumber, + year: yearNumber, isSelected: isSelected, isToday: isToday, isDisabled: isDisabled, isEmpty: isEmpty, isStartRange: isStartRange, isEndRange: isEndRange, - isInRange: isInRange + isInRange: isInRange, + showDaysInNextAndPreviousMonths: opts.showDaysInNextAndPreviousMonths }; row.push(renderDay(dayConfig));