123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638 |
- /*!
- * # Fomantic-UI - Calendar
- * http://github.com/fomantic/Fomantic-UI/
- *
- *
- * Released under the MIT license
- * http://opensource.org/licenses/MIT
- *
- */
- ;(function ($, window, document, undefined) {
- 'use strict';
- $.isFunction = $.isFunction || function(obj) {
- return typeof obj === "function" && typeof obj.nodeType !== "number";
- };
- window = (typeof window != 'undefined' && window.Math == Math)
- ? window
- : (typeof self != 'undefined' && self.Math == Math)
- ? self
- : Function('return this')()
- ;
- $.fn.calendar = function(parameters) {
- var
- $allModules = $(this),
- moduleSelector = $allModules.selector || '',
- time = new Date().getTime(),
- performance = [],
- query = arguments[0],
- methodInvoked = (typeof query == 'string'),
- queryArguments = [].slice.call(arguments, 1),
- returnedValue,
- timeGapTable = {
- '5': {'row': 4, 'column': 3 },
- '10': {'row': 3, 'column': 2 },
- '15': {'row': 2, 'column': 2 },
- '20': {'row': 3, 'column': 1 },
- '30': {'row': 2, 'column': 1 }
- }
- ;
- $allModules
- .each(function () {
- var
- settings = ( $.isPlainObject(parameters) )
- ? $.extend(true, {}, $.fn.calendar.settings, parameters)
- : $.extend({}, $.fn.calendar.settings),
- className = settings.className,
- namespace = settings.namespace,
- selector = settings.selector,
- formatter = settings.formatter,
- parser = settings.parser,
- metadata = settings.metadata,
- timeGap = timeGapTable[settings.minTimeGap],
- error = settings.error,
- eventNamespace = '.' + namespace,
- moduleNamespace = 'module-' + namespace,
- $module = $(this),
- $input = $module.find(selector.input),
- $container = $module.find(selector.popup),
- $activator = $module.find(selector.activator),
- element = this,
- instance = $module.data(moduleNamespace),
- isTouch,
- isTouchDown = false,
- focusDateUsedForRange = false,
- module
- ;
- module = {
- initialize: function () {
- module.debug('Initializing calendar for', element, $module);
- isTouch = module.get.isTouch();
- module.setup.config();
- module.setup.popup();
- module.setup.inline();
- module.setup.input();
- module.setup.date();
- module.create.calendar();
- module.bind.events();
- module.instantiate();
- },
- instantiate: function () {
- module.verbose('Storing instance of calendar');
- instance = module;
- $module.data(moduleNamespace, instance);
- },
- destroy: function () {
- module.verbose('Destroying previous calendar for', element);
- $module.removeData(moduleNamespace);
- module.unbind.events();
- },
- setup: {
- config: function () {
- if (module.get.minDate() !== null) {
- module.set.minDate($module.data(metadata.minDate));
- }
- if (module.get.maxDate() !== null) {
- module.set.maxDate($module.data(metadata.maxDate));
- }
- module.setting('type', module.get.type());
- },
- popup: function () {
- if (settings.inline) {
- return;
- }
- if (!$activator.length) {
- $activator = $module.children().first();
- if (!$activator.length) {
- return;
- }
- }
- if ($.fn.popup === undefined) {
- module.error(error.popup);
- return;
- }
- if (!$container.length) {
- //prepend the popup element to the activator's parent so that it has less chance of messing with
- //the styling (eg input action button needs to be the last child to have correct border radius)
- var $activatorParent = $activator.parent(),
- domPositionFunction = $activatorParent.closest(selector.append).length !== 0 ? 'appendTo' : 'prependTo';
- $container = $('<div/>').addClass(className.popup)[domPositionFunction]($activatorParent);
- }
- $container.addClass(className.calendar);
- var onVisible = settings.onVisible;
- var onHidden = settings.onHidden;
- if (!$input.length) {
- //no input, $container has to handle focus/blur
- $container.attr('tabindex', '0');
- onVisible = function () {
- module.focus();
- return settings.onVisible.apply($container, arguments);
- };
- onHidden = function () {
- module.blur();
- return settings.onHidden.apply($container, arguments);
- };
- }
- var onShow = function () {
- //reset the focus date onShow
- module.set.focusDate(module.get.date());
- module.set.mode(settings.startMode);
- return settings.onShow.apply($container, arguments);
- };
- var on = settings.on || ($input.length ? 'focus' : 'click');
- var options = $.extend({}, settings.popupOptions, {
- popup: $container,
- on: on,
- hoverable: on === 'hover',
- onShow: onShow,
- onVisible: onVisible,
- onHide: settings.onHide,
- onHidden: onHidden
- });
- module.popup(options);
- },
- inline: function () {
- if ($activator.length && !settings.inline) {
- return;
- }
- $container = $('<div/>').addClass(className.calendar).appendTo($module);
- if (!$input.length) {
- $container.attr('tabindex', '0');
- }
- },
- input: function () {
- if (settings.touchReadonly && $input.length && isTouch) {
- $input.prop('readonly', true);
- }
- },
- date: function () {
- var date;
- if (settings.initialDate) {
- date = parser.date(settings.initialDate, settings);
- } else if ($module.data(metadata.date) !== undefined) {
- date = parser.date($module.data(metadata.date), settings);
- } else if ($input.length) {
- date = parser.date($input.val(), settings);
- }
- module.set.date(date, settings.formatInput, false);
- }
- },
- create: {
- calendar: function () {
- var i, r, c, p, row, cell, pageGrid;
- var mode = module.get.mode();
- var today = new Date();
- var date = module.get.date();
- var focusDate = module.get.focusDate();
- var display = focusDate || date || settings.initialDate || today;
- display = module.helper.dateInRange(display);
- if (!focusDate) {
- focusDate = display;
- module.set.focusDate(focusDate, false, false);
- }
- var isYear = mode === 'year';
- var isMonth = mode === 'month';
- var isDay = mode === 'day';
- var isHour = mode === 'hour';
- var isMinute = mode === 'minute';
- var isTimeOnly = settings.type === 'time';
- var multiMonth = Math.max(settings.multiMonth, 1);
- var monthOffset = !isDay ? 0 : module.get.monthOffset();
- var minute = display.getMinutes();
- var hour = display.getHours();
- var day = display.getDate();
- var startMonth = display.getMonth() + monthOffset;
- var year = display.getFullYear();
- var columns = isDay ? settings.showWeekNumbers ? 8 : 7 : isHour ? 4 : timeGap['column'];
- var rows = isDay || isHour ? 6 : timeGap['row'];
- var pages = isDay ? multiMonth : 1;
- var container = $container;
- var tooltipPosition = container.hasClass("left") ? "right center" : "left center";
- container.empty();
- if (pages > 1) {
- pageGrid = $('<div/>').addClass(className.grid).appendTo(container);
- }
- for (p = 0; p < pages; p++) {
- if (pages > 1) {
- var pageColumn = $('<div/>').addClass(className.column).appendTo(pageGrid);
- container = pageColumn;
- }
- var month = startMonth + p;
- var firstMonthDayColumn = (new Date(year, month, 1).getDay() - settings.firstDayOfWeek % 7 + 7) % 7;
- if (!settings.constantHeight && isDay) {
- var requiredCells = new Date(year, month + 1, 0).getDate() + firstMonthDayColumn;
- rows = Math.ceil(requiredCells / 7);
- }
- var yearChange = isYear ? 10 : isMonth ? 1 : 0;
- var monthChange = isDay ? 1 : 0;
- var dayChange = isHour || isMinute ? 1 : 0;
- var prevNextDay = isHour || isMinute ? day : 1;
- var prevDate = new Date(year - yearChange, month - monthChange, prevNextDay - dayChange, hour);
- var nextDate = new Date(year + yearChange, month + monthChange, prevNextDay + dayChange, hour);
- var prevLast = isYear ? new Date(Math.ceil(year / 10) * 10 - 9, 0, 0) :
- isMonth ? new Date(year, 0, 0) : isDay ? new Date(year, month, 0) : new Date(year, month, day, -1);
- var nextFirst = isYear ? new Date(Math.ceil(year / 10) * 10 + 1, 0, 1) :
- isMonth ? new Date(year + 1, 0, 1) : isDay ? new Date(year, month + 1, 1) : new Date(year, month, day + 1);
- var tempMode = mode;
- if (isDay && settings.showWeekNumbers){
- tempMode += ' andweek';
- }
- var table = $('<table/>').addClass(className.table).addClass(tempMode).appendTo(container);
- var textColumns = columns;
- //no header for time-only mode
- if (!isTimeOnly) {
- var thead = $('<thead/>').appendTo(table);
- row = $('<tr/>').appendTo(thead);
- cell = $('<th/>').attr('colspan', '' + columns).appendTo(row);
- var headerDate = isYear || isMonth ? new Date(year, 0, 1) :
- isDay ? new Date(year, month, 1) : new Date(year, month, day, hour, minute);
- var headerText = $('<span/>').addClass(className.link).appendTo(cell);
- headerText.text(formatter.header(headerDate, mode, settings));
- var newMode = isMonth ? (settings.disableYear ? 'day' : 'year') :
- isDay ? (settings.disableMonth ? 'year' : 'month') : 'day';
- headerText.data(metadata.mode, newMode);
- if (p === 0) {
- var prev = $('<span/>').addClass(className.prev).appendTo(cell);
- prev.data(metadata.focusDate, prevDate);
- prev.toggleClass(className.disabledCell, !module.helper.isDateInRange(prevLast, mode));
- $('<i/>').addClass(className.prevIcon).appendTo(prev);
- }
- if (p === pages - 1) {
- var next = $('<span/>').addClass(className.next).appendTo(cell);
- next.data(metadata.focusDate, nextDate);
- next.toggleClass(className.disabledCell, !module.helper.isDateInRange(nextFirst, mode));
- $('<i/>').addClass(className.nextIcon).appendTo(next);
- }
- if (isDay) {
- row = $('<tr/>').appendTo(thead);
- if(settings.showWeekNumbers) {
- cell = $('<th/>').appendTo(row);
- cell.text(settings.text.weekNo);
- cell.addClass(className.weekCell);
- textColumns--;
- }
- for (i = 0; i < textColumns; i++) {
- cell = $('<th/>').appendTo(row);
- cell.text(formatter.dayColumnHeader((i + settings.firstDayOfWeek) % 7, settings));
- }
- }
- }
- var tbody = $('<tbody/>').appendTo(table);
- i = isYear ? Math.ceil(year / 10) * 10 - 9 : isDay ? 1 - firstMonthDayColumn : 0;
- for (r = 0; r < rows; r++) {
- row = $('<tr/>').appendTo(tbody);
- if(isDay && settings.showWeekNumbers){
- cell = $('<th/>').appendTo(row);
- cell.text(module.get.weekOfYear(year,month,i+1-settings.firstDayOfWeek));
- cell.addClass(className.weekCell);
- }
- for (c = 0; c < textColumns; c++, i++) {
- var cellDate = isYear ? new Date(i, month, 1, hour, minute) :
- isMonth ? new Date(year, i, 1, hour, minute) : isDay ? new Date(year, month, i, hour, minute) :
- isHour ? new Date(year, month, day, i) : new Date(year, month, day, hour, i * settings.minTimeGap);
- var cellText = isYear ? i :
- isMonth ? settings.text.monthsShort[i] : isDay ? cellDate.getDate() :
- formatter.time(cellDate, settings, true);
- cell = $('<td/>').addClass(className.cell).appendTo(row);
- cell.text(cellText);
- cell.data(metadata.date, cellDate);
- var adjacent = isDay && cellDate.getMonth() !== ((month + 12) % 12);
- var disabled = (!settings.selectAdjacentDays && adjacent) || !module.helper.isDateInRange(cellDate, mode) || settings.isDisabled(cellDate, mode) || module.helper.isDisabled(cellDate, mode) || !module.helper.isEnabled(cellDate, mode);
- if (disabled) {
- var disabledDate = module.helper.findDayAsObject(cellDate, mode, settings.disabledDates);
- if (disabledDate !== null && disabledDate[metadata.message]) {
- cell.attr("data-tooltip", disabledDate[metadata.message]);
- cell.attr("data-position", tooltipPosition);
- }
- } else {
- var eventDate = module.helper.findDayAsObject(cellDate, mode, settings.eventDates);
- if (eventDate !== null) {
- cell.addClass(eventDate[metadata.class] || settings.eventClass);
- if (eventDate[metadata.message]) {
- cell.attr("data-tooltip", eventDate[metadata.message]);
- cell.attr("data-position", tooltipPosition);
- }
- }
- }
- var active = module.helper.dateEqual(cellDate, date, mode);
- var isToday = module.helper.dateEqual(cellDate, today, mode);
- cell.toggleClass(className.adjacentCell, adjacent);
- cell.toggleClass(className.disabledCell, disabled);
- cell.toggleClass(className.activeCell, active && !adjacent);
- if (!isHour && !isMinute) {
- cell.toggleClass(className.todayCell, !adjacent && isToday);
- }
- // Allow for external modifications of each cell
- var cellOptions = {
- mode: mode,
- adjacent: adjacent,
- disabled: disabled,
- active: active,
- today: isToday
- };
- formatter.cell(cell, cellDate, cellOptions);
- if (module.helper.dateEqual(cellDate, focusDate, mode)) {
- //ensure that the focus date is exactly equal to the cell date
- //so that, if selected, the correct value is set
- module.set.focusDate(cellDate, false, false);
- }
- }
- }
- if (settings.today) {
- var todayRow = $('<tr/>').appendTo(tbody);
- var todayButton = $('<td/>').attr('colspan', '' + columns).addClass(className.today).appendTo(todayRow);
- todayButton.text(formatter.today(settings));
- todayButton.data(metadata.date, today);
- }
- module.update.focus(false, table);
- }
- }
- },
- update: {
- focus: function (updateRange, container) {
- container = container || $container;
- var mode = module.get.mode();
- var date = module.get.date();
- var focusDate = module.get.focusDate();
- var startDate = module.get.startDate();
- var endDate = module.get.endDate();
- var rangeDate = (updateRange ? focusDate : null) || date || (!isTouch ? focusDate : null);
- container.find('td').each(function () {
- var cell = $(this);
- var cellDate = cell.data(metadata.date);
- if (!cellDate) {
- return;
- }
- var disabled = cell.hasClass(className.disabledCell);
- var active = cell.hasClass(className.activeCell);
- var adjacent = cell.hasClass(className.adjacentCell);
- var focused = module.helper.dateEqual(cellDate, focusDate, mode);
- var inRange = !rangeDate ? false :
- ((!!startDate && module.helper.isDateInRange(cellDate, mode, startDate, rangeDate)) ||
- (!!endDate && module.helper.isDateInRange(cellDate, mode, rangeDate, endDate)));
- cell.toggleClass(className.focusCell, focused && (!isTouch || isTouchDown) && (!adjacent || (settings.selectAdjacentDays && adjacent)) && !disabled);
- if (module.helper.isTodayButton(cell)) {
- return;
- }
- cell.toggleClass(className.rangeCell, inRange && !active && !disabled);
- });
- }
- },
- refresh: function () {
- module.create.calendar();
- },
- bind: {
- events: function () {
- module.debug('Binding events');
- $container.on('mousedown' + eventNamespace, module.event.mousedown);
- $container.on('touchstart' + eventNamespace, module.event.mousedown);
- $container.on('mouseup' + eventNamespace, module.event.mouseup);
- $container.on('touchend' + eventNamespace, module.event.mouseup);
- $container.on('mouseover' + eventNamespace, module.event.mouseover);
- if ($input.length) {
- $input.on('input' + eventNamespace, module.event.inputChange);
- $input.on('focus' + eventNamespace, module.event.inputFocus);
- $input.on('blur' + eventNamespace, module.event.inputBlur);
- $input.on('click' + eventNamespace, module.event.inputClick);
- $input.on('keydown' + eventNamespace, module.event.keydown);
- } else {
- $container.on('keydown' + eventNamespace, module.event.keydown);
- }
- }
- },
- unbind: {
- events: function () {
- module.debug('Unbinding events');
- $container.off(eventNamespace);
- if ($input.length) {
- $input.off(eventNamespace);
- }
- }
- },
- event: {
- mouseover: function (event) {
- var target = $(event.target);
- var date = target.data(metadata.date);
- var mousedown = event.buttons === 1;
- if (date) {
- module.set.focusDate(date, false, true, mousedown);
- }
- },
- mousedown: function (event) {
- if ($input.length) {
- //prevent the mousedown on the calendar causing the input to lose focus
- event.preventDefault();
- }
- isTouchDown = event.type.indexOf('touch') >= 0;
- var target = $(event.target);
- var date = target.data(metadata.date);
- if (date) {
- module.set.focusDate(date, false, true, true);
- }
- },
- mouseup: function (event) {
- //ensure input has focus so that it receives keydown events for calendar navigation
- module.focus();
- event.preventDefault();
- event.stopPropagation();
- isTouchDown = false;
- var target = $(event.target);
- if (target.hasClass("disabled")) {
- return;
- }
- var parent = target.parent();
- if (parent.data(metadata.date) || parent.data(metadata.focusDate) || parent.data(metadata.mode)) {
- //clicked on a child element, switch to parent (used when clicking directly on prev/next <i> icon element)
- target = parent;
- }
- var date = target.data(metadata.date);
- var focusDate = target.data(metadata.focusDate);
- var mode = target.data(metadata.mode);
- if (date && settings.onSelect.call(element, date, module.get.mode()) !== false) {
- var forceSet = target.hasClass(className.today);
- module.selectDate(date, forceSet);
- }
- else if (focusDate) {
- module.set.focusDate(focusDate);
- }
- else if (mode) {
- module.set.mode(mode);
- }
- },
- keydown: function (event) {
- var keyCode = event.which;
- if (keyCode === 27 || keyCode === 9) {
- //esc || tab
- module.popup('hide');
- }
- if (module.popup('is visible')) {
- if (keyCode === 37 || keyCode === 38 || keyCode === 39 || keyCode === 40) {
- //arrow keys
- var mode = module.get.mode();
- var bigIncrement = mode === 'day' ? 7 : mode === 'hour' ? 4 : mode === 'minute' ? timeGap['column'] : 3;
- var increment = keyCode === 37 ? -1 : keyCode === 38 ? -bigIncrement : keyCode == 39 ? 1 : bigIncrement;
- increment *= mode === 'minute' ? settings.minTimeGap : 1;
- var focusDate = module.get.focusDate() || module.get.date() || new Date();
- var year = focusDate.getFullYear() + (mode === 'year' ? increment : 0);
- var month = focusDate.getMonth() + (mode === 'month' ? increment : 0);
- var day = focusDate.getDate() + (mode === 'day' ? increment : 0);
- var hour = focusDate.getHours() + (mode === 'hour' ? increment : 0);
- var minute = focusDate.getMinutes() + (mode === 'minute' ? increment : 0);
- var newFocusDate = new Date(year, month, day, hour, minute);
- if (settings.type === 'time') {
- newFocusDate = module.helper.mergeDateTime(focusDate, newFocusDate);
- }
- if (module.helper.isDateInRange(newFocusDate, mode)) {
- module.set.focusDate(newFocusDate);
- }
- } else if (keyCode === 13) {
- //enter
- var mode = module.get.mode();
- var date = module.get.focusDate();
- if (date && !settings.isDisabled(date, mode) && !module.helper.isDisabled(date, mode) && module.helper.isEnabled(date, mode)) {
- module.selectDate(date);
- }
- //disable form submission:
- event.preventDefault();
- event.stopPropagation();
- }
- }
- if (keyCode === 38 || keyCode === 40) {
- //arrow-up || arrow-down
- event.preventDefault(); //don't scroll
- module.popup('show');
- }
- },
- inputChange: function () {
- var val = $input.val();
- var date = parser.date(val, settings);
- module.set.date(date, false);
- },
- inputFocus: function () {
- $container.addClass(className.active);
- },
- inputBlur: function () {
- $container.removeClass(className.active);
- if (settings.formatInput) {
- var date = module.get.date();
- var text = formatter.datetime(date, settings);
- $input.val(text);
- }
- },
- inputClick: function () {
- module.popup('show');
- }
- },
- get: {
- weekOfYear: function(weekYear,weekMonth,weekDay) {
- // adapted from http://www.merlyn.demon.co.uk/weekcalc.htm
- var ms1d = 864e5, // milliseconds in a day
- ms7d = 7 * ms1d; // milliseconds in a week
- return function() { // return a closure so constants get calculated only once
- var DC3 = Date.UTC(weekYear, weekMonth, weekDay + 3) / ms1d, // an Absolute Day Number
- AWN = Math.floor(DC3 / 7), // an Absolute Week Number
- Wyr = new Date(AWN * ms7d).getUTCFullYear();
- return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;
- }();
- },
- date: function () {
- return module.helper.sanitiseDate($module.data(metadata.date)) || null;
- },
- inputDate: function() {
- return $input.val();
- },
- focusDate: function () {
- return $module.data(metadata.focusDate) || null;
- },
- startDate: function () {
- var startModule = module.get.calendarModule(settings.startCalendar);
- return (startModule ? startModule.get.date() : $module.data(metadata.startDate)) || null;
- },
- endDate: function () {
- var endModule = module.get.calendarModule(settings.endCalendar);
- return (endModule ? endModule.get.date() : $module.data(metadata.endDate)) || null;
- },
- minDate: function() {
- return $module.data(metadata.minDate) || null;
- },
- maxDate: function() {
- return $module.data(metadata.maxDate) || null;
- },
- monthOffset: function () {
- return $module.data(metadata.monthOffset) || 0;
- },
- mode: function () {
- //only returns valid modes for the current settings
- var mode = $module.data(metadata.mode) || settings.startMode;
- var validModes = module.get.validModes();
- if ($.inArray(mode, validModes) >= 0) {
- return mode;
- }
- return settings.type === 'time' ? 'hour' :
- settings.type === 'month' ? 'month' :
- settings.type === 'year' ? 'year' : 'day';
- },
- type: function() {
- return $module.data(metadata.type) || settings.type;
- },
- validModes: function () {
- var validModes = [];
- if (settings.type !== 'time') {
- if (!settings.disableYear || settings.type === 'year') {
- validModes.push('year');
- }
- if (!(settings.disableMonth || settings.type === 'year') || settings.type === 'month') {
- validModes.push('month');
- }
- if (settings.type.indexOf('date') >= 0) {
- validModes.push('day');
- }
- }
- if (settings.type.indexOf('time') >= 0) {
- validModes.push('hour');
- if (!settings.disableMinute) {
- validModes.push('minute');
- }
- }
- return validModes;
- },
- isTouch: function () {
- try {
- document.createEvent('TouchEvent');
- return true;
- }
- catch (e) {
- return false;
- }
- },
- calendarModule: function (selector) {
- if (!selector) {
- return null;
- }
- if (!(selector instanceof $)) {
- selector = $(selector).first();
- }
- //assume range related calendars are using the same namespace
- return selector.data(moduleNamespace);
- }
- },
- set: {
- date: function (date, updateInput, fireChange) {
- updateInput = updateInput !== false;
- fireChange = fireChange !== false;
- date = module.helper.sanitiseDate(date);
- date = module.helper.dateInRange(date);
- var mode = module.get.mode();
- var text = formatter.datetime(date, settings);
- if (fireChange && settings.onBeforeChange.call(element, date, text, mode) === false) {
- return false;
- }
- module.set.focusDate(date);
- if (settings.isDisabled(date, mode)) {
- return false;
- }
- var endDate = module.get.endDate();
- if (!!endDate && !!date && date > endDate) {
- //selected date is greater than end date in range, so clear end date
- module.set.endDate(undefined);
- }
- module.set.dataKeyValue(metadata.date, date);
- if (updateInput && $input.length) {
- $input.val(text);
- }
- if (fireChange) {
- settings.onChange.call(element, date, text, mode);
- }
- },
- startDate: function (date, refreshCalendar) {
- date = module.helper.sanitiseDate(date);
- var startModule = module.get.calendarModule(settings.startCalendar);
- if (startModule) {
- startModule.set.date(date);
- }
- module.set.dataKeyValue(metadata.startDate, date, refreshCalendar);
- },
- endDate: function (date, refreshCalendar) {
- date = module.helper.sanitiseDate(date);
- var endModule = module.get.calendarModule(settings.endCalendar);
- if (endModule) {
- endModule.set.date(date);
- }
- module.set.dataKeyValue(metadata.endDate, date, refreshCalendar);
- },
- focusDate: function (date, refreshCalendar, updateFocus, updateRange) {
- date = module.helper.sanitiseDate(date);
- date = module.helper.dateInRange(date);
- var isDay = module.get.mode() === 'day';
- var oldFocusDate = module.get.focusDate();
- if (isDay && date && oldFocusDate) {
- var yearDelta = date.getFullYear() - oldFocusDate.getFullYear();
- var monthDelta = yearDelta * 12 + date.getMonth() - oldFocusDate.getMonth();
- if (monthDelta) {
- var monthOffset = module.get.monthOffset() - monthDelta;
- module.set.monthOffset(monthOffset, false);
- }
- }
- var changed = module.set.dataKeyValue(metadata.focusDate, date, refreshCalendar);
- updateFocus = (updateFocus !== false && changed && refreshCalendar === false) || focusDateUsedForRange != updateRange;
- focusDateUsedForRange = updateRange;
- if (updateFocus) {
- module.update.focus(updateRange);
- }
- },
- minDate: function (date) {
- date = module.helper.sanitiseDate(date);
- if (settings.maxDate !== null && settings.maxDate <= date) {
- module.verbose('Unable to set minDate variable bigger that maxDate variable', date, settings.maxDate);
- } else {
- module.setting('minDate', date);
- module.set.dataKeyValue(metadata.minDate, date);
- }
- },
- maxDate: function (date) {
- date = module.helper.sanitiseDate(date);
- if (settings.minDate !== null && settings.minDate >= date) {
- module.verbose('Unable to set maxDate variable lower that minDate variable', date, settings.minDate);
- } else {
- module.setting('maxDate', date);
- module.set.dataKeyValue(metadata.maxDate, date);
- }
- },
- monthOffset: function (monthOffset, refreshCalendar) {
- var multiMonth = Math.max(settings.multiMonth, 1);
- monthOffset = Math.max(1 - multiMonth, Math.min(0, monthOffset));
- module.set.dataKeyValue(metadata.monthOffset, monthOffset, refreshCalendar);
- },
- mode: function (mode, refreshCalendar) {
- module.set.dataKeyValue(metadata.mode, mode, refreshCalendar);
- },
- dataKeyValue: function (key, value, refreshCalendar) {
- var oldValue = $module.data(key);
- var equal = oldValue === value || (oldValue <= value && oldValue >= value); //equality test for dates and string objects
- if (value) {
- $module.data(key, value);
- } else {
- $module.removeData(key);
- }
- refreshCalendar = refreshCalendar !== false && !equal;
- if (refreshCalendar) {
- module.refresh();
- }
- return !equal;
- }
- },
- selectDate: function (date, forceSet) {
- module.verbose('New date selection', date);
- var mode = module.get.mode();
- var complete = forceSet || mode === 'minute' ||
- (settings.disableMinute && mode === 'hour') ||
- (settings.type === 'date' && mode === 'day') ||
- (settings.type === 'month' && mode === 'month') ||
- (settings.type === 'year' && mode === 'year');
- if (complete) {
- var canceled = module.set.date(date) === false;
- if (!canceled && settings.closable) {
- module.popup('hide');
- //if this is a range calendar, show the end date calendar popup and focus the input
- var endModule = module.get.calendarModule(settings.endCalendar);
- if (endModule) {
- endModule.popup('show');
- endModule.focus();
- }
- }
- } else {
- var newMode = mode === 'year' ? (!settings.disableMonth ? 'month' : 'day') :
- mode === 'month' ? 'day' : mode === 'day' ? 'hour' : 'minute';
- module.set.mode(newMode);
- if (mode === 'hour' || (mode === 'day' && module.get.date())) {
- //the user has chosen enough to consider a valid date/time has been chosen
- module.set.date(date);
- } else {
- module.set.focusDate(date);
- }
- }
- },
- changeDate: function (date) {
- module.set.date(date);
- },
- clear: function () {
- module.set.date(undefined);
- },
- popup: function () {
- return $activator.popup.apply($activator, arguments);
- },
- focus: function () {
- if ($input.length) {
- $input.focus();
- } else {
- $container.focus();
- }
- },
- blur: function () {
- if ($input.length) {
- $input.blur();
- } else {
- $container.blur();
- }
- },
- helper: {
- isDisabled: function(date, mode) {
- return (mode === 'day' || mode === 'month' || mode === 'year') && ((settings.disabledDaysOfWeek.indexOf(date.getDay()) !== -1) || settings.disabledDates.some(function(d){
- if(typeof d === 'string') {
- d = module.helper.sanitiseDate(d);
- }
- if (d instanceof Date) {
- return module.helper.dateEqual(date, d, mode);
- }
- if (d !== null && typeof d === 'object') {
- if (d[metadata.year]) {
- if (typeof d[metadata.year] === 'number') {
- return date.getFullYear() == d[metadata.year];
- } else if (Array.isArray(d[metadata.year])) {
- return d[metadata.year].indexOf(date.getFullYear()) > -1;
- }
- } else if (d[metadata.month]) {
- if (typeof d[metadata.month] === 'number') {
- return date.getMonth() == d[metadata.month];
- } else if (Array.isArray(d[metadata.month])) {
- return d[metadata.month].indexOf(date.getMonth()) > -1;
- } else if (d[metadata.month] instanceof Date) {
- var sdate = module.helper.sanitiseDate(d[metadata.month]);
- return (date.getMonth() == sdate.getMonth()) && (date.getFullYear() == sdate.getFullYear())
- }
- } else if (d[metadata.date] && mode === 'day') {
- if (d[metadata.date] instanceof Date) {
- return module.helper.dateEqual(date, module.helper.sanitiseDate(d[metadata.date]), mode);
- } else if (Array.isArray(d[metadata.date])) {
- return d[metadata.date].some(function(idate) {
- return module.helper.dateEqual(date, idate, mode);
- });
- }
- }
- }
- }));
- },
- isEnabled: function(date, mode) {
- if (mode === 'day') {
- return settings.enabledDates.length === 0 || settings.enabledDates.some(function(d){
- if(typeof d === 'string') {
- d = module.helper.sanitiseDate(d);
- }
- if (d instanceof Date) {
- return module.helper.dateEqual(date, d, mode);
- }
- if (d !== null && typeof d === 'object' && d[metadata.date]) {
- return module.helper.dateEqual(date, module.helper.sanitiseDate(d[metadata.date]), mode);
- }
- });
- } else {
- return true;
- }
- },
- findDayAsObject: function(date, mode, dates) {
- if (mode === 'day' || mode === 'month' || mode === 'year') {
- var d;
- for (var i = 0; i < dates.length; i++) {
- d = dates[i];
- if(typeof d === 'string') {
- d = module.helper.sanitiseDate(d);
- }
- if (d instanceof Date && module.helper.dateEqual(date, d, mode)) {
- var dateObject = {};
- dateObject[metadata.date] = d;
- return dateObject;
- }
- else if (d !== null && typeof d === 'object') {
- if (d[metadata.year]) {
- if (typeof d[metadata.year] === 'number' && date.getFullYear() == d[metadata.year]) {
- return d;
- } else if (Array.isArray(d[metadata.year])) {
- if (d[metadata.year].indexOf(date.getFullYear()) > -1) {
- return d;
- }
- }
- } else if (d[metadata.month]) {
- if (typeof d[metadata.month] === 'number' && date.getMonth() == d[metadata.month]) {
- return d;
- } else if (Array.isArray(d[metadata.month])) {
- if (d[metadata.month].indexOf(date.getMonth()) > -1) {
- return d;
- }
- } else if (d[metadata.month] instanceof Date) {
- var sdate = module.helper.sanitiseDate(d[metadata.month]);
- if ((date.getMonth() == sdate.getMonth()) && (date.getFullYear() == sdate.getFullYear())) {
- return d;
- }
- }
- } else if (d[metadata.date] && mode === 'day') {
- if (d[metadata.date] instanceof Date && module.helper.dateEqual(date, module.helper.sanitiseDate(d[metadata.date]), mode)) {
- return d;
- } else if (Array.isArray(d[metadata.date])) {
- if(d[metadata.date].some(function(idate) { return module.helper.dateEqual(date, idate, mode); })) {
- return d;
- }
- }
- }
- }
- }
- }
- return null;
- },
- sanitiseDate: function (date) {
- if (!date) {
- return undefined;
- }
- if (!(date instanceof Date)) {
- date = parser.date('' + date, settings);
- }
- if (!date || date === null || isNaN(date.getTime())) {
- return undefined;
- }
- return date;
- },
- dateDiff: function (date1, date2, mode) {
- mode = mode || 'day';
- var isTimeOnly = settings.type === 'time';
- var isYear = mode === 'year';
- var isYearOrMonth = isYear || mode === 'month';
- var isMinute = mode === 'minute';
- var isHourOrMinute = isMinute || mode === 'hour';
- //only care about a minute accuracy of settings.minTimeGap
- date1 = new Date(
- isTimeOnly ? 2000 : date1.getFullYear(),
- isTimeOnly ? 0 : isYear ? 0 : date1.getMonth(),
- isTimeOnly ? 1 : isYearOrMonth ? 1 : date1.getDate(),
- !isHourOrMinute ? 0 : date1.getHours(),
- !isMinute ? 0 : settings.minTimeGap * Math.floor(date1.getMinutes() / settings.minTimeGap));
- date2 = new Date(
- isTimeOnly ? 2000 : date2.getFullYear(),
- isTimeOnly ? 0 : isYear ? 0 : date2.getMonth(),
- isTimeOnly ? 1 : isYearOrMonth ? 1 : date2.getDate(),
- !isHourOrMinute ? 0 : date2.getHours(),
- !isMinute ? 0 : settings.minTimeGap * Math.floor(date2.getMinutes() / settings.minTimeGap));
- return date2.getTime() - date1.getTime();
- },
- dateEqual: function (date1, date2, mode) {
- return !!date1 && !!date2 && module.helper.dateDiff(date1, date2, mode) === 0;
- },
- isDateInRange: function (date, mode, minDate, maxDate) {
- if (!minDate && !maxDate) {
- var startDate = module.get.startDate();
- minDate = startDate && settings.minDate ? new Date(Math.max(startDate, settings.minDate)) : startDate || settings.minDate;
- maxDate = settings.maxDate;
- }
- minDate = minDate && new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate(), minDate.getHours(), settings.minTimeGap * Math.ceil(minDate.getMinutes() / settings.minTimeGap));
- return !(!date ||
- (minDate && module.helper.dateDiff(date, minDate, mode) > 0) ||
- (maxDate && module.helper.dateDiff(maxDate, date, mode) > 0));
- },
- dateInRange: function (date, minDate, maxDate) {
- if (!minDate && !maxDate) {
- var startDate = module.get.startDate();
- minDate = startDate && settings.minDate ? new Date(Math.max(startDate, settings.minDate)) : startDate || settings.minDate;
- maxDate = settings.maxDate;
- }
- minDate = minDate && new Date(minDate.getFullYear(), minDate.getMonth(), minDate.getDate(), minDate.getHours(), settings.minTimeGap * Math.ceil(minDate.getMinutes() / settings.minTimeGap));
- var isTimeOnly = settings.type === 'time';
- return !date ? date :
- (minDate && module.helper.dateDiff(date, minDate, 'minute') > 0) ?
- (isTimeOnly ? module.helper.mergeDateTime(date, minDate) : minDate) :
- (maxDate && module.helper.dateDiff(maxDate, date, 'minute') > 0) ?
- (isTimeOnly ? module.helper.mergeDateTime(date, maxDate) : maxDate) :
- date;
- },
- mergeDateTime: function (date, time) {
- return (!date || !time) ? time :
- new Date(date.getFullYear(), date.getMonth(), date.getDate(), time.getHours(), time.getMinutes());
- },
- isTodayButton: function(element) {
- return element.text() === settings.text.today;
- }
- },
- setting: function (name, value) {
- module.debug('Changing setting', name, value);
- if ($.isPlainObject(name)) {
- $.extend(true, settings, name);
- }
- else if (value !== undefined) {
- if ($.isPlainObject(settings[name])) {
- $.extend(true, settings[name], value);
- }
- else {
- settings[name] = value;
- }
- }
- else {
- return settings[name];
- }
- },
- internal: function (name, value) {
- if( $.isPlainObject(name) ) {
- $.extend(true, module, name);
- }
- else if(value !== undefined) {
- module[name] = value;
- }
- else {
- return module[name];
- }
- },
- debug: function () {
- if (!settings.silent && settings.debug) {
- if (settings.performance) {
- module.performance.log(arguments);
- }
- else {
- module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
- module.debug.apply(console, arguments);
- }
- }
- },
- verbose: function () {
- if (!settings.silent && settings.verbose && settings.debug) {
- if (settings.performance) {
- module.performance.log(arguments);
- }
- else {
- module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
- module.verbose.apply(console, arguments);
- }
- }
- },
- error: function () {
- if (!settings.silent) {
- module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
- module.error.apply(console, arguments);
- }
- },
- performance: {
- log: function (message) {
- var
- currentTime,
- executionTime,
- previousTime
- ;
- if (settings.performance) {
- currentTime = new Date().getTime();
- previousTime = time || currentTime;
- executionTime = currentTime - previousTime;
- time = currentTime;
- performance.push({
- 'Name': message[0],
- 'Arguments': [].slice.call(message, 1) || '',
- 'Element': element,
- 'Execution Time': executionTime
- });
- }
- clearTimeout(module.performance.timer);
- module.performance.timer = setTimeout(module.performance.display, 500);
- },
- display: function () {
- var
- title = settings.name + ':',
- totalTime = 0
- ;
- time = false;
- clearTimeout(module.performance.timer);
- $.each(performance, function (index, data) {
- totalTime += data['Execution Time'];
- });
- title += ' ' + totalTime + 'ms';
- if (moduleSelector) {
- title += ' \'' + moduleSelector + '\'';
- }
- if ((console.group !== undefined || console.table !== undefined) && performance.length > 0) {
- console.groupCollapsed(title);
- if (console.table) {
- console.table(performance);
- }
- else {
- $.each(performance, function (index, data) {
- console.log(data['Name'] + ': ' + data['Execution Time'] + 'ms');
- });
- }
- console.groupEnd();
- }
- performance = [];
- }
- },
- invoke: function (query, passedArguments, context) {
- var
- object = instance,
- maxDepth,
- found,
- response
- ;
- passedArguments = passedArguments || queryArguments;
- context = element || context;
- if (typeof query == 'string' && object !== undefined) {
- query = query.split(/[\. ]/);
- maxDepth = query.length - 1;
- $.each(query, function (depth, value) {
- var camelCaseValue = (depth != maxDepth)
- ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
- : query
- ;
- if ($.isPlainObject(object[camelCaseValue]) && (depth != maxDepth)) {
- object = object[camelCaseValue];
- }
- else if (object[camelCaseValue] !== undefined) {
- found = object[camelCaseValue];
- return false;
- }
- else if ($.isPlainObject(object[value]) && (depth != maxDepth)) {
- object = object[value];
- }
- else if (object[value] !== undefined) {
- found = object[value];
- return false;
- }
- else {
- module.error(error.method, query);
- return false;
- }
- });
- }
- if ($.isFunction(found)) {
- response = found.apply(context, passedArguments);
- }
- else if (found !== undefined) {
- response = found;
- }
- if (Array.isArray(returnedValue)) {
- returnedValue.push(response);
- }
- else if (returnedValue !== undefined) {
- returnedValue = [returnedValue, response];
- }
- else if (response !== undefined) {
- returnedValue = response;
- }
- return found;
- }
- };
- if (methodInvoked) {
- if (instance === undefined) {
- module.initialize();
- }
- module.invoke(query);
- }
- else {
- if (instance !== undefined) {
- instance.invoke('destroy');
- }
- module.initialize();
- }
- })
- ;
- return (returnedValue !== undefined)
- ? returnedValue
- : this
- ;
- };
- $.fn.calendar.settings = {
- name : 'Calendar',
- namespace : 'calendar',
- silent: false,
- debug: false,
- verbose: false,
- performance: false,
- type : 'datetime', // picker type, can be 'datetime', 'date', 'time', 'month', or 'year'
- firstDayOfWeek : 0, // day for first day column (0 = Sunday)
- constantHeight : true, // add rows to shorter months to keep day calendar height consistent (6 rows)
- today : false, // show a 'today/now' button at the bottom of the calendar
- closable : true, // close the popup after selecting a date/time
- monthFirst : true, // month before day when parsing/converting date from/to text
- touchReadonly : true, // set input to readonly on touch devices
- inline : false, // create the calendar inline instead of inside a popup
- on : null, // when to show the popup (defaults to 'focus' for input, 'click' for others)
- initialDate : null, // date to display initially when no date is selected (null = now)
- startMode : false, // display mode to start in, can be 'year', 'month', 'day', 'hour', 'minute' (false = 'day')
- minDate : null, // minimum date/time that can be selected, dates/times before are disabled
- maxDate : null, // maximum date/time that can be selected, dates/times after are disabled
- ampm : true, // show am/pm in time mode
- disableYear : false, // disable year selection mode
- disableMonth : false, // disable month selection mode
- disableMinute : false, // disable minute selection mode
- formatInput : true, // format the input text upon input blur and module creation
- startCalendar : null, // jquery object or selector for another calendar that represents the start date of a date range
- endCalendar : null, // jquery object or selector for another calendar that represents the end date of a date range
- multiMonth : 1, // show multiple months when in 'day' mode
- minTimeGap : 5,
- showWeekNumbers : null, // show Number of Week at the very first column of a dayView
- disabledDates : [], // specific day(s) which won't be selectable and contain additional information.
- disabledDaysOfWeek : [], // day(s) which won't be selectable(s) (0 = Sunday)
- enabledDates : [], // specific day(s) which will be selectable, all other days will be disabled
- eventDates : [], // specific day(s) which will be shown in a different color and using tooltips
- centuryBreak : 60, // starting short year until 99 where it will be assumed to belong to the last century
- currentCentury : 2000, // century to be added to 2-digit years (00 to {centuryBreak}-1)
- selectAdjacentDays : false, // The calendar can show dates from adjacent month. These adjacent month dates can also be made selectable.
- // popup options ('popup', 'on', 'hoverable', and show/hide callbacks are overridden)
- popupOptions: {
- position: 'bottom left',
- lastResort: 'bottom left',
- prefer: 'opposite',
- hideOnScroll: false
- },
- text: {
- days: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
- months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
- monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
- today: 'Today',
- now: 'Now',
- am: 'AM',
- pm: 'PM',
- weekNo: 'Week'
- },
- formatter: {
- header: function (date, mode, settings) {
- return mode === 'year' ? settings.formatter.yearHeader(date, settings) :
- mode === 'month' ? settings.formatter.monthHeader(date, settings) :
- mode === 'day' ? settings.formatter.dayHeader(date, settings) :
- mode === 'hour' ? settings.formatter.hourHeader(date, settings) :
- settings.formatter.minuteHeader(date, settings);
- },
- yearHeader: function (date, settings) {
- var decadeYear = Math.ceil(date.getFullYear() / 10) * 10;
- return (decadeYear - 9) + ' - ' + (decadeYear + 2);
- },
- monthHeader: function (date, settings) {
- return date.getFullYear();
- },
- dayHeader: function (date, settings) {
- var month = settings.text.months[date.getMonth()];
- var year = date.getFullYear();
- return month + ' ' + year;
- },
- hourHeader: function (date, settings) {
- return settings.formatter.date(date, settings);
- },
- minuteHeader: function (date, settings) {
- return settings.formatter.date(date, settings);
- },
- dayColumnHeader: function (day, settings) {
- return settings.text.days[day];
- },
- datetime: function (date, settings) {
- if (!date) {
- return '';
- }
- var day = settings.type === 'time' ? '' : settings.formatter.date(date, settings);
- var time = settings.type.indexOf('time') < 0 ? '' : settings.formatter.time(date, settings, false);
- var separator = settings.type === 'datetime' ? ' ' : '';
- return day + separator + time;
- },
- date: function (date, settings) {
- if (!date) {
- return '';
- }
- var day = date.getDate();
- var month = settings.text.months[date.getMonth()];
- var year = date.getFullYear();
- return settings.type === 'year' ? year :
- settings.type === 'month' ? month + ' ' + year :
- (settings.monthFirst ? month + ' ' + day : day + ' ' + month) + ', ' + year;
- },
- time: function (date, settings, forCalendar) {
- if (!date) {
- return '';
- }
- var hour = date.getHours();
- var minute = date.getMinutes();
- var ampm = '';
- if (settings.ampm) {
- ampm = ' ' + (hour < 12 ? settings.text.am : settings.text.pm);
- hour = hour === 0 ? 12 : hour > 12 ? hour - 12 : hour;
- }
- return hour + ':' + (minute < 10 ? '0' : '') + minute + ampm;
- },
- today: function (settings) {
- return settings.type === 'date' ? settings.text.today : settings.text.now;
- },
- cell: function (cell, date, cellOptions) {
- }
- },
- parser: {
- date: function (text, settings) {
- if (text instanceof Date) {
- return text;
- }
- if (!text) {
- return null;
- }
- text = ('' + text).trim().toLowerCase();
- if (text.length === 0) {
- return null;
- }
- // Reverse date and month in some cases
- text = settings.monthFirst ? text : text.replace(/[\/\-\.]/g,'/').replace(/([0-9]+)\/([0-9]+)/,'$2/$1');
- var textDate = new Date(text);
- if(!isNaN(textDate.getDate())) {
- return textDate;
- }
- var i, j, k;
- var minute = -1, hour = -1, day = -1, month = -1, year = -1;
- var isAm = undefined;
- var isTimeOnly = settings.type === 'time';
- var isDateOnly = settings.type.indexOf('time') < 0;
- var words = text.split(settings.regExp.dateWords), word;
- var numbers = text.split(settings.regExp.dateNumbers), number;
- var parts;
- var monthString;
- if (!isDateOnly) {
- //am/pm
- isAm = $.inArray(settings.text.am.toLowerCase(), words) >= 0 ? true :
- $.inArray(settings.text.pm.toLowerCase(), words) >= 0 ? false : undefined;
- //time with ':'
- for (i = 0; i < numbers.length; i++) {
- number = numbers[i];
- if (number.indexOf(':') >= 0) {
- if (hour < 0 || minute < 0) {
- parts = number.split(':');
- for (k = 0; k < Math.min(2, parts.length); k++) {
- j = parseInt(parts[k]);
- if (isNaN(j)) {
- j = 0;
- }
- if (k === 0) {
- hour = j % 24;
- } else {
- minute = j % 60;
- }
- }
- }
- numbers.splice(i, 1);
- }
- }
- }
- if (!isTimeOnly) {
- //textual month
- for (i = 0; i < words.length; i++) {
- word = words[i];
- if (word.length <= 0) {
- continue;
- }
- for (j = 0; j < settings.text.months.length; j++) {
- monthString = settings.text.months[j];
- monthString = monthString.substring(0, word.length).toLowerCase();
- if (monthString === word) {
- month = j + 1;
- break;
- }
- }
- if (month >= 0) {
- break;
- }
- }
- //year > settings.centuryBreak
- for (i = 0; i < numbers.length; i++) {
- j = parseInt(numbers[i]);
- if (isNaN(j)) {
- continue;
- }
- if (j >= settings.centuryBreak && i === numbers.length-1) {
- if (j <= 99) {
- j += settings.currentCentury - 100;
- }
- year = j;
- numbers.splice(i, 1);
- break;
- }
- }
- //numeric month
- if (month < 0) {
- for (i = 0; i < numbers.length; i++) {
- k = i > 1 || settings.monthFirst ? i : i === 1 ? 0 : 1;
- j = parseInt(numbers[k]);
- if (isNaN(j)) {
- continue;
- }
- if (1 <= j && j <= 12) {
- month = j;
- numbers.splice(k, 1);
- break;
- }
- }
- }
- //day
- for (i = 0; i < numbers.length; i++) {
- j = parseInt(numbers[i]);
- if (isNaN(j)) {
- continue;
- }
- if (1 <= j && j <= 31) {
- day = j;
- numbers.splice(i, 1);
- break;
- }
- }
- //year <= settings.centuryBreak
- if (year < 0) {
- for (i = numbers.length - 1; i >= 0; i--) {
- j = parseInt(numbers[i]);
- if (isNaN(j)) {
- continue;
- }
- if (j <= 99) {
- j += settings.currentCentury;
- }
- year = j;
- numbers.splice(i, 1);
- break;
- }
- }
- }
- if (!isDateOnly) {
- //hour
- if (hour < 0) {
- for (i = 0; i < numbers.length; i++) {
- j = parseInt(numbers[i]);
- if (isNaN(j)) {
- continue;
- }
- if (0 <= j && j <= 23) {
- hour = j;
- numbers.splice(i, 1);
- break;
- }
- }
- }
- //minute
- if (minute < 0) {
- for (i = 0; i < numbers.length; i++) {
- j = parseInt(numbers[i]);
- if (isNaN(j)) {
- continue;
- }
- if (0 <= j && j <= 59) {
- minute = j;
- numbers.splice(i, 1);
- break;
- }
- }
- }
- }
- if (minute < 0 && hour < 0 && day < 0 && month < 0 && year < 0) {
- return null;
- }
- if (minute < 0) {
- minute = 0;
- }
- if (hour < 0) {
- hour = 0;
- }
- if (day < 0) {
- day = 1;
- }
- if (month < 0) {
- month = 1;
- }
- if (year < 0) {
- year = new Date().getFullYear();
- }
- if (isAm !== undefined) {
- if (isAm) {
- if (hour === 12) {
- hour = 0;
- }
- } else if (hour < 12) {
- hour += 12;
- }
- }
- var date = new Date(year, month - 1, day, hour, minute);
- if (date.getMonth() !== month - 1 || date.getFullYear() !== year) {
- //month or year don't match up, switch to last day of the month
- date = new Date(year, month, 0, hour, minute);
- }
- return isNaN(date.getTime()) ? null : date;
- }
- },
- // callback before date is changed, return false to cancel the change
- onBeforeChange: function (date, text, mode) {
- return true;
- },
- // callback when date changes
- onChange: function (date, text, mode) {
- },
- // callback before show animation, return false to prevent show
- onShow: function () {
- },
- // callback after show animation
- onVisible: function () {
- },
- // callback before hide animation, return false to prevent hide
- onHide: function () {
- },
- // callback after hide animation
- onHidden: function () {
- },
- // callback before item is selected, return false to prevent selection
- onSelect: function (date, mode) {
- },
- // is the given date disabled?
- isDisabled: function (date, mode) {
- return false;
- },
- selector: {
- popup: '.ui.popup',
- input: 'input',
- activator: 'input',
- append: '.inline.field,.inline.fields'
- },
- regExp: {
- dateWords: /[^A-Za-z\u00C0-\u024F]+/g,
- dateNumbers: /[^\d:]+/g
- },
- error: {
- popup: 'UI Popup, a required component is not included in this page',
- method: 'The method you called is not defined.'
- },
- className: {
- calendar: 'calendar',
- active: 'active',
- popup: 'ui popup',
- grid: 'ui equal width grid',
- column: 'column',
- table: 'ui celled center aligned unstackable table',
- prev: 'prev link',
- next: 'next link',
- prevIcon: 'chevron left icon',
- nextIcon: 'chevron right icon',
- link: 'link',
- cell: 'link',
- disabledCell: 'disabled',
- weekCell: 'disabled',
- adjacentCell: 'adjacent',
- activeCell: 'active',
- rangeCell: 'range',
- focusCell: 'focus',
- todayCell: 'today',
- today: 'today link'
- },
- metadata: {
- date: 'date',
- focusDate: 'focusDate',
- startDate: 'startDate',
- endDate: 'endDate',
- minDate: 'minDate',
- maxDate: 'maxDate',
- mode: 'mode',
- type: 'type',
- monthOffset: 'monthOffset',
- message: 'message',
- class: 'class',
- month: 'month',
- year: 'year'
- },
- eventClass: 'blue'
- };
- })(jQuery, window, document);
|