Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/apps/system/js/value_selector/date_picker.js
diff options
context:
space:
mode:
Diffstat (limited to 'apps/system/js/value_selector/date_picker.js')
-rw-r--r--apps/system/js/value_selector/date_picker.js568
1 files changed, 0 insertions, 568 deletions
diff --git a/apps/system/js/value_selector/date_picker.js b/apps/system/js/value_selector/date_picker.js
deleted file mode 100644
index 9cdd484..0000000
--- a/apps/system/js/value_selector/date_picker.js
+++ /dev/null
@@ -1,568 +0,0 @@
-/**
- * DatePicker is a html/js "widget" which will display
- * all the days of a given month and allow selection of
- * one specific day. It also implements controls to travel
- * between months and jump into arbitrary time.
- *
- * The DatePicker itself contains no UI for the controls.
- *
- * Example usage:
- *
- * // the container will have elements for the month
- * // added and removed from it.
- * var picker = new DatePicker(container);
- *
- * // EVENTS:
- *
- * // called when the user clicks a day in the calendar.
- * picker.onvaluechange = function(date) {}
- *
- * // called when the month of the calendar changes.
- * // NOTE: at this time this can only happen programmatically
- * // so there is only for control flow.
- * picker.onmonthchange = function(date) {}
- *
- * // display a given year/month/date on the calendar the month
- * // is zero based just like the JS date constructor.
- * picker.display(2012, 0, 2);
- *
- * // move to the next month.
- * picker.next();
- *
- * // move to the previous month
- * picker.previous();
- *
- */
-var DatePicker = (function() {
- 'use strict';
-
- const SELECTED = 'selected';
-
- var Calc = {
-
- NEXT_MONTH: 'next-month',
-
- OTHER_MONTH: 'other-month',
-
- PRESENT: 'present',
-
- FUTURE: 'future',
-
- PAST: 'past',
-
- get today() {
- return new Date();
- },
-
- daysInWeek: function() {
- //XXX: We need to localize this...
- return 7;
- },
-
- /**
- * Checks is given date is today.
- *
- * @param {Date} date compare.
- * @return {Boolean} true when today.
- */
- isToday: function(date) {
- return Calc.isSameDate(date, Calc.today);
- },
-
- /**
- * Checks if two date objects occur
- * on the same date (in the same month, year, day).
- * Disregards time.
- *
- * @param {Date} first date.
- * @param {Date} second date.
- * @return {Boolean} true when they are the same date.
- */
- isSameDate: function(first, second) {
- return first.getMonth() == second.getMonth() &&
- first.getDate() == second.getDate() &&
- first.getFullYear() == second.getFullYear();
- },
-
- /**
- * Returns an identifier for a specific
- * date in time for a given date
- *
- * @param {Date} date to get id for.
- * @return {String} identifier.
- */
- getDayId: function(date) {
- return [
- date.getFullYear(),
- date.getMonth(),
- date.getDate()
- ].join('-');
- },
-
- /**
- * Returns a date object from
- * a string id for a date.
- *
- * @param {String} id identifier for date.
- * @return {Date} date output.
- */
- dateFromId: function(id) {
- var parts = id.split('-');
- return new Date(parts[0], parts[1], parts[2]);
- },
-
- createDay: function(date, day, month, year) {
- return new Date(
- typeof year !== 'undefined' ? year : date.getFullYear(),
- typeof month !== 'undefined' ? month : date.getMonth(),
- typeof day !== 'undefined' ? day : date.getDate()
- );
- },
-
- /**
- * Finds localized week start date of given date.
- *
- * @param {Date} date any day the week.
- * @return {Date} first date in the week of given date.
- */
- getWeekStartDate: function(date) {
- var currentDay = date.getDay();
- var startDay = date.getDate() - currentDay;
-
- return Calc.createDay(date, startDay);
- },
-
- getWeekEndDate: function(date) {
- // TODO: There are localization problems
- // with this approach as we assume a 7 day week.
- var start = Calc.getWeekStartDate(date);
- start.setDate(start.getDate() + 7);
- start.setMilliseconds(-1);
-
- return start;
- },
-
- /**
- * Returns an array of dates objects.
- * Inclusive. First and last are
- * the given instances.
- *
- * @param {Date} start starting day.
- * @param {Date} end ending day.
- * @param {Boolean} includeTime include times start/end ?
- */
- daysBetween: function(start, end, includeTime) {
- if (!(start instanceof Date)) {
- throw new Error('start date must be an instanceof Date');
- }
-
- if (!(end instanceof Date)) {
- throw new Error('end date must be an instanceof Date');
- }
-
- if (start > end) {
- var tmp = end;
- end = start;
- start = tmp;
- tmp = null;
- }
-
- var list = [];
- var last = start.getDate();
- var cur;
-
- // for infinite loop protection.
- var max = 500;
- var macInc = 0;
-
- while (macInc++ < max) {
- var next = new Date(
- start.getFullYear(),
- start.getMonth(),
- ++last
- );
-
- if (next > end) {
- throw new Error(
- 'sanity fails next is greater then end'
- );
- }
-
- if (!Calc.isSameDate(next, end)) {
- list.push(next);
- continue;
- }
-
- break;
- }
-
- if (includeTime) {
- list.unshift(start);
- list.push(end);
- } else {
- list.unshift(this.createDay(start));
- list.push(this.createDay(end));
- }
-
- return list;
- },
-
- /**
- * Checks if date is in the past
- *
- * @param {Date} date to check.
- * @return {Boolean} true when date is in the past.
- */
- isPast: function(date) {
- return (date.valueOf() < Calc.today.valueOf());
- },
-
- /**
- * Checks if date is in the future
- *
- * @param {Date} date to check.
- * @return {Boolean} true when date is in the future.
- */
- isFuture: function(date) {
- return !Calc.isPast(date);
- },
-
- /**
- * Based on the input date
- * will return one of the following states
- *
- * past, present, future
- *
- * @param {Date} day for compare.
- * @param {Date} month comparison month.
- * @return {String} state.
- */
- relativeState: function(day, month) {
- var states;
- //var today = Calc.today;
-
- // 1. the date is today (real time)
- if (Calc.isToday(day)) {
- return Calc.PRESENT;
- }
-
- // 2. the date is in the past (real time)
- if (Calc.isPast(day)) {
- states = Calc.PAST;
- // 3. the date is in the future (real time)
- } else {
- states = Calc.FUTURE;
- }
-
- // 4. the date is not in the current month (relative time)
- if (day.getMonth() !== month.getMonth()) {
- states += ' ' + Calc.OTHER_MONTH;
- }
-
- return states;
- }
-
- };
-
- /* expose calc */
- DatePicker.Calc = Calc;
-
- /**
- * Initialize a date picker widget.
- *
- * @param {HTMLELement} element target of widget creation.
- */
- function DatePicker(element) {
- this.element = element;
- // default time is set so next/previous work
- // but we do not render the initial display here.
- this._position = new Date();
-
- // register events
- element.addEventListener('click', this);
-
- //XXX: When the document is localized again
- // we must also re-render the month because
- // the week days may have changed?
- // This will only happen when we change timezones
- // unless we add this information to the locales.
- }
-
- DatePicker.prototype = {
-
- /**
- * Internal value not exposed so we can fire events
- * when the getter/setter's are used.
- *
- * @type Date
- */
- _value: null,
-
- SELECTED: 'selected',
-
- /**
- * Gets current value
- *
- * @return {Null|Date} date or null.
- */
- get value() {
- return this._value;
- },
-
- /**
- * Sets the current value of the date picker.
- * When value differs from the currently set the
- * `onvaluechange` event will be fired with the new/old value.
- */
- set value(value) {
- var old = this._value;
- if (old !== value) {
- this._value = value;
- this._clearSelectedDay(value);
- this.onvaluechange(value, old);
- }
- },
-
- /**
- * Clears the currently selected date of its 'selected' class.
- * @private
- */
- _clearSelectedDay: function(value) {
- var target = this.element.querySelector('.' + SELECTED);
- if (target) {
- target.classList.remove(SELECTED);
- }
- },
-
- handleEvent: function(e) {
- switch (e.type) {
- case 'click':
- var target = e.target;
- //XXX: if the html of the date elements changes
- // this may also need to be altered as it
- // assumes that there is no nesting of elements.
- if (target.dataset.date) {
- var date = Calc.dateFromId(target.dataset.date);
- // order here is important as setting value will
- // clear all the past selected dates...
- this.value = date;
- this._position = date;
- // must come after setting selected date
- target.classList.add(SELECTED);
- }
- break;
- }
- },
-
- /**
- * Getter is used for date normalization.
- */
- get year() {
- return this._position.getFullYear();
- },
-
- /**
- * Getter is used for date normalization.
- */
- get month() {
- return this._position.getMonth();
- },
-
- get date() {
- return this._position.getDate();
- },
-
- /**
- * Find the number of days in the given month/year.
- * Month is zero based like the JS date constructor.
- *
- * @param {Numeric} year year value.
- * @param {Numeric} month month value.
- * @return {Numeric} number of days in month.
- */
- _daysInMonth: function(year, month) {
- var end = new Date(year, month + 1);
- end.setMilliseconds(-1);
- return end.getDate();
- },
-
- /**
- * Build the container for a day element.
- * Each element has classes added to it based
- * on what date it is created for.
- *
- * _today_ is based on today's actual date.
- * Each date element also contains a data-date attribute
- * with its current date as a string represented in
- * the following format: "yyyy-mm-dd".
- *
- * Possible classes:
- * - past
- * - present (today)
- * - future
- * - other-month (day of another month but falls within same week)
- *
- * @param {Date} date date desired.
- * @return {HTMLElement} dom element for day.
- */
- _renderDay: function(date) {
- var dayContainer = document.createElement('li');
- var dayEl = document.createElement('span');
-
- dayContainer.className = Calc.relativeState(
- date,
- this._position
- );
-
- dayEl.dataset.date = Calc.getDayId(date);
- dayEl.textContent = date.getDate();
-
- dayContainer.appendChild(dayEl);
-
- return dayContainer;
- },
-
- /**
- * Renders a set of dates and returns an ol element
- * containing each date.
- *
- * @private
- * @param {Array[Date]} dates array of dates.
- * @return {HTMLELement} container for week.
- */
- _renderWeek: function(dates) {
- var container = document.createElement('ol');
- var i = 0;
- var len = dates.length;
-
- for (; i < len; i++) {
- container.appendChild(
- this._renderDay(dates[i])
- );
- }
-
- return container;
- },
-
- /**
- * Finds all dates in a given month by week.
- * Includes leading and trailing days that occur
- * outside the given year/month combination.
- *
- * @private
- * @param {Numeric} year target year.
- * @param {Numeric} month target month.
- * @return {Array[Date]} array of dates.
- */
- _getMonthDays: function(year, month) {
- var date = new Date(year, month);
- var dateEnd = new Date(year, month + 1);
- dateEnd.setMilliseconds(-1);
-
- var start = Calc.getWeekStartDate(date);
- var end = Calc.getWeekEndDate(dateEnd);
- return Calc.daysBetween(start, end);
- },
-
- /**
- * Returns a section element with all
- * the days of the given month/year pair.
- *
- * Each month has a class for the number of weeks
- * it contains.
- *
- * Possible values:
- * - weeks-4
- * - weeks-5
- * - weeks-6
- *
- * @private
- */
- _renderMonth: function(year, month) {
- var container = document.createElement('section');
- var days = this._getMonthDays(year, month);
- var daysInWeek = Calc.daysInWeek();
- var weeks = days.length / daysInWeek;
- var i = 0;
-
- container.classList.add('weeks-' + weeks);
-
- for (; i < weeks; i++) {
- container.appendChild(this._renderWeek(
- days.splice(0, daysInWeek)
- ));
- }
-
- return container;
- },
-
- /**
- * Moves calendar one month into the future.
- */
- next: function() {
- this.display(this.year, this.month + 1, this.date);
- },
-
- /**
- * Moves calendar one month into the past.
- */
- previous: function() {
- this.display(this.year, this.month - 1, this.date);
- },
-
- /**
- * Primary method to display given month.
- * Will remove the current display and replace
- * it with the given month.
- *
- * @param {Numeric} year year to display.
- * @param {Numeric} month month to display.
- * @param {Numeric} date date to display.
- */
- display: function(year, month, date) {
-
- // reset the date to the last date if overflow
- var lastDate = new Date(year, month + 1, 0).getDate();
- if (lastDate < date)
- date = lastDate;
-
- // Should come before render month
- this._position = new Date(year, month, date);
-
- var element = this._renderMonth(year, month);
-
- if (this.monthDisplay) {
- this.monthDisplay.parentNode.removeChild(
- this.monthDisplay
- );
- }
-
- this.monthDisplay = element;
- this.element.appendChild(this.monthDisplay);
-
- this.onmonthchange(this._position);
-
- // Set the date as selected if presented
- this._clearSelectedDay();
- if (date) {
- var dayId = Calc.getDayId(this._position);
- this.value = this._position;
- var selector = '[data-date="' + dayId + '"]';
- var dateElement = document.querySelector(selector);
- dateElement.classList.add(SELECTED);
- }
- },
-
- /**
- * Called when the month is changed.
- */
- onmonthchange: function(month, year) {},
-
- /**
- * Called when the selected day changes.
- */
- onvaluechange: function(date) {}
- };
-
- return DatePicker;
-}());