diff --git a/app/assets/javascripts/app/controllers/layout_ref.js.coffee b/app/assets/javascripts/app/controllers/layout_ref.js.coffee
index 1184dcec4..629286f21 100644
--- a/app/assets/javascripts/app/controllers/layout_ref.js.coffee
+++ b/app/assets/javascripts/app/controllers/layout_ref.js.coffee
@@ -843,6 +843,11 @@ class TicketZoomRef extends App.ControllerContent
colors: @colors
activeColorIndex: @activeColorIndex
+ @$('.js-datepicker').datepicker
+ todayHighlight: true
+ startDate: new Date().toLocaleDateString("en-US") # returns 9/25/2015
+ container: @$('.js-datepicker').parent()
+
# for testing purposes the highlights get stored in localStorage
loadHighlights: ->
if highlights = localStorage['highlights']
diff --git a/app/assets/javascripts/app/lib/bootstrap/bootstrap-datepicker.js b/app/assets/javascripts/app/lib/bootstrap/bootstrap-datepicker.js
new file mode 100755
index 000000000..3f58995c7
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/bootstrap-datepicker.js
@@ -0,0 +1,1944 @@
+/* =========================================================
+ * bootstrap-datepicker.js
+ * Repo: https://github.com/eternicode/bootstrap-datepicker/
+ * Demo: http://eternicode.github.io/bootstrap-datepicker/
+ * Docs: http://bootstrap-datepicker.readthedocs.org/
+ * Forked from http://www.eyecon.ro/bootstrap-datepicker
+ * =========================================================
+ * Started by Stefan Petre; improvements by Andrew Rowls + contributors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================= */
+
+ /*
+
+ Zammad Edits:
+ - fix todayBtn toggle of display none and block: toggleClass instead
+ - [ICONS]: hardwire our icons
+
+ */
+
+(function(factory){
+ if (typeof define === "function" && define.amd) {
+ define(["jquery"], factory);
+ } else if (typeof exports === 'object') {
+ factory(require('jquery'));
+ } else {
+ factory(jQuery);
+ }
+}(function($, undefined){
+
+ function UTCDate(){
+ return new Date(Date.UTC.apply(Date, arguments));
+ }
+ function UTCToday(){
+ var today = new Date();
+ return UTCDate(today.getFullYear(), today.getMonth(), today.getDate());
+ }
+ function isUTCEquals(date1, date2) {
+ return (
+ date1.getUTCFullYear() === date2.getUTCFullYear() &&
+ date1.getUTCMonth() === date2.getUTCMonth() &&
+ date1.getUTCDate() === date2.getUTCDate()
+ );
+ }
+ function alias(method){
+ return function(){
+ return this[method].apply(this, arguments);
+ };
+ }
+ function isValidDate(d) {
+ return d && !isNaN(d.getTime());
+ }
+
+ var DateArray = (function(){
+ var extras = {
+ get: function(i){
+ return this.slice(i)[0];
+ },
+ contains: function(d){
+ // Array.indexOf is not cross-browser;
+ // $.inArray doesn't work with Dates
+ var val = d && d.valueOf();
+ for (var i=0, l=this.length; i < l; i++)
+ if (this[i].valueOf() === val)
+ return i;
+ return -1;
+ },
+ remove: function(i){
+ this.splice(i,1);
+ },
+ replace: function(new_array){
+ if (!new_array)
+ return;
+ if (!$.isArray(new_array))
+ new_array = [new_array];
+ this.clear();
+ this.push.apply(this, new_array);
+ },
+ clear: function(){
+ this.length = 0;
+ },
+ copy: function(){
+ var a = new DateArray();
+ a.replace(this);
+ return a;
+ }
+ };
+
+ return function(){
+ var a = [];
+ a.push.apply(a, arguments);
+ $.extend(a, extras);
+ return a;
+ };
+ })();
+
+
+ // Picker object
+
+ var Datepicker = function(element, options){
+ this._process_options(options);
+
+ this.dates = new DateArray();
+ this.viewDate = this.o.defaultViewDate;
+ this.focusDate = null;
+
+ this.element = $(element);
+ this.isInline = false;
+ this.isInput = this.element.is('input');
+ this.component = this.element.hasClass('date') ? this.element.find('.add-on, .input-group-addon, .btn') : false;
+ this.hasInput = this.component && this.element.find('input').length;
+ if (this.component && this.component.length === 0)
+ this.component = false;
+
+ this.picker = $(DPGlobal.template);
+ this._buildEvents();
+ this._attachEvents();
+
+ if (this.isInline){
+ this.picker.addClass('datepicker-inline').appendTo(this.element);
+ }
+ else {
+ this.picker.addClass('datepicker-dropdown dropdown-menu');
+ }
+
+ if (this.o.rtl){
+ this.picker.addClass('datepicker-rtl');
+ }
+
+ this.viewMode = this.o.startView;
+
+ if (this.o.calendarWeeks)
+ this.picker.find('tfoot .today, tfoot .clear')
+ .attr('colspan', function(i, val){
+ return parseInt(val) + 1;
+ });
+
+ this._allow_update = false;
+
+ this.setStartDate(this._o.startDate);
+ this.setEndDate(this._o.endDate);
+ this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled);
+ this.setDaysOfWeekHighlighted(this.o.daysOfWeekHighlighted);
+ this.setDatesDisabled(this.o.datesDisabled);
+
+ this.fillDow();
+ this.fillMonths();
+
+ this._allow_update = true;
+
+ this.update();
+ this.showMode();
+
+ if (this.isInline){
+ this.show();
+ }
+ };
+
+ Datepicker.prototype = {
+ constructor: Datepicker,
+
+ _process_options: function(opts){
+ // Store raw options for reference
+ this._o = $.extend({}, this._o, opts);
+ // Processed options
+ var o = this.o = $.extend({}, this._o);
+
+ // Check if "de-DE" style date is available, if not language should
+ // fallback to 2 letter code eg "de"
+ var lang = o.language;
+ if (!dates[lang]){
+ lang = lang.split('-')[0];
+ if (!dates[lang])
+ lang = defaults.language;
+ }
+ o.language = lang;
+
+ switch (o.startView){
+ case 2:
+ case 'decade':
+ o.startView = 2;
+ break;
+ case 1:
+ case 'year':
+ o.startView = 1;
+ break;
+ default:
+ o.startView = 0;
+ }
+
+ switch (o.minViewMode){
+ case 1:
+ case 'months':
+ o.minViewMode = 1;
+ break;
+ case 2:
+ case 'years':
+ o.minViewMode = 2;
+ break;
+ default:
+ o.minViewMode = 0;
+ }
+
+ switch (o.maxViewMode) {
+ case 0:
+ case 'days':
+ o.maxViewMode = 0;
+ break;
+ case 1:
+ case 'months':
+ o.maxViewMode = 1;
+ break;
+ default:
+ o.maxViewMode = 2;
+ }
+
+ o.startView = Math.min(o.startView, o.maxViewMode);
+ o.startView = Math.max(o.startView, o.minViewMode);
+
+ // true, false, or Number > 0
+ if (o.multidate !== true){
+ o.multidate = Number(o.multidate) || false;
+ if (o.multidate !== false)
+ o.multidate = Math.max(0, o.multidate);
+ }
+ o.multidateSeparator = String(o.multidateSeparator);
+
+ o.weekStart %= 7;
+ o.weekEnd = ((o.weekStart + 6) % 7);
+
+ var format = DPGlobal.parseFormat(o.format);
+ if (o.startDate !== -Infinity){
+ if (!!o.startDate){
+ if (o.startDate instanceof Date)
+ o.startDate = this._local_to_utc(this._zero_time(o.startDate));
+ else
+ o.startDate = DPGlobal.parseDate(o.startDate, format, o.language);
+ }
+ else {
+ o.startDate = -Infinity;
+ }
+ }
+ if (o.endDate !== Infinity){
+ if (!!o.endDate){
+ if (o.endDate instanceof Date)
+ o.endDate = this._local_to_utc(this._zero_time(o.endDate));
+ else
+ o.endDate = DPGlobal.parseDate(o.endDate, format, o.language);
+ }
+ else {
+ o.endDate = Infinity;
+ }
+ }
+
+ o.daysOfWeekDisabled = o.daysOfWeekDisabled||[];
+ if (!$.isArray(o.daysOfWeekDisabled))
+ o.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\s]*/);
+ o.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function(d){
+ return parseInt(d, 10);
+ });
+
+ o.daysOfWeekHighlighted = o.daysOfWeekHighlighted||[];
+ if (!$.isArray(o.daysOfWeekHighlighted))
+ o.daysOfWeekHighlighted = o.daysOfWeekHighlighted.split(/[,\s]*/);
+ o.daysOfWeekHighlighted = $.map(o.daysOfWeekHighlighted, function(d){
+ return parseInt(d, 10);
+ });
+
+ o.datesDisabled = o.datesDisabled||[];
+ if (!$.isArray(o.datesDisabled)) {
+ var datesDisabled = [];
+ datesDisabled.push(DPGlobal.parseDate(o.datesDisabled, format, o.language));
+ o.datesDisabled = datesDisabled;
+ }
+ o.datesDisabled = $.map(o.datesDisabled,function(d){
+ return DPGlobal.parseDate(d, format, o.language);
+ });
+
+ var plc = String(o.orientation).toLowerCase().split(/\s+/g),
+ _plc = o.orientation.toLowerCase();
+ plc = $.grep(plc, function(word){
+ return /^auto|left|right|top|bottom$/.test(word);
+ });
+ o.orientation = {x: 'auto', y: 'auto'};
+ if (!_plc || _plc === 'auto')
+ ; // no action
+ else if (plc.length === 1){
+ switch (plc[0]){
+ case 'top':
+ case 'bottom':
+ o.orientation.y = plc[0];
+ break;
+ case 'left':
+ case 'right':
+ o.orientation.x = plc[0];
+ break;
+ }
+ }
+ else {
+ _plc = $.grep(plc, function(word){
+ return /^left|right$/.test(word);
+ });
+ o.orientation.x = _plc[0] || 'auto';
+
+ _plc = $.grep(plc, function(word){
+ return /^top|bottom$/.test(word);
+ });
+ o.orientation.y = _plc[0] || 'auto';
+ }
+ if (o.defaultViewDate) {
+ var year = o.defaultViewDate.year || new Date().getFullYear();
+ var month = o.defaultViewDate.month || 0;
+ var day = o.defaultViewDate.day || 1;
+ o.defaultViewDate = UTCDate(year, month, day);
+ } else {
+ o.defaultViewDate = UTCToday();
+ }
+ o.showOnFocus = o.showOnFocus !== undefined ? o.showOnFocus : true;
+ o.zIndexOffset = o.zIndexOffset !== undefined ? o.zIndexOffset : 10;
+ },
+ _events: [],
+ _secondaryEvents: [],
+ _applyEvents: function(evs){
+ for (var i=0, el, ch, ev; i < evs.length; i++){
+ el = evs[i][0];
+ if (evs[i].length === 2){
+ ch = undefined;
+ ev = evs[i][1];
+ }
+ else if (evs[i].length === 3){
+ ch = evs[i][1];
+ ev = evs[i][2];
+ }
+ el.on(ev, ch);
+ }
+ },
+ _unapplyEvents: function(evs){
+ for (var i=0, el, ev, ch; i < evs.length; i++){
+ el = evs[i][0];
+ if (evs[i].length === 2){
+ ch = undefined;
+ ev = evs[i][1];
+ }
+ else if (evs[i].length === 3){
+ ch = evs[i][1];
+ ev = evs[i][2];
+ }
+ el.off(ev, ch);
+ }
+ },
+ _buildEvents: function(){
+ var events = {
+ keyup: $.proxy(function(e){
+ if ($.inArray(e.keyCode, [27, 37, 39, 38, 40, 32, 13, 9]) === -1)
+ this.update();
+ }, this),
+ keydown: $.proxy(this.keydown, this),
+ paste: $.proxy(this.paste, this)
+ };
+
+ if (this.o.showOnFocus === true) {
+ events.focus = $.proxy(this.show, this);
+ }
+
+ if (this.isInput) { // single input
+ this._events = [
+ [this.element, events]
+ ];
+ }
+ else if (this.component && this.hasInput) { // component: input + button
+ this._events = [
+ // For components that are not readonly, allow keyboard nav
+ [this.element.find('input'), events],
+ [this.component, {
+ click: $.proxy(this.show, this)
+ }]
+ ];
+ }
+ else if (this.element.is('div')){ // inline datepicker
+ this.isInline = true;
+ }
+ else {
+ this._events = [
+ [this.element, {
+ click: $.proxy(this.show, this)
+ }]
+ ];
+ }
+ this._events.push(
+ // Component: listen for blur on element descendants
+ [this.element, '*', {
+ blur: $.proxy(function(e){
+ this._focused_from = e.target;
+ }, this)
+ }],
+ // Input: listen for blur on element
+ [this.element, {
+ blur: $.proxy(function(e){
+ this._focused_from = e.target;
+ }, this)
+ }]
+ );
+
+ if (this.o.immediateUpdates) {
+ // Trigger input updates immediately on changed year/month
+ this._events.push([this.element, {
+ 'changeYear changeMonth': $.proxy(function(e){
+ this.update(e.date);
+ }, this)
+ }]);
+ }
+
+ this._secondaryEvents = [
+ [this.picker, {
+ click: $.proxy(this.click, this)
+ }],
+ [$(window), {
+ resize: $.proxy(this.place, this)
+ }],
+ [$(document), {
+ mousedown: $.proxy(function(e){
+ // Clicked outside the datepicker, hide it
+ if (!(
+ this.element.is(e.target) ||
+ this.element.find(e.target).length ||
+ this.picker.is(e.target) ||
+ this.picker.find(e.target).length ||
+ this.picker.hasClass('datepicker-inline')
+ )){
+ this.hide();
+ }
+ }, this)
+ }]
+ ];
+ },
+ _attachEvents: function(){
+ this._detachEvents();
+ this._applyEvents(this._events);
+ },
+ _detachEvents: function(){
+ this._unapplyEvents(this._events);
+ },
+ _attachSecondaryEvents: function(){
+ this._detachSecondaryEvents();
+ this._applyEvents(this._secondaryEvents);
+ },
+ _detachSecondaryEvents: function(){
+ this._unapplyEvents(this._secondaryEvents);
+ },
+ _trigger: function(event, altdate){
+ var date = altdate || this.dates.get(-1),
+ local_date = this._utc_to_local(date);
+
+ this.element.trigger({
+ type: event,
+ date: local_date,
+ dates: $.map(this.dates, this._utc_to_local),
+ format: $.proxy(function(ix, format){
+ if (arguments.length === 0){
+ ix = this.dates.length - 1;
+ format = this.o.format;
+ }
+ else if (typeof ix === 'string'){
+ format = ix;
+ ix = this.dates.length - 1;
+ }
+ format = format || this.o.format;
+ var date = this.dates.get(ix);
+ return DPGlobal.formatDate(date, format, this.o.language);
+ }, this)
+ });
+ },
+
+ show: function(){
+ if (this.element.attr('readonly') && this.o.enableOnReadonly === false)
+ return;
+ if (!this.isInline)
+ this.picker.appendTo(this.o.container);
+ this.place();
+ this.picker.show();
+ this._attachSecondaryEvents();
+ this._trigger('show');
+ if ((window.navigator.msMaxTouchPoints || 'ontouchstart' in document) && this.o.disableTouchKeyboard) {
+ $(this.element).blur();
+ }
+ return this;
+ },
+
+ hide: function(){
+ if (this.isInline)
+ return this;
+ if (!this.picker.is(':visible'))
+ return this;
+ this.focusDate = null;
+ this.picker.hide().detach();
+ this._detachSecondaryEvents();
+ this.viewMode = this.o.startView;
+ this.showMode();
+
+ if (
+ this.o.forceParse &&
+ (
+ this.isInput && this.element.val() ||
+ this.hasInput && this.element.find('input').val()
+ )
+ )
+ this.setValue();
+ this._trigger('hide');
+ return this;
+ },
+
+ remove: function(){
+ this.hide();
+ this._detachEvents();
+ this._detachSecondaryEvents();
+ this.picker.remove();
+ delete this.element.data().datepicker;
+ if (!this.isInput){
+ delete this.element.data().date;
+ }
+ return this;
+ },
+
+ paste: function(evt){
+ var dateString;
+ if (evt.originalEvent.clipboardData && evt.originalEvent.clipboardData.types
+ && $.inArray('text/plain', evt.originalEvent.clipboardData.types) !== -1) {
+ dateString = evt.originalEvent.clipboardData.getData('text/plain');
+ }
+ else if (window.clipboardData) {
+ dateString = window.clipboardData.getData('Text');
+ }
+ else {
+ return;
+ }
+ this.setDate(dateString);
+ this.update();
+ evt.preventDefault();
+ },
+
+ _utc_to_local: function(utc){
+ return utc && new Date(utc.getTime() + (utc.getTimezoneOffset()*60000));
+ },
+ _local_to_utc: function(local){
+ return local && new Date(local.getTime() - (local.getTimezoneOffset()*60000));
+ },
+ _zero_time: function(local){
+ return local && new Date(local.getFullYear(), local.getMonth(), local.getDate());
+ },
+ _zero_utc_time: function(utc){
+ return utc && new Date(Date.UTC(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate()));
+ },
+
+ getDates: function(){
+ return $.map(this.dates, this._utc_to_local);
+ },
+
+ getUTCDates: function(){
+ return $.map(this.dates, function(d){
+ return new Date(d);
+ });
+ },
+
+ getDate: function(){
+ return this._utc_to_local(this.getUTCDate());
+ },
+
+ getUTCDate: function(){
+ var selected_date = this.dates.get(-1);
+ if (typeof selected_date !== 'undefined') {
+ return new Date(selected_date);
+ } else {
+ return null;
+ }
+ },
+
+ clearDates: function(){
+ var element;
+ if (this.isInput) {
+ element = this.element;
+ } else if (this.component) {
+ element = this.element.find('input');
+ }
+
+ if (element) {
+ element.val('');
+ }
+
+ this.update();
+ this._trigger('changeDate');
+
+ if (this.o.autoclose) {
+ this.hide();
+ }
+ },
+ setDates: function(){
+ var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
+ this.update.apply(this, args);
+ this._trigger('changeDate');
+ this.setValue();
+ return this;
+ },
+
+ setUTCDates: function(){
+ var args = $.isArray(arguments[0]) ? arguments[0] : arguments;
+ this.update.apply(this, $.map(args, this._utc_to_local));
+ this._trigger('changeDate');
+ this.setValue();
+ return this;
+ },
+
+ setDate: alias('setDates'),
+ setUTCDate: alias('setUTCDates'),
+
+ setValue: function(){
+ var formatted = this.getFormattedDate();
+ if (!this.isInput){
+ if (this.component){
+ this.element.find('input').val(formatted);
+ }
+ }
+ else {
+ this.element.val(formatted);
+ }
+ return this;
+ },
+
+ getFormattedDate: function(format){
+ if (format === undefined)
+ format = this.o.format;
+
+ var lang = this.o.language;
+ return $.map(this.dates, function(d){
+ return DPGlobal.formatDate(d, format, lang);
+ }).join(this.o.multidateSeparator);
+ },
+
+ setStartDate: function(startDate){
+ this._process_options({startDate: startDate});
+ this.update();
+ this.updateNavArrows();
+ return this;
+ },
+
+ setEndDate: function(endDate){
+ this._process_options({endDate: endDate});
+ this.update();
+ this.updateNavArrows();
+ return this;
+ },
+
+ setDaysOfWeekDisabled: function(daysOfWeekDisabled){
+ this._process_options({daysOfWeekDisabled: daysOfWeekDisabled});
+ this.update();
+ this.updateNavArrows();
+ return this;
+ },
+
+ setDaysOfWeekHighlighted: function(daysOfWeekHighlighted){
+ this._process_options({daysOfWeekHighlighted: daysOfWeekHighlighted});
+ this.update();
+ return this;
+ },
+
+ setDatesDisabled: function(datesDisabled){
+ this._process_options({datesDisabled: datesDisabled});
+ this.update();
+ this.updateNavArrows();
+ },
+
+ place: function(){
+ if (this.isInline)
+ return this;
+ var calendarWidth = this.picker.outerWidth(),
+ calendarHeight = this.picker.outerHeight(),
+ visualPadding = 10,
+ container = $(this.o.container),
+ windowWidth = container.width(),
+ scrollTop = container.scrollTop(),
+ appendOffset = container.offset();
+
+ var parentsZindex = [];
+ this.element.parents().each(function(){
+ var itemZIndex = $(this).css('z-index');
+ if (itemZIndex !== 'auto' && itemZIndex !== 0) parentsZindex.push(parseInt(itemZIndex));
+ });
+ var zIndex = Math.max.apply(Math, parentsZindex) + this.o.zIndexOffset;
+ var offset = this.component ? this.component.parent().offset() : this.element.offset();
+ var height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false);
+ var width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false);
+ var left = offset.left - appendOffset.left,
+ top = offset.top - appendOffset.top;
+
+ this.picker.removeClass(
+ 'datepicker-orient-top datepicker-orient-bottom '+
+ 'datepicker-orient-right datepicker-orient-left'
+ );
+
+ if (this.o.orientation.x !== 'auto'){
+ this.picker.addClass('datepicker-orient-' + this.o.orientation.x);
+ if (this.o.orientation.x === 'right')
+ left -= calendarWidth - width;
+ }
+ // auto x orientation is best-placement: if it crosses a window
+ // edge, fudge it sideways
+ else {
+ if (offset.left < 0) {
+ // component is outside the window on the left side. Move it into visible range
+ this.picker.addClass('datepicker-orient-left');
+ left -= offset.left - visualPadding;
+ } else if (left + calendarWidth > windowWidth) {
+ // the calendar passes the widow right edge. Align it to component right side
+ this.picker.addClass('datepicker-orient-right');
+ left = offset.left + width - calendarWidth;
+ } else {
+ // Default to left
+ this.picker.addClass('datepicker-orient-left');
+ }
+ }
+
+ // auto y orientation is best-situation: top or bottom, no fudging,
+ // decision based on which shows more of the calendar
+ var yorient = this.o.orientation.y,
+ top_overflow;
+ if (yorient === 'auto'){
+ top_overflow = -scrollTop + top - calendarHeight;
+ yorient = top_overflow < 0 ? 'bottom' : 'top';
+ }
+
+ this.picker.addClass('datepicker-orient-' + yorient);
+ if (yorient === 'top')
+ top -= calendarHeight + parseInt(this.picker.css('padding-top'));
+ else
+ top += height;
+
+ if (this.o.rtl) {
+ var right = windowWidth - (left + width);
+ this.picker.css({
+ top: top,
+ right: right,
+ zIndex: zIndex
+ });
+ } else {
+ this.picker.css({
+ top: top,
+ left: left,
+ zIndex: zIndex
+ });
+ }
+ return this;
+ },
+
+ _allow_update: true,
+ update: function(){
+ if (!this._allow_update)
+ return this;
+
+ var oldDates = this.dates.copy(),
+ dates = [],
+ fromArgs = false;
+ if (arguments.length){
+ $.each(arguments, $.proxy(function(i, date){
+ if (date instanceof Date)
+ date = this._local_to_utc(date);
+ dates.push(date);
+ }, this));
+ fromArgs = true;
+ }
+ else {
+ dates = this.isInput
+ ? this.element.val()
+ : this.element.data('date') || this.element.find('input').val();
+ if (dates && this.o.multidate)
+ dates = dates.split(this.o.multidateSeparator);
+ else
+ dates = [dates];
+ delete this.element.data().date;
+ }
+
+ dates = $.map(dates, $.proxy(function(date){
+ return DPGlobal.parseDate(date, this.o.format, this.o.language);
+ }, this));
+ dates = $.grep(dates, $.proxy(function(date){
+ return (
+ date < this.o.startDate ||
+ date > this.o.endDate ||
+ !date
+ );
+ }, this), true);
+ this.dates.replace(dates);
+
+ if (this.dates.length)
+ this.viewDate = new Date(this.dates.get(-1));
+ else if (this.viewDate < this.o.startDate)
+ this.viewDate = new Date(this.o.startDate);
+ else if (this.viewDate > this.o.endDate)
+ this.viewDate = new Date(this.o.endDate);
+ else
+ this.viewDate = this.o.defaultViewDate;
+
+ if (fromArgs){
+ // setting date by clicking
+ this.setValue();
+ }
+ else if (dates.length){
+ // setting date by typing
+ if (String(oldDates) !== String(this.dates))
+ this._trigger('changeDate');
+ }
+ if (!this.dates.length && oldDates.length)
+ this._trigger('clearDate');
+
+ this.fill();
+ this.element.change();
+ return this;
+ },
+
+ fillDow: function(){
+ var dowCnt = this.o.weekStart,
+ html = '
';
+ if (this.o.calendarWeeks){
+ this.picker.find('.datepicker-days .datepicker-switch')
+ .attr('colspan', function(i, val){
+ return parseInt(val) + 1;
+ });
+ html += ' ';
+ }
+ while (dowCnt < this.o.weekStart + 7){
+ html += ''+dates[this.o.language].daysMin[(dowCnt++)%7]+' ';
+ }
+ html += ' ';
+ this.picker.find('.datepicker-days thead').append(html);
+ },
+
+ fillMonths: function(){
+ var html = '',
+ i = 0;
+ while (i < 12){
+ html += ''+dates[this.o.language].monthsShort[i++]+' ';
+ }
+ this.picker.find('.datepicker-months td').html(html);
+ },
+
+ setRange: function(range){
+ if (!range || !range.length)
+ delete this.range;
+ else
+ this.range = $.map(range, function(d){
+ return d.valueOf();
+ });
+ this.fill();
+ },
+
+ getClassNames: function(date){
+ var cls = [],
+ year = this.viewDate.getUTCFullYear(),
+ month = this.viewDate.getUTCMonth(),
+ today = new Date();
+ if (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)){
+ cls.push('old');
+ }
+ else if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){
+ cls.push('new');
+ }
+ if (this.focusDate && date.valueOf() === this.focusDate.valueOf())
+ cls.push('focused');
+ // Compare internal UTC date with local today, not UTC today
+ if (this.o.todayHighlight &&
+ date.getUTCFullYear() === today.getFullYear() &&
+ date.getUTCMonth() === today.getMonth() &&
+ date.getUTCDate() === today.getDate()){
+ cls.push('today');
+ }
+ if (this.dates.contains(date) !== -1)
+ cls.push('active');
+ if (date.valueOf() < this.o.startDate || date.valueOf() > this.o.endDate ||
+ $.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1){
+ cls.push('disabled');
+ }
+ if ($.inArray(date.getUTCDay(), this.o.daysOfWeekHighlighted) !== -1){
+ cls.push('highlighted');
+ }
+ if (this.o.datesDisabled.length > 0 &&
+ $.grep(this.o.datesDisabled, function(d){
+ return isUTCEquals(date, d); }).length > 0) {
+ cls.push('disabled', 'disabled-date');
+ }
+
+ if (this.range){
+ if (date > this.range[0] && date < this.range[this.range.length-1]){
+ cls.push('range');
+ }
+ if ($.inArray(date.valueOf(), this.range) !== -1){
+ cls.push('selected');
+ }
+ if (date.valueOf() === this.range[0]){
+ cls.push('range-start');
+ }
+ if (date.valueOf() === this.range[this.range.length-1]){
+ cls.push('range-end');
+ }
+ }
+ return cls;
+ },
+
+ fill: function(){
+ var d = new Date(this.viewDate),
+ year = d.getUTCFullYear(),
+ month = d.getUTCMonth(),
+ startYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity,
+ startMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity,
+ endYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity,
+ endMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity,
+ todaytxt = dates[this.o.language].today || dates['en'].today || '',
+ cleartxt = dates[this.o.language].clear || dates['en'].clear || '',
+ titleFormat = dates[this.o.language].titleFormat || dates['en'].titleFormat,
+ tooltip;
+ if (isNaN(year) || isNaN(month))
+ return;
+ this.picker.find('.datepicker-days thead .datepicker-switch')
+ .text(DPGlobal.formatDate(new UTCDate(year, month), titleFormat, this.o.language));
+ this.picker.find('tfoot .today')
+ .text(todaytxt)
+ .toggleClass('hidden', this.o.todayBtn == false);
+ this.picker.find('tfoot .clear')
+ .text(cleartxt)
+ .toggle(this.o.clearBtn !== false);
+ this.picker.find('thead .datepicker-title')
+ .text(this.o.title)
+ .toggle(this.o.title !== '');
+ this.updateNavArrows();
+ this.fillMonths();
+ var prevMonth = UTCDate(year, month-1, 28),
+ day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());
+ prevMonth.setUTCDate(day);
+ prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7);
+ var nextMonth = new Date(prevMonth);
+ if (prevMonth.getUTCFullYear() < 100){
+ nextMonth.setUTCFullYear(prevMonth.getUTCFullYear());
+ }
+ nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);
+ nextMonth = nextMonth.valueOf();
+ var html = [];
+ var clsName;
+ while (prevMonth.valueOf() < nextMonth){
+ if (prevMonth.getUTCDay() === this.o.weekStart){
+ html.push('');
+ if (this.o.calendarWeeks){
+ // ISO 8601: First week contains first thursday.
+ // ISO also states week starts on Monday, but we can be more abstract here.
+ var
+ // Start of current week: based on weekstart/current date
+ ws = new Date(+prevMonth + (this.o.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),
+ // Thursday of this week
+ th = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),
+ // First Thursday of year, year from thursday
+ yth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay())%7*864e5),
+ // Calendar week: ms between thursdays, div ms per day, div 7 days
+ calWeek = (th - yth) / 864e5 / 7 + 1;
+ html.push(''+ calWeek +' ');
+
+ }
+ }
+ clsName = this.getClassNames(prevMonth);
+ clsName.push('day');
+
+ if (this.o.beforeShowDay !== $.noop){
+ var before = this.o.beforeShowDay(this._utc_to_local(prevMonth));
+ if (before === undefined)
+ before = {};
+ else if (typeof(before) === 'boolean')
+ before = {enabled: before};
+ else if (typeof(before) === 'string')
+ before = {classes: before};
+ if (before.enabled === false)
+ clsName.push('disabled');
+ if (before.classes)
+ clsName = clsName.concat(before.classes.split(/\s+/));
+ if (before.tooltip)
+ tooltip = before.tooltip;
+ }
+
+ clsName = $.unique(clsName);
+ html.push(''+prevMonth.getUTCDate() + ' ');
+ tooltip = null;
+ if (prevMonth.getUTCDay() === this.o.weekEnd){
+ html.push(' ');
+ }
+ prevMonth.setUTCDate(prevMonth.getUTCDate()+1);
+ }
+ this.picker.find('.datepicker-days tbody').empty().append(html.join(''));
+
+ var months = this.picker.find('.datepicker-months')
+ .find('.datepicker-switch')
+ .text(this.o.maxViewMode < 2 ? 'Months' : year)
+ .end()
+ .find('span').removeClass('active');
+
+ $.each(this.dates, function(i, d){
+ if (d.getUTCFullYear() === year)
+ months.eq(d.getUTCMonth()).addClass('active');
+ });
+
+ if (year < startYear || year > endYear){
+ months.addClass('disabled');
+ }
+ if (year === startYear){
+ months.slice(0, startMonth).addClass('disabled');
+ }
+ if (year === endYear){
+ months.slice(endMonth+1).addClass('disabled');
+ }
+
+ if (this.o.beforeShowMonth !== $.noop){
+ var that = this;
+ $.each(months, function(i, month){
+ if (!$(month).hasClass('disabled')) {
+ var moDate = new Date(year, i, 1);
+ var before = that.o.beforeShowMonth(moDate);
+ if (before === false)
+ $(month).addClass('disabled');
+ }
+ });
+ }
+
+ html = '';
+ year = parseInt(year/10, 10) * 10;
+ var yearCont = this.picker.find('.datepicker-years')
+ .find('.datepicker-switch')
+ .text(year + '-' + (year + 9))
+ .end()
+ .find('td');
+ year -= 1;
+ var years = $.map(this.dates, function(d){
+ return d.getUTCFullYear();
+ }),
+ classes;
+ for (var i = -1; i < 11; i++){
+ classes = ['year'];
+ tooltip = null;
+
+ if (i === -1)
+ classes.push('old');
+ else if (i === 10)
+ classes.push('new');
+ if ($.inArray(year, years) !== -1)
+ classes.push('active');
+ if (year < startYear || year > endYear)
+ classes.push('disabled');
+
+ if (this.o.beforeShowYear !== $.noop) {
+ var yrBefore = this.o.beforeShowYear(new Date(year, 0, 1));
+ if (yrBefore === undefined)
+ yrBefore = {};
+ else if (typeof(yrBefore) === 'boolean')
+ yrBefore = {enabled: yrBefore};
+ else if (typeof(yrBefore) === 'string')
+ yrBefore = {classes: yrBefore};
+ if (yrBefore.enabled === false)
+ classes.push('disabled');
+ if (yrBefore.classes)
+ classes = classes.concat(yrBefore.classes.split(/\s+/));
+ if (yrBefore.tooltip)
+ tooltip = yrBefore.tooltip;
+ }
+
+ html += '' + year + ' ';
+ year += 1;
+ }
+ yearCont.html(html);
+ },
+
+ updateNavArrows: function(){
+ if (!this._allow_update)
+ return;
+
+ var d = new Date(this.viewDate),
+ year = d.getUTCFullYear(),
+ month = d.getUTCMonth();
+ switch (this.viewMode){
+ case 0:
+ if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() && month <= this.o.startDate.getUTCMonth()){
+ this.picker.find('.prev').css({visibility: 'hidden'});
+ }
+ else {
+ this.picker.find('.prev').css({visibility: 'visible'});
+ }
+ if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() && month >= this.o.endDate.getUTCMonth()){
+ this.picker.find('.next').css({visibility: 'hidden'});
+ }
+ else {
+ this.picker.find('.next').css({visibility: 'visible'});
+ }
+ break;
+ case 1:
+ case 2:
+ if (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() || this.o.maxViewMode < 2){
+ this.picker.find('.prev').css({visibility: 'hidden'});
+ }
+ else {
+ this.picker.find('.prev').css({visibility: 'visible'});
+ }
+ if (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() || this.o.maxViewMode < 2){
+ this.picker.find('.next').css({visibility: 'hidden'});
+ }
+ else {
+ this.picker.find('.next').css({visibility: 'visible'});
+ }
+ break;
+ }
+ },
+
+ click: function(e){
+ e.preventDefault();
+ e.stopPropagation();
+ var target = $(e.target).closest('span, td, th'),
+ year, month, day;
+ if (target.length === 1){
+ switch (target[0].nodeName.toLowerCase()){
+ case 'th':
+ switch (target[0].className){
+ case 'datepicker-switch':
+ this.showMode(1);
+ break;
+ case 'prev':
+ case 'next':
+ var dir = DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1);
+ switch (this.viewMode){
+ case 0:
+ this.viewDate = this.moveMonth(this.viewDate, dir);
+ this._trigger('changeMonth', this.viewDate);
+ break;
+ case 1:
+ case 2:
+ this.viewDate = this.moveYear(this.viewDate, dir);
+ if (this.viewMode === 1)
+ this._trigger('changeYear', this.viewDate);
+ break;
+ }
+ this.fill();
+ break;
+ case 'today':
+ var date = new Date();
+ date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
+
+ this.showMode(-2);
+ var which = this.o.todayBtn === 'linked' ? null : 'view';
+ this._setDate(date, which);
+ break;
+ case 'clear':
+ this.clearDates();
+ break;
+ }
+ break;
+ case 'span':
+ if (!target.hasClass('disabled')){
+ this.viewDate.setUTCDate(1);
+ if (target.hasClass('month')){
+ day = 1;
+ month = target.parent().find('span').index(target);
+ year = this.viewDate.getUTCFullYear();
+ this.viewDate.setUTCMonth(month);
+ this._trigger('changeMonth', this.viewDate);
+ if (this.o.minViewMode === 1){
+ this._setDate(UTCDate(year, month, day));
+ this.showMode();
+ } else {
+ this.showMode(-1);
+ }
+ }
+ else {
+ day = 1;
+ month = 0;
+ year = parseInt(target.text(), 10)||0;
+ this.viewDate.setUTCFullYear(year);
+ this._trigger('changeYear', this.viewDate);
+ if (this.o.minViewMode === 2){
+ this._setDate(UTCDate(year, month, day));
+ }
+ this.showMode(-1);
+ }
+ this.fill();
+ }
+ break;
+ case 'td':
+ if (target.hasClass('day') && !target.hasClass('disabled')){
+ day = parseInt(target.text(), 10)||1;
+ year = this.viewDate.getUTCFullYear();
+ month = this.viewDate.getUTCMonth();
+ if (target.hasClass('old')){
+ if (month === 0){
+ month = 11;
+ year -= 1;
+ }
+ else {
+ month -= 1;
+ }
+ }
+ else if (target.hasClass('new')){
+ if (month === 11){
+ month = 0;
+ year += 1;
+ }
+ else {
+ month += 1;
+ }
+ }
+ this._setDate(UTCDate(year, month, day));
+ }
+ break;
+ }
+ }
+ if (this.picker.is(':visible') && this._focused_from){
+ $(this._focused_from).focus();
+ }
+ delete this._focused_from;
+ },
+
+ _toggle_multidate: function(date){
+ var ix = this.dates.contains(date);
+ if (!date){
+ this.dates.clear();
+ }
+
+ if (ix !== -1){
+ if (this.o.multidate === true || this.o.multidate > 1 || this.o.toggleActive){
+ this.dates.remove(ix);
+ }
+ } else if (this.o.multidate === false) {
+ this.dates.clear();
+ this.dates.push(date);
+ }
+ else {
+ this.dates.push(date);
+ }
+
+ if (typeof this.o.multidate === 'number')
+ while (this.dates.length > this.o.multidate)
+ this.dates.remove(0);
+ },
+
+ _setDate: function(date, which){
+ if (!which || which === 'date')
+ this._toggle_multidate(date && new Date(date));
+ if (!which || which === 'view')
+ this.viewDate = date && new Date(date);
+
+ this.fill();
+ this.setValue();
+ if (!which || which !== 'view') {
+ this._trigger('changeDate');
+ }
+ var element;
+ if (this.isInput){
+ element = this.element;
+ }
+ else if (this.component){
+ element = this.element.find('input');
+ }
+ if (element){
+ element.change();
+ }
+ if (this.o.autoclose && (!which || which === 'date')){
+ this.hide();
+ }
+ },
+
+ moveMonth: function(date, dir){
+ if (!isValidDate(date))
+ return this.o.defaultViewDate;
+ if (!dir)
+ return date;
+ var new_date = new Date(date.valueOf()),
+ day = new_date.getUTCDate(),
+ month = new_date.getUTCMonth(),
+ mag = Math.abs(dir),
+ new_month, test;
+ dir = dir > 0 ? 1 : -1;
+ if (mag === 1){
+ test = dir === -1
+ // If going back one month, make sure month is not current month
+ // (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02)
+ ? function(){
+ return new_date.getUTCMonth() === month;
+ }
+ // If going forward one month, make sure month is as expected
+ // (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02)
+ : function(){
+ return new_date.getUTCMonth() !== new_month;
+ };
+ new_month = month + dir;
+ new_date.setUTCMonth(new_month);
+ // Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11
+ if (new_month < 0 || new_month > 11)
+ new_month = (new_month + 12) % 12;
+ }
+ else {
+ // For magnitudes >1, move one month at a time...
+ for (var i=0; i < mag; i++)
+ // ...which might decrease the day (eg, Jan 31 to Feb 28, etc)...
+ new_date = this.moveMonth(new_date, dir);
+ // ...then reset the day, keeping it in the new month
+ new_month = new_date.getUTCMonth();
+ new_date.setUTCDate(day);
+ test = function(){
+ return new_month !== new_date.getUTCMonth();
+ };
+ }
+ // Common date-resetting loop -- if date is beyond end of month, make it
+ // end of month
+ while (test()){
+ new_date.setUTCDate(--day);
+ new_date.setUTCMonth(new_month);
+ }
+ return new_date;
+ },
+
+ moveYear: function(date, dir){
+ return this.moveMonth(date, dir*12);
+ },
+
+ dateWithinRange: function(date){
+ return date >= this.o.startDate && date <= this.o.endDate;
+ },
+
+ keydown: function(e){
+ if (!this.picker.is(':visible')){
+ if (e.keyCode === 40 || e.keyCode === 27) { // allow down to re-show picker
+ this.show();
+ e.stopPropagation();
+ }
+ return;
+ }
+ var dateChanged = false,
+ dir, newDate, newViewDate,
+ focusDate = this.focusDate || this.viewDate;
+ switch (e.keyCode){
+ case 27: // escape
+ if (this.focusDate){
+ this.focusDate = null;
+ this.viewDate = this.dates.get(-1) || this.viewDate;
+ this.fill();
+ }
+ else
+ this.hide();
+ e.preventDefault();
+ e.stopPropagation();
+ break;
+ case 37: // left
+ case 39: // right
+ if (!this.o.keyboardNavigation)
+ break;
+ dir = e.keyCode === 37 ? -1 : 1;
+ if (e.ctrlKey){
+ newDate = this.moveYear(this.dates.get(-1) || UTCToday(), dir);
+ newViewDate = this.moveYear(focusDate, dir);
+ this._trigger('changeYear', this.viewDate);
+ }
+ else if (e.shiftKey){
+ newDate = this.moveMonth(this.dates.get(-1) || UTCToday(), dir);
+ newViewDate = this.moveMonth(focusDate, dir);
+ this._trigger('changeMonth', this.viewDate);
+ }
+ else {
+ newDate = new Date(this.dates.get(-1) || UTCToday());
+ newDate.setUTCDate(newDate.getUTCDate() + dir);
+ newViewDate = new Date(focusDate);
+ newViewDate.setUTCDate(focusDate.getUTCDate() + dir);
+ }
+ if (this.dateWithinRange(newViewDate)){
+ this.focusDate = this.viewDate = newViewDate;
+ this.setValue();
+ this.fill();
+ e.preventDefault();
+ }
+ break;
+ case 38: // up
+ case 40: // down
+ if (!this.o.keyboardNavigation)
+ break;
+ dir = e.keyCode === 38 ? -1 : 1;
+ if (e.ctrlKey){
+ newDate = this.moveYear(this.dates.get(-1) || UTCToday(), dir);
+ newViewDate = this.moveYear(focusDate, dir);
+ this._trigger('changeYear', this.viewDate);
+ }
+ else if (e.shiftKey){
+ newDate = this.moveMonth(this.dates.get(-1) || UTCToday(), dir);
+ newViewDate = this.moveMonth(focusDate, dir);
+ this._trigger('changeMonth', this.viewDate);
+ }
+ else {
+ newDate = new Date(this.dates.get(-1) || UTCToday());
+ newDate.setUTCDate(newDate.getUTCDate() + dir * 7);
+ newViewDate = new Date(focusDate);
+ newViewDate.setUTCDate(focusDate.getUTCDate() + dir * 7);
+ }
+ if (this.dateWithinRange(newViewDate)){
+ this.focusDate = this.viewDate = newViewDate;
+ this.setValue();
+ this.fill();
+ e.preventDefault();
+ }
+ break;
+ case 32: // spacebar
+ // Spacebar is used in manually typing dates in some formats.
+ // As such, its behavior should not be hijacked.
+ break;
+ case 13: // enter
+ if (!this.o.forceParse) {
+ break;
+ }
+ focusDate = this.focusDate || this.dates.get(-1) || this.viewDate;
+ if (this.o.keyboardNavigation) {
+ this._toggle_multidate(focusDate);
+ dateChanged = true;
+ }
+ this.focusDate = null;
+ this.viewDate = this.dates.get(-1) || this.viewDate;
+ this.setValue();
+ this.fill();
+ if (this.picker.is(':visible')){
+ e.preventDefault();
+ if (typeof e.stopPropagation === 'function') {
+ e.stopPropagation(); // All modern browsers, IE9+
+ } else {
+ e.cancelBubble = true; // IE6,7,8 ignore "stopPropagation"
+ }
+ if (this.o.autoclose)
+ this.hide();
+ }
+ break;
+ case 9: // tab
+ this.focusDate = null;
+ this.viewDate = this.dates.get(-1) || this.viewDate;
+ this.fill();
+ this.hide();
+ break;
+ }
+ if (dateChanged){
+ if (this.dates.length)
+ this._trigger('changeDate');
+ else
+ this._trigger('clearDate');
+ var element;
+ if (this.isInput){
+ element = this.element;
+ }
+ else if (this.component){
+ element = this.element.find('input');
+ }
+ if (element){
+ element.change();
+ }
+ }
+ },
+
+ showMode: function(dir){
+ if (dir){
+ this.viewMode = Math.max(this.o.minViewMode, Math.min(this.o.maxViewMode, this.viewMode + dir));
+ }
+ this.picker
+ .children('div')
+ .hide()
+ .filter('.datepicker-' + DPGlobal.modes[this.viewMode].clsName)
+ .show();
+ this.updateNavArrows();
+ }
+ };
+
+ var DateRangePicker = function(element, options){
+ this.element = $(element);
+ this.inputs = $.map(options.inputs, function(i){
+ return i.jquery ? i[0] : i;
+ });
+ delete options.inputs;
+
+ datepickerPlugin.call($(this.inputs), options)
+ .on('changeDate', $.proxy(this.dateUpdated, this));
+
+ this.pickers = $.map(this.inputs, function(i){
+ return $(i).data('datepicker');
+ });
+ this.updateDates();
+ };
+ DateRangePicker.prototype = {
+ updateDates: function(){
+ this.dates = $.map(this.pickers, function(i){
+ return i.getUTCDate();
+ });
+ this.updateRanges();
+ },
+ updateRanges: function(){
+ var range = $.map(this.dates, function(d){
+ return d.valueOf();
+ });
+ $.each(this.pickers, function(i, p){
+ p.setRange(range);
+ });
+ },
+ dateUpdated: function(e){
+ // `this.updating` is a workaround for preventing infinite recursion
+ // between `changeDate` triggering and `setUTCDate` calling. Until
+ // there is a better mechanism.
+ if (this.updating)
+ return;
+ this.updating = true;
+
+ var dp = $(e.target).data('datepicker');
+
+ if (typeof(dp) === "undefined") {
+ return;
+ }
+
+ var new_date = dp.getUTCDate(),
+ i = $.inArray(e.target, this.inputs),
+ j = i - 1,
+ k = i + 1,
+ l = this.inputs.length;
+ if (i === -1)
+ return;
+
+ $.each(this.pickers, function(i, p){
+ if (!p.getUTCDate())
+ p.setUTCDate(new_date);
+ });
+
+ if (new_date < this.dates[j]){
+ // Date being moved earlier/left
+ while (j >= 0 && new_date < this.dates[j]){
+ this.pickers[j--].setUTCDate(new_date);
+ }
+ }
+ else if (new_date > this.dates[k]){
+ // Date being moved later/right
+ while (k < l && new_date > this.dates[k]){
+ this.pickers[k++].setUTCDate(new_date);
+ }
+ }
+ this.updateDates();
+
+ delete this.updating;
+ },
+ remove: function(){
+ $.map(this.pickers, function(p){ p.remove(); });
+ delete this.element.data().datepicker;
+ }
+ };
+
+ function opts_from_el(el, prefix){
+ // Derive options from element data-attrs
+ var data = $(el).data(),
+ out = {}, inkey,
+ replace = new RegExp('^' + prefix.toLowerCase() + '([A-Z])');
+ prefix = new RegExp('^' + prefix.toLowerCase());
+ function re_lower(_,a){
+ return a.toLowerCase();
+ }
+ for (var key in data)
+ if (prefix.test(key)){
+ inkey = key.replace(replace, re_lower);
+ out[inkey] = data[key];
+ }
+ return out;
+ }
+
+ function opts_from_locale(lang){
+ // Derive options from locale plugins
+ var out = {};
+ // Check if "de-DE" style date is available, if not language should
+ // fallback to 2 letter code eg "de"
+ if (!dates[lang]){
+ lang = lang.split('-')[0];
+ if (!dates[lang])
+ return;
+ }
+ var d = dates[lang];
+ $.each(locale_opts, function(i,k){
+ if (k in d)
+ out[k] = d[k];
+ });
+ return out;
+ }
+
+ var old = $.fn.datepicker;
+ var datepickerPlugin = function(option){
+ var args = Array.apply(null, arguments);
+ args.shift();
+ var internal_return;
+ this.each(function(){
+ var $this = $(this),
+ data = $this.data('datepicker'),
+ options = typeof option === 'object' && option;
+ if (!data){
+ var elopts = opts_from_el(this, 'date'),
+ // Preliminary otions
+ xopts = $.extend({}, defaults, elopts, options),
+ locopts = opts_from_locale(xopts.language),
+ // Options priority: js args, data-attrs, locales, defaults
+ opts = $.extend({}, defaults, locopts, elopts, options);
+ if ($this.hasClass('input-daterange') || opts.inputs){
+ var ropts = {
+ inputs: opts.inputs || $this.find('input').toArray()
+ };
+ $this.data('datepicker', (data = new DateRangePicker(this, $.extend(opts, ropts))));
+ }
+ else {
+ $this.data('datepicker', (data = new Datepicker(this, opts)));
+ }
+ }
+ if (typeof option === 'string' && typeof data[option] === 'function'){
+ internal_return = data[option].apply(data, args);
+ }
+ });
+
+ if (
+ internal_return === undefined ||
+ internal_return instanceof Datepicker ||
+ internal_return instanceof DateRangePicker
+ )
+ return this;
+
+ if (this.length > 1)
+ throw new Error('Using only allowed for the collection of a single element (' + option + ' function)');
+ else
+ return internal_return;
+ };
+ $.fn.datepicker = datepickerPlugin;
+
+ var defaults = $.fn.datepicker.defaults = {
+ autoclose: false,
+ beforeShowDay: $.noop,
+ beforeShowMonth: $.noop,
+ beforeShowYear: $.noop,
+ calendarWeeks: false,
+ clearBtn: false,
+ toggleActive: false,
+ daysOfWeekDisabled: [],
+ daysOfWeekHighlighted: [],
+ datesDisabled: [],
+ endDate: Infinity,
+ forceParse: true,
+ format: 'mm/dd/yyyy',
+ keyboardNavigation: true,
+ language: 'en',
+ minViewMode: 0,
+ maxViewMode: 2,
+ multidate: false,
+ multidateSeparator: ',',
+ orientation: "auto",
+ rtl: false,
+ startDate: -Infinity,
+ startView: 0,
+ todayBtn: false,
+ todayHighlight: false,
+ weekStart: 0,
+ disableTouchKeyboard: false,
+ enableOnReadonly: true,
+ container: 'body',
+ immediateUpdates: false,
+ title: ''
+ };
+ var locale_opts = $.fn.datepicker.locale_opts = [
+ 'format',
+ 'rtl',
+ 'weekStart'
+ ];
+ $.fn.datepicker.Constructor = Datepicker;
+ var dates = $.fn.datepicker.dates = {
+ en: {
+ days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
+ daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
+ daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
+ 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",
+ clear: "Clear",
+ titleFormat: "MM yyyy"
+ }
+ };
+
+ var DPGlobal = {
+ modes: [
+ {
+ clsName: 'days',
+ navFnc: 'Month',
+ navStep: 1
+ },
+ {
+ clsName: 'months',
+ navFnc: 'FullYear',
+ navStep: 1
+ },
+ {
+ clsName: 'years',
+ navFnc: 'FullYear',
+ navStep: 10
+ }],
+ isLeapYear: function(year){
+ return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));
+ },
+ getDaysInMonth: function(year, month){
+ return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
+ },
+ validParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g,
+ nonpunctuation: /[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g,
+ parseFormat: function(format){
+ if (typeof format.toValue === 'function' && typeof format.toDisplay === 'function')
+ return format;
+ // IE treats \0 as a string end in inputs (truncating the value),
+ // so it's a bad format delimiter, anyway
+ var separators = format.replace(this.validParts, '\0').split('\0'),
+ parts = format.match(this.validParts);
+ if (!separators || !separators.length || !parts || parts.length === 0){
+ throw new Error("Invalid date format.");
+ }
+ return {separators: separators, parts: parts};
+ },
+ parseDate: function(date, format, language){
+ if (!date)
+ return undefined;
+ if (date instanceof Date)
+ return date;
+ if (typeof format === 'string')
+ format = DPGlobal.parseFormat(format);
+ if (format.toValue)
+ return format.toValue(date, format, language);
+ var part_re = /([\-+]\d+)([dmwy])/,
+ parts = date.match(/([\-+]\d+)([dmwy])/g),
+ part, dir, i;
+ if (/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(date)){
+ date = new Date();
+ for (i=0; i < parts.length; i++){
+ part = part_re.exec(parts[i]);
+ dir = parseInt(part[1]);
+ switch (part[2]){
+ case 'd':
+ date.setUTCDate(date.getUTCDate() + dir);
+ break;
+ case 'm':
+ date = Datepicker.prototype.moveMonth.call(Datepicker.prototype, date, dir);
+ break;
+ case 'w':
+ date.setUTCDate(date.getUTCDate() + dir * 7);
+ break;
+ case 'y':
+ date = Datepicker.prototype.moveYear.call(Datepicker.prototype, date, dir);
+ break;
+ }
+ }
+ return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 0, 0, 0);
+ }
+ parts = date && date.match(this.nonpunctuation) || [];
+ date = new Date();
+ var parsed = {},
+ setters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'],
+ setters_map = {
+ yyyy: function(d,v){
+ return d.setUTCFullYear(v);
+ },
+ yy: function(d,v){
+ return d.setUTCFullYear(2000+v);
+ },
+ m: function(d,v){
+ if (isNaN(d))
+ return d;
+ v -= 1;
+ while (v < 0) v += 12;
+ v %= 12;
+ d.setUTCMonth(v);
+ while (d.getUTCMonth() !== v)
+ d.setUTCDate(d.getUTCDate()-1);
+ return d;
+ },
+ d: function(d,v){
+ return d.setUTCDate(v);
+ }
+ },
+ val, filtered;
+ setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];
+ setters_map['dd'] = setters_map['d'];
+ date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);
+ var fparts = format.parts.slice();
+ // Remove noop parts
+ if (parts.length !== fparts.length){
+ fparts = $(fparts).filter(function(i,p){
+ return $.inArray(p, setters_order) !== -1;
+ }).toArray();
+ }
+ // Process remainder
+ function match_part(){
+ var m = this.slice(0, parts[i].length),
+ p = parts[i].slice(0, m.length);
+ return m.toLowerCase() === p.toLowerCase();
+ }
+ if (parts.length === fparts.length){
+ var cnt;
+ for (i=0, cnt = fparts.length; i < cnt; i++){
+ val = parseInt(parts[i], 10);
+ part = fparts[i];
+ if (isNaN(val)){
+ switch (part){
+ case 'MM':
+ filtered = $(dates[language].months).filter(match_part);
+ val = $.inArray(filtered[0], dates[language].months) + 1;
+ break;
+ case 'M':
+ filtered = $(dates[language].monthsShort).filter(match_part);
+ val = $.inArray(filtered[0], dates[language].monthsShort) + 1;
+ break;
+ }
+ }
+ parsed[part] = val;
+ }
+ var _date, s;
+ for (i=0; i < setters_order.length; i++){
+ s = setters_order[i];
+ if (s in parsed && !isNaN(parsed[s])){
+ _date = new Date(date);
+ setters_map[s](_date, parsed[s]);
+ if (!isNaN(_date))
+ date = _date;
+ }
+ }
+ }
+ return date;
+ },
+ formatDate: function(date, format, language){
+ if (!date)
+ return '';
+ if (typeof format === 'string')
+ format = DPGlobal.parseFormat(format);
+ if (format.toDisplay)
+ return format.toDisplay(date, format, language);
+ var val = {
+ d: date.getUTCDate(),
+ D: dates[language].daysShort[date.getUTCDay()],
+ DD: dates[language].days[date.getUTCDay()],
+ m: date.getUTCMonth() + 1,
+ M: dates[language].monthsShort[date.getUTCMonth()],
+ MM: dates[language].months[date.getUTCMonth()],
+ yy: date.getUTCFullYear().toString().substring(2),
+ yyyy: date.getUTCFullYear()
+ };
+ val.dd = (val.d < 10 ? '0' : '') + val.d;
+ val.mm = (val.m < 10 ? '0' : '') + val.m;
+ date = [];
+ var seps = $.extend([], format.separators);
+ for (var i=0, cnt = format.parts.length; i <= cnt; i++){
+ if (seps.length)
+ date.push(seps.shift());
+ date.push(val[format.parts[i]]);
+ }
+ return date.join('');
+ },
+ headTemplate: ''+
+ ''+
+ ' '+
+ ' '+
+ ''+
+ ' '+
+ ' '+
+ ' '+
+ ' '+
+ ' ',
+ contTemplate: ' ',
+ footTemplate: ''+
+ ''+
+ ' '+
+ ' '+
+ ''+
+ ' '+
+ ' '+
+ ' '
+ };
+ DPGlobal.template = ''+
+ '
'+
+ '
'+
+ DPGlobal.headTemplate+
+ ' '+
+ DPGlobal.footTemplate+
+ '
'+
+ '
'+
+ '
'+
+ '
'+
+ DPGlobal.headTemplate+
+ DPGlobal.contTemplate+
+ DPGlobal.footTemplate+
+ '
'+
+ '
'+
+ '
'+
+ '
'+
+ DPGlobal.headTemplate+
+ DPGlobal.contTemplate+
+ DPGlobal.footTemplate+
+ '
'+
+ '
'+
+ '
';
+
+ $.fn.datepicker.DPGlobal = DPGlobal;
+
+
+ /* DATEPICKER NO CONFLICT
+ * =================== */
+
+ $.fn.datepicker.noConflict = function(){
+ $.fn.datepicker = old;
+ return this;
+ };
+
+ /* DATEPICKER VERSION
+ * =================== */
+ $.fn.datepicker.version = "1.4.1-dev";
+
+ /* DATEPICKER DATA-API
+ * ================== */
+
+ $(document).on(
+ 'focus.datepicker.data-api click.datepicker.data-api',
+ '[data-provide="datepicker"]',
+ function(e){
+ var $this = $(this);
+ if ($this.data('datepicker'))
+ return;
+ e.preventDefault();
+ // component click requires us to explicitly show it
+ datepickerPlugin.call($this, 'show');
+ }
+ );
+ $(function(){
+ datepickerPlugin.call($('[data-provide="datepicker-inline"]'));
+ });
+
+}));
\ No newline at end of file
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ar.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ar.js
new file mode 100755
index 000000000..12ae1821d
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ar.js
@@ -0,0 +1,15 @@
+/**
+ * Arabic translation for bootstrap-datepicker
+ * Mohammed Alshehri
+ */
+;(function($){
+ $.fn.datepicker.dates['ar'] = {
+ days: ["الأحد", "الاثنين", "الثلاثاء", "الأربعاء", "الخميس", "الجمعة", "السبت", "الأحد"],
+ daysShort: ["أحد", "اثنين", "ثلاثاء", "أربعاء", "خميس", "جمعة", "سبت", "أحد"],
+ daysMin: ["ح", "ن", "ث", "ع", "خ", "ج", "س", "ح"],
+ months: ["يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو", "يوليو", "أغسطس", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر"],
+ monthsShort: ["يناير", "فبراير", "مارس", "أبريل", "مايو", "يونيو", "يوليو", "أغسطس", "سبتمبر", "أكتوبر", "نوفمبر", "ديسمبر"],
+ today: "هذا اليوم",
+ rtl: true
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.az.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.az.js
new file mode 100755
index 000000000..460bfd44e
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.az.js
@@ -0,0 +1,12 @@
+// Azerbaijani
+;(function($){
+ $.fn.datepicker.dates['az'] = {
+ days: ["Bazar", "Bazar ertəsi", "Çərşənbə axşamı", "Çərşənbə", "Cümə axşamı", "Cümə", "Şənbə"],
+ daysShort: ["B.", "B.e", "Ç.a", "Ç.", "C.a", "C.", "Ş."],
+ daysMin: ["B.", "B.e", "Ç.a", "Ç.", "C.a", "C.", "Ş."],
+ months: ["Yanvar", "Fevral", "Mart", "Aprel", "May", "İyun", "İyul", "Avqust", "Sentyabr", "Oktyabr", "Noyabr", "Dekabr"],
+ monthsShort: ["Yan", "Fev", "Mar", "Apr", "May", "İyun", "İyul", "Avq", "Sen", "Okt", "Noy", "Dek"],
+ today: "Bu gün",
+ weekStart: 1
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.bg.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.bg.js
new file mode 100755
index 000000000..3193e199b
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.bg.js
@@ -0,0 +1,14 @@
+/**
+ * Bulgarian translation for bootstrap-datepicker
+ * Apostol Apostolov
+ */
+;(function($){
+ $.fn.datepicker.dates['bg'] = {
+ days: ["Неделя", "Понеделник", "Вторник", "Сряда", "Четвъртък", "Петък", "Събота"],
+ daysShort: ["Нед", "Пон", "Вто", "Сря", "Чет", "Пет", "Съб"],
+ daysMin: ["Н", "П", "В", "С", "Ч", "П", "С"],
+ months: ["Януари", "Февруари", "Март", "Април", "Май", "Юни", "Юли", "Август", "Септември", "Октомври", "Ноември", "Декември"],
+ monthsShort: ["Ян", "Фев", "Мар", "Апр", "Май", "Юни", "Юли", "Авг", "Сеп", "Окт", "Ное", "Дек"],
+ today: "днес"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.bs.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.bs.js
new file mode 100755
index 000000000..4a76529d9
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.bs.js
@@ -0,0 +1,15 @@
+/**
+ * Bosnian translation for bootstrap-datepicker
+ */
+;(function($){
+ $.fn.datepicker.dates['bs'] = {
+ days: ["Nedjelja","Ponedjeljak", "Utorak", "Srijeda", "Četvrtak", "Petak", "Subota"],
+ daysShort: ["Ned", "Pon", "Uto", "Sri", "Čet", "Pet", "Sub"],
+ daysMin: ["N", "Po", "U", "Sr", "Č", "Pe", "Su"],
+ months: ["Januar", "Februar", "Mart", "April", "Maj", "Juni", "Juli", "August", "Septembar", "Oktobar", "Novembar", "Decembar"],
+ monthsShort: ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"],
+ today: "Danas",
+ weekStart: 1,
+ format: "dd.mm.yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ca.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ca.js
new file mode 100755
index 000000000..d4e7e9a3d
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ca.js
@@ -0,0 +1,17 @@
+/**
+ * Catalan translation for bootstrap-datepicker
+ * J. Garcia
+ */
+;(function($){
+ $.fn.datepicker.dates['ca'] = {
+ days: ["Diumenge", "Dilluns", "Dimarts", "Dimecres", "Dijous", "Divendres", "Dissabte"],
+ daysShort: ["Diu", "Dil", "Dmt", "Dmc", "Dij", "Div", "Dis"],
+ daysMin: ["dg", "dl", "dt", "dc", "dj", "dv", "ds"],
+ months: ["Gener", "Febrer", "Març", "Abril", "Maig", "Juny", "Juliol", "Agost", "Setembre", "Octubre", "Novembre", "Desembre"],
+ monthsShort: ["Gen", "Feb", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Oct", "Nov", "Des"],
+ today: "Avui",
+ clear: "Esborrar",
+ weekStart: 1,
+ format: "dd/mm/yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.cs.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.cs.js
new file mode 100755
index 000000000..8cc17d638
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.cs.js
@@ -0,0 +1,18 @@
+/**
+ * Czech translation for bootstrap-datepicker
+ * Matěj Koubík
+ * Fixes by Michal Remiš
+ */
+;(function($){
+ $.fn.datepicker.dates['cs'] = {
+ days: ["Neděle", "Pondělí", "Úterý", "Středa", "Čtvrtek", "Pátek", "Sobota"],
+ daysShort: ["Ned", "Pon", "Úte", "Stř", "Čtv", "Pát", "Sob"],
+ daysMin: ["Ne", "Po", "Út", "St", "Čt", "Pá", "So"],
+ months: ["Leden", "Únor", "Březen", "Duben", "Květen", "Červen", "Červenec", "Srpen", "Září", "Říjen", "Listopad", "Prosinec"],
+ monthsShort: ["Led", "Úno", "Bře", "Dub", "Kvě", "Čer", "Čnc", "Srp", "Zář", "Říj", "Lis", "Pro"],
+ today: "Dnes",
+ clear: "Vymazat",
+ weekStart: 1,
+ format: "dd.m.yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.cy.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.cy.js
new file mode 100755
index 000000000..553933bc6
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.cy.js
@@ -0,0 +1,14 @@
+/**
+ * Welsh translation for bootstrap-datepicker
+ * S. Morris
+ */
+;(function($){
+ $.fn.datepicker.dates['cy'] = {
+ days: ["Sul", "Llun", "Mawrth", "Mercher", "Iau", "Gwener", "Sadwrn"],
+ daysShort: ["Sul", "Llu", "Maw", "Mer", "Iau", "Gwe", "Sad"],
+ daysMin: ["Su", "Ll", "Ma", "Me", "Ia", "Gwe", "Sa"],
+ months: ["Ionawr", "Chewfror", "Mawrth", "Ebrill", "Mai", "Mehefin", "Gorfennaf", "Awst", "Medi", "Hydref", "Tachwedd", "Rhagfyr"],
+ monthsShort: ["Ion", "Chw", "Maw", "Ebr", "Mai", "Meh", "Gor", "Aws", "Med", "Hyd", "Tach", "Rha"],
+ today: "Heddiw"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.da.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.da.js
new file mode 100755
index 000000000..540dd6dd2
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.da.js
@@ -0,0 +1,16 @@
+/**
+ * Danish translation for bootstrap-datepicker
+ * Christian Pedersen
+ * Ivan Mylyanyk
+ */
+;(function($){
+ $.fn.datepicker.dates['da'] = {
+ days: ["søndag", "mandag", "tirsdag", "onsdag", "torsdag", "fredag", "lørdag"],
+ daysShort: ["søn", "man", "tir", "ons", "tor", "fre", "lør"],
+ daysMin: ["sø", "ma", "ti", "on", "to", "fr", "lø"],
+ months: ["januar", "februar", "marts", "april", "maj", "juni", "juli", "august", "september", "oktober", "november", "december"],
+ monthsShort: ["jan", "feb", "mar", "apr", "maj", "jun", "jul", "aug", "sep", "okt", "nov", "dec"],
+ today: "I Dag",
+ clear: "Nulstil"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.de.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.de.js
new file mode 100755
index 000000000..a04d8f19e
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.de.js
@@ -0,0 +1,17 @@
+/**
+ * German translation for bootstrap-datepicker
+ * Sam Zurcher
+ */
+;(function($){
+ $.fn.datepicker.dates['de'] = {
+ days: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"],
+ daysShort: ["Son", "Mon", "Die", "Mit", "Don", "Fre", "Sam"],
+ daysMin: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"],
+ months: ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"],
+ monthsShort: ["Jan", "Feb", "Mär", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"],
+ today: "Heute",
+ clear: "Löschen",
+ weekStart: 1,
+ format: "dd.mm.yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.el.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.el.js
new file mode 100755
index 000000000..5e00c7d4a
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.el.js
@@ -0,0 +1,16 @@
+/**
+ * Greek translation for bootstrap-datepicker
+ */
+;(function($){
+ $.fn.datepicker.dates['el'] = {
+ days: ["Κυριακή", "Δευτέρα", "Τρίτη", "Τετάρτη", "Πέμπτη", "Παρασκευή", "Σάββατο"],
+ daysShort: ["Κυρ", "Δευ", "Τρι", "Τετ", "Πεμ", "Παρ", "Σαβ"],
+ daysMin: ["Κυ", "Δε", "Τρ", "Τε", "Πε", "Πα", "Σα"],
+ months: ["Ιανουάριος", "Φεβρουάριος", "Μάρτιος", "Απρίλιος", "Μάιος", "Ιούνιος", "Ιούλιος", "Αύγουστος", "Σεπτέμβριος", "Οκτώβριος", "Νοέμβριος", "Δεκέμβριος"],
+ monthsShort: ["Ιαν", "Φεβ", "Μαρ", "Απρ", "Μάι", "Ιουν", "Ιουλ", "Αυγ", "Σεπ", "Οκτ", "Νοε", "Δεκ"],
+ today: "Σήμερα",
+ clear: "Καθαρισμός",
+ weekStart: 1,
+ format: "d/m/yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.en-GB.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.en-GB.js
new file mode 100755
index 000000000..4e0e57deb
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.en-GB.js
@@ -0,0 +1,17 @@
+/**
+ * British English translation for bootstrap-datepicker
+ * Xavier Dutreilh
+ */
+;(function($){
+ $.fn.datepicker.dates['en-GB'] = {
+ days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
+ daysShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
+ daysMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
+ 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",
+ clear: "Clear",
+ weekStart: 1,
+ format: "dd/mm/yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.eo.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.eo.js
new file mode 100755
index 000000000..98e498875
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.eo.js
@@ -0,0 +1,17 @@
+/**
+ * Esperanto translation for bootstrap-datepicker
+ * Emmanuel Debanne
+ */
+;(function($){
+ $.fn.datepicker.dates['eo'] = {
+ days: ["dimanĉo", "lundo", "mardo", "merkredo", "ĵaŭdo", "vendredo", "sabato"],
+ daysShort: ["dim.", "lun.", "mar.", "mer.", "ĵaŭ.", "ven.", "sam."],
+ daysMin: ["d", "l", "ma", "me", "ĵ", "v", "s"],
+ months: ["januaro", "februaro", "marto", "aprilo", "majo", "junio", "julio", "aŭgusto", "septembro", "oktobro", "novembro", "decembro"],
+ monthsShort: ["jan.", "feb.", "mar.", "apr.", "majo", "jun.", "jul.", "aŭg.", "sep.", "okt.", "nov.", "dec."],
+ today: "Hodiaŭ",
+ clear: "Nuligi",
+ weekStart: 1,
+ format: "yyyy-mm-dd"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.es.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.es.js
new file mode 100755
index 000000000..12b729c26
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.es.js
@@ -0,0 +1,17 @@
+/**
+ * Spanish translation for bootstrap-datepicker
+ * Bruno Bonamin
+ */
+;(function($){
+ $.fn.datepicker.dates['es'] = {
+ days: ["Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado"],
+ daysShort: ["Dom", "Lun", "Mar", "Mié", "Jue", "Vie", "Sáb"],
+ daysMin: ["Do", "Lu", "Ma", "Mi", "Ju", "Vi", "Sa"],
+ months: ["Enero", "Febrero", "Marzo", "Abril", "Mayo", "Junio", "Julio", "Agosto", "Septiembre", "Octubre", "Noviembre", "Diciembre"],
+ monthsShort: ["Ene", "Feb", "Mar", "Abr", "May", "Jun", "Jul", "Ago", "Sep", "Oct", "Nov", "Dic"],
+ today: "Hoy",
+ clear: "Borrar",
+ weekStart: 1,
+ format: "dd/mm/yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.et.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.et.js
new file mode 100755
index 000000000..7f7100d42
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.et.js
@@ -0,0 +1,18 @@
+/**
+ * Estonian translation for bootstrap-datepicker
+ * Ando Roots
+ * Fixes by Illimar Tambek <
+ */
+;(function($){
+ $.fn.datepicker.dates['et'] = {
+ days: ["Pühapäev", "Esmaspäev", "Teisipäev", "Kolmapäev", "Neljapäev", "Reede", "Laupäev"],
+ daysShort: ["Pühap", "Esmasp", "Teisip", "Kolmap", "Neljap", "Reede", "Laup"],
+ daysMin: ["P", "E", "T", "K", "N", "R", "L"],
+ months: ["Jaanuar", "Veebruar", "Märts", "Aprill", "Mai", "Juuni", "Juuli", "August", "September", "Oktoober", "November", "Detsember"],
+ monthsShort: ["Jaan", "Veebr", "Märts", "Apr", "Mai", "Juuni", "Juuli", "Aug", "Sept", "Okt", "Nov", "Dets"],
+ today: "Täna",
+ clear: "Tühjenda",
+ weekStart: 1,
+ format: "dd.mm.yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.eu.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.eu.js
new file mode 100755
index 000000000..e727cc3ad
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.eu.js
@@ -0,0 +1,15 @@
+/**
+ * Basque translation for bootstrap-datepicker
+ * Arkaitz Etxeberria
+ */
+;(function($){
+ $.fn.datepicker.dates['eu'] = {
+ days: ['Igandea', 'Astelehena', 'Asteartea', 'Asteazkena', 'Osteguna', 'Ostirala', 'Larunbata'],
+ daysShort: ['Ig', 'Al', 'Ar', 'Az', 'Og', 'Ol', 'Lr'],
+ daysMin: ['Ig', 'Al', 'Ar', 'Az', 'Og', 'Ol', 'Lr'],
+ months: ['Urtarrila', 'Otsaila', 'Martxoa', 'Apirila', 'Maiatza', 'Ekaina', 'Uztaila', 'Abuztua', 'Iraila', 'Urria', 'Azaroa', 'Abendua'],
+ monthsShort: ['Urt', 'Ots', 'Mar', 'Api', 'Mai', 'Eka', 'Uzt', 'Abu', 'Ira', 'Urr', 'Aza', 'Abe'],
+ today: "Gaur"
+ };
+}(jQuery));
+
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.fa.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.fa.js
new file mode 100755
index 000000000..6503c85dd
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.fa.js
@@ -0,0 +1,17 @@
+/**
+ * Persian translation for bootstrap-datepicker
+ * Mostafa Rokooie
+ */
+;(function($){
+ $.fn.datepicker.dates['fa'] = {
+ days: ["یکشنبه", "دوشنبه", "سهشنبه", "چهارشنبه", "پنجشنبه", "جمعه", "شنبه", "یکشنبه"],
+ daysShort: ["یک", "دو", "سه", "چهار", "پنج", "جمعه", "شنبه", "یک"],
+ daysMin: ["ی", "د", "س", "چ", "پ", "ج", "ش", "ی"],
+ months: ["ژانویه", "فوریه", "مارس", "آوریل", "مه", "ژوئن", "ژوئیه", "اوت", "سپتامبر", "اکتبر", "نوامبر", "دسامبر"],
+ monthsShort: ["ژان", "فور", "مار", "آور", "مه", "ژون", "ژوی", "اوت", "سپت", "اکت", "نوا", "دسا"],
+ today: "امروز",
+ clear: "پاک کن",
+ weekStart: 1,
+ format: "yyyy/mm/dd"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.fi.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.fi.js
new file mode 100755
index 000000000..220f6b2bf
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.fi.js
@@ -0,0 +1,17 @@
+/**
+ * Finnish translation for bootstrap-datepicker
+ * Jaakko Salonen
+ */
+;(function($){
+ $.fn.datepicker.dates['fi'] = {
+ days: ["sunnuntai", "maanantai", "tiistai", "keskiviikko", "torstai", "perjantai", "lauantai"],
+ daysShort: ["sun", "maa", "tii", "kes", "tor", "per", "lau"],
+ daysMin: ["su", "ma", "ti", "ke", "to", "pe", "la"],
+ months: ["tammikuu", "helmikuu", "maaliskuu", "huhtikuu", "toukokuu", "kesäkuu", "heinäkuu", "elokuu", "syyskuu", "lokakuu", "marraskuu", "joulukuu"],
+ monthsShort: ["tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mar", "jou"],
+ today: "tänään",
+ clear: "Tyhjennä",
+ weekStart: 1,
+ format: "d.m.yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.fo.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.fo.js
new file mode 100755
index 000000000..eaada077b
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.fo.js
@@ -0,0 +1,15 @@
+/**
+ * Faroese translation for bootstrap-datepicker
+ * Theodor Johannesen
+ */
+;(function($){
+ $.fn.datepicker.dates['fo'] = {
+ days: ["Sunnudagur", "Mánadagur", "Týsdagur", "Mikudagur", "Hósdagur", "Fríggjadagur", "Leygardagur"],
+ daysShort: ["Sun", "Mán", "Týs", "Mik", "Hós", "Frí", "Ley"],
+ daysMin: ["Su", "Má", "Tý", "Mi", "Hó", "Fr", "Le"],
+ months: ["Januar", "Februar", "Marts", "Apríl", "Mei", "Juni", "Juli", "August", "Septembur", "Oktobur", "Novembur", "Desembur"],
+ monthsShort: ["Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Des"],
+ today: "Í Dag",
+ clear: "Reinsa"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.fr-CH.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.fr-CH.js
new file mode 100755
index 000000000..c1fb27bf3
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.fr-CH.js
@@ -0,0 +1,20 @@
+/**
+ * French (Switzerland) translation for bootstrap-datepicker
+ * Christoph Jossi
+ * Based on
+ * French translation for bootstrap-datepicker
+ * Nico Mollet
+ */
+;(function($){
+ $.fn.datepicker.dates['fr'] = {
+ days: ["Dimanche", "Lundi", "Mardi", "Mercredi", "Jeudi", "Vendredi", "Samedi"],
+ daysShort: ["Dim", "Lun", "Mar", "Mer", "Jeu", "Ven", "Sam"],
+ daysMin: ["D", "L", "Ma", "Me", "J", "V", "S"],
+ months: ["Janvier", "Février", "Mars", "Avril", "Mai", "Juin", "Juillet", "Août", "Septembre", "Octobre", "Novembre", "Décembre"],
+ monthsShort: ["Jan", "Fév", "Mar", "Avr", "Mai", "Jui", "Jul", "Aou", "Sep", "Oct", "Nov", "Déc"],
+ today: "Aujourd'hui",
+ clear: "Effacer",
+ weekStart: 1,
+ format: "dd.mm.yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.fr.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.fr.js
new file mode 100755
index 000000000..ef430a05a
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.fr.js
@@ -0,0 +1,17 @@
+/**
+ * French translation for bootstrap-datepicker
+ * Nico Mollet
+ */
+;(function($){
+ $.fn.datepicker.dates['fr'] = {
+ days: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"],
+ daysShort: ["dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam."],
+ daysMin: ["d", "l", "ma", "me", "j", "v", "s"],
+ months: ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"],
+ monthsShort: ["janv.", "févr.", "mars", "avril", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc."],
+ today: "Aujourd'hui",
+ clear: "Effacer",
+ weekStart: 1,
+ format: "dd/mm/yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.gl.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.gl.js
new file mode 100755
index 000000000..592ce0045
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.gl.js
@@ -0,0 +1,13 @@
+;(function($){
+ $.fn.datepicker.dates['gl'] = {
+ days: ["Domingo", "Luns", "Martes", "Mércores", "Xoves", "Venres", "Sábado"],
+ daysShort: ["Dom", "Lun", "Mar", "Mér", "Xov", "Ven", "Sáb"],
+ daysMin: ["Do", "Lu", "Ma", "Me", "Xo", "Ve", "Sa"],
+ months: ["Xaneiro", "Febreiro", "Marzo", "Abril", "Maio", "Xuño", "Xullo", "Agosto", "Setembro", "Outubro", "Novembro", "Decembro"],
+ monthsShort: ["Xan", "Feb", "Mar", "Abr", "Mai", "Xun", "Xul", "Ago", "Sep", "Out", "Nov", "Dec"],
+ today: "Hoxe",
+ clear: "Limpar",
+ weekStart: 1,
+ format: "dd/mm/yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.he.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.he.js
new file mode 100755
index 000000000..2e17393b1
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.he.js
@@ -0,0 +1,15 @@
+/**
+ * Hebrew translation for bootstrap-datepicker
+ * Sagie Maoz
+ */
+;(function($){
+ $.fn.datepicker.dates['he'] = {
+ days: ["ראשון", "שני", "שלישי", "רביעי", "חמישי", "שישי", "שבת", "ראשון"],
+ daysShort: ["א", "ב", "ג", "ד", "ה", "ו", "ש", "א"],
+ daysMin: ["א", "ב", "ג", "ד", "ה", "ו", "ש", "א"],
+ months: ["ינואר", "פברואר", "מרץ", "אפריל", "מאי", "יוני", "יולי", "אוגוסט", "ספטמבר", "אוקטובר", "נובמבר", "דצמבר"],
+ monthsShort: ["ינו", "פבר", "מרץ", "אפר", "מאי", "יונ", "יול", "אוג", "ספט", "אוק", "נוב", "דצמ"],
+ today: "היום",
+ rtl: true
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.hr.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.hr.js
new file mode 100755
index 000000000..ec72952af
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.hr.js
@@ -0,0 +1,13 @@
+/**
+ * Croatian localisation
+ */
+;(function($){
+ $.fn.datepicker.dates['hr'] = {
+ days: ["Nedjelja", "Ponedjeljak", "Utorak", "Srijeda", "Četvrtak", "Petak", "Subota"],
+ daysShort: ["Ned", "Pon", "Uto", "Sri", "Čet", "Pet", "Sub"],
+ daysMin: ["Ne", "Po", "Ut", "Sr", "Če", "Pe", "Su"],
+ months: ["Siječanj", "Veljača", "Ožujak", "Travanj", "Svibanj", "Lipanj", "Srpanj", "Kolovoz", "Rujan", "Listopad", "Studeni", "Prosinac"],
+ monthsShort: ["Sij", "Velj", "Ožu", "Tra", "Svi", "Lip", "Srp", "Kol", "Ruj", "Lis", "Stu", "Pro"],
+ today: "Danas"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.hu.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.hu.js
new file mode 100755
index 000000000..03a36ee8a
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.hu.js
@@ -0,0 +1,18 @@
+/**
+ * Hungarian translation for bootstrap-datepicker
+ * Sotus László
+ */
+;(function($){
+ $.fn.datepicker.dates['hu'] = {
+ days: ["vasárnap", "hétfő", "kedd", "szerda", "csütörtök", "péntek", "szombat"],
+ daysShort: ["vas", "hét", "ked", "sze", "csü", "pén", "szo"],
+ daysMin: ["V", "H", "K", "Sze", "Cs", "P", "Szo"],
+ months: ["január", "február", "március", "április", "május", "június", "július", "augusztus", "szeptember", "október", "november", "december"],
+ monthsShort: ["jan", "feb", "már", "ápr", "máj", "jún", "júl", "aug", "sze", "okt", "nov", "dec"],
+ today: "ma",
+ weekStart: 1,
+ clear: "töröl",
+ titleFormat: "yyyy. MM",
+ format: "yyyy.mm.dd"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.hy.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.hy.js
new file mode 100755
index 000000000..a923c05a9
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.hy.js
@@ -0,0 +1,17 @@
+/**
+ * Armenian translation for bootstrap-datepicker
+ * Hayk Chamyan
+ */
+;(function($){
+ $.fn.datepicker.dates['hy'] = {
+ days: ["Կիրակի", "Երկուշաբթի", "Երեքշաբթի", "Չորեքշաբթի", "Հինգշաբթի", "Ուրբաթ", "Շաբաթ"],
+ daysShort: ["Կիր", "Երկ", "Երք", "Չոր", "Հնգ", "Ուր", "Շաբ"],
+ daysMin: ["Կի", "Եկ", "Եք", "Չո", "Հի", "Ու", "Շա"],
+ months: ["Հունվար", "Փետրվար", "Մարտ", "Ապրիլ", "Մայիս", "Հունիս", "Հուլիս", "Օգոստոս", "Սեպտեմբեր", "Հոկտեմբեր", "Նոյեմբեր", "Դեկտեմբեր"],
+ monthsShort: ["Հնվ", "Փետ", "Մար", "Ապր", "Մայ", "Հուն", "Հուլ", "Օգս", "Սեպ", "Հոկ", "Նոյ", "Դեկ"],
+ today: "Այսօր",
+ clear: "Ջնջել",
+ format: "dd.mm.yyyy",
+ weekStart: 1
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.id.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.id.js
new file mode 100755
index 000000000..832045ac6
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.id.js
@@ -0,0 +1,15 @@
+/**
+ * Bahasa translation for bootstrap-datepicker
+ * Azwar Akbar
+ */
+;(function($){
+ $.fn.datepicker.dates['id'] = {
+ days: ["Minggu", "Senin", "Selasa", "Rabu", "Kamis", "Jumat", "Sabtu"],
+ daysShort: ["Mgu", "Sen", "Sel", "Rab", "Kam", "Jum", "Sab"],
+ daysMin: ["Mg", "Sn", "Sl", "Ra", "Ka", "Ju", "Sa"],
+ months: ["Januari", "Februari", "Maret", "April", "Mei", "Juni", "Juli", "Agustus", "September", "Oktober", "November", "Desember"],
+ monthsShort: ["Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Ags", "Sep", "Okt", "Nov", "Des"],
+ today: "Hari Ini",
+ clear: "Kosongkan"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.is.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.is.js
new file mode 100755
index 000000000..2eef5e129
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.is.js
@@ -0,0 +1,14 @@
+/**
+ * Icelandic translation for bootstrap-datepicker
+ * Hinrik Örn Sigurðsson
+ */
+;(function($){
+ $.fn.datepicker.dates['is'] = {
+ days: ["Sunnudagur", "Mánudagur", "Þriðjudagur", "Miðvikudagur", "Fimmtudagur", "Föstudagur", "Laugardagur"],
+ daysShort: ["Sun", "Mán", "Þri", "Mið", "Fim", "Fös", "Lau"],
+ daysMin: ["Su", "Má", "Þr", "Mi", "Fi", "Fö", "La"],
+ months: ["Janúar", "Febrúar", "Mars", "Apríl", "Maí", "Júní", "Júlí", "Ágúst", "September", "Október", "Nóvember", "Desember"],
+ monthsShort: ["Jan", "Feb", "Mar", "Apr", "Maí", "Jún", "Júl", "Ágú", "Sep", "Okt", "Nóv", "Des"],
+ today: "Í Dag"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.it-CH.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.it-CH.js
new file mode 100755
index 000000000..b4496aa9c
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.it-CH.js
@@ -0,0 +1,20 @@
+/**
+ * Italian (Switzerland) translation for bootstrap-datepicker
+ * Christoph Jossi
+ * Based on
+ * Italian translation for bootstrap-datepicker
+ * Enrico Rubboli
+ */
+;(function($){
+ $.fn.datepicker.dates['it'] = {
+ days: ["Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"],
+ daysShort: ["Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"],
+ daysMin: ["Do", "Lu", "Ma", "Me", "Gi", "Ve", "Sa"],
+ months: ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"],
+ monthsShort: ["Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic"],
+ today: "Oggi",
+ clear: "Cancella",
+ weekStart: 1,
+ format: "dd.mm.yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.it.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.it.js
new file mode 100755
index 000000000..e97e2cd64
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.it.js
@@ -0,0 +1,17 @@
+/**
+ * Italian translation for bootstrap-datepicker
+ * Enrico Rubboli
+ */
+;(function($){
+ $.fn.datepicker.dates['it'] = {
+ days: ["Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"],
+ daysShort: ["Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"],
+ daysMin: ["Do", "Lu", "Ma", "Me", "Gi", "Ve", "Sa"],
+ months: ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"],
+ monthsShort: ["Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic"],
+ today: "Oggi",
+ clear: "Cancella",
+ weekStart: 1,
+ format: "dd/mm/yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ja.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ja.js
new file mode 100755
index 000000000..c64a61472
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ja.js
@@ -0,0 +1,17 @@
+/**
+ * Japanese translation for bootstrap-datepicker
+ * Norio Suzuki
+ */
+;(function($){
+ $.fn.datepicker.dates['ja'] = {
+ days: ["日曜", "月曜", "火曜", "水曜", "木曜", "金曜", "土曜"],
+ daysShort: ["日", "月", "火", "水", "木", "金", "土"],
+ daysMin: ["日", "月", "火", "水", "木", "金", "土"],
+ months: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
+ monthsShort: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
+ today: "今日",
+ format: "yyyy/mm/dd",
+ titleFormat: "yyyy年mm月",
+ clear: "クリア"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ka.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ka.js
new file mode 100755
index 000000000..003f53780
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ka.js
@@ -0,0 +1,17 @@
+/**
+ * Georgian translation for bootstrap-datepicker
+ * Levan Melikishvili
+ */
+;(function($){
+ $.fn.datepicker.dates['ka'] = {
+ days: ["კვირა", "ორშაბათი", "სამშაბათი", "ოთხშაბათი", "ხუთშაბათი", "პარასკევი", "შაბათი"],
+ daysShort: ["კვი", "ორშ", "სამ", "ოთხ", "ხუთ", "პარ", "შაბ"],
+ daysMin: ["კვ", "ორ", "სა", "ოთ", "ხუ", "პა", "შა"],
+ months: ["იანვარი", "თებერვალი", "მარტი", "აპრილი", "მაისი", "ივნისი", "ივლისი", "აგვისტო", "სექტემბერი", "ოქტომები", "ნოემბერი", "დეკემბერი"],
+ monthsShort: ["იან", "თებ", "მარ", "აპრ", "მაი", "ივნ", "ივლ", "აგვ", "სექ", "ოქტ", "ნოე", "დეკ"],
+ today: "დღეს",
+ clear: "გასუფთავება",
+ weekStart: 1,
+ format: "dd.mm.yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.kh.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.kh.js
new file mode 100755
index 000000000..681ae8786
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.kh.js
@@ -0,0 +1,15 @@
+/**
+ * Cambodia (Khmer) translation for bootstrap-datepicker
+ * Lytay TOUCH
+ */
+;(function($){
+ $.fn.datepicker.dates['kh'] = {
+ days: ["អាទិត្យ", "ចន្ទ", "អង្គារ", "ពុធ", "ព្រហស្បតិ៍", "សុក្រ", "សៅរ៍", "អាទិត្យ"],
+ daysShort: ["អា.ទិ", "ចន្ទ", "អង្គារ", "ពុធ", "ព្រ.ហ", "សុក្រ", "សៅរ៍", "អា.ទិ"],
+ daysMin: ["អា.ទិ", "ចន្ទ", "អង្គារ", "ពុធ", "ព្រ.ហ", "សុក្រ", "សៅរ៍", "អា.ទិ"],
+ months: ["មករា", "កុម្ភះ", "មិនា", "មេសា", "ឧសភា", "មិថុនា", "កក្កដា", "សីហា", "កញ្ញា", "តុលា", "វិច្ឆិកា", "ធ្នូ"],
+ monthsShort: ["មករា", "កុម្ភះ", "មិនា", "មេសា", "ឧសភា", "មិថុនា", "កក្កដា", "សីហា", "កញ្ញា", "តុលា", "វិច្ឆិកា", "ធ្នូ"],
+ today: "ថ្ងៃនេះ",
+ clear: "សំអាត"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.kk.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.kk.js
new file mode 100755
index 000000000..e301ecf25
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.kk.js
@@ -0,0 +1,15 @@
+/**
+ * Kazakh translation for bootstrap-datepicker
+ * Yerzhan Tolekov
+ */
+;(function($){
+ $.fn.datepicker.dates['kk'] = {
+ days: ["Жексенбі", "Дүйсенбі", "Сейсенбі", "Сәрсенбі", "Бейсенбі", "Жұма", "Сенбі"],
+ daysShort: ["Жек", "Дүй", "Сей", "Сәр", "Бей", "Жұм", "Сен"],
+ daysMin: ["Жк", "Дс", "Сс", "Ср", "Бс", "Жм", "Сн"],
+ months: ["Қаңтар", "Ақпан", "Наурыз", "Сәуір", "Мамыр", "Маусым", "Шілде", "Тамыз", "Қыркүйек", "Қазан", "Қараша", "Желтоқсан"],
+ monthsShort: ["Қаң", "Ақп", "Нау", "Сәу", "Мамыр", "Мау", "Шлд", "Тмз", "Қыр", "Қзн", "Қар", "Жел"],
+ today: "Бүгін",
+ weekStart: 1
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ko.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ko.js
new file mode 100755
index 000000000..24116925f
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ko.js
@@ -0,0 +1,18 @@
+/**
+ * Korean translation for bootstrap-datepicker
+ * This is a port from https://github.com/moment/moment/blob/develop/src/locale/ko.js
+ */
+;(function($){
+ $.fn.datepicker.dates['ko'] = {
+ days: ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"],
+ daysShort: ["일", "월", "화", "수", "목", "금", "토"],
+ daysMin: ["일", "월", "화", "수", "목", "금", "토"],
+ months: ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"],
+ monthsShort: ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"],
+ today: "오늘",
+ clear: "투명",
+ format: "YYYY-MM-DD",
+ titleFormat: "yyyy년mm월",
+ weekStart: 0
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.kr.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.kr.js
new file mode 100755
index 000000000..3ccea6460
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.kr.js
@@ -0,0 +1,17 @@
+/**
+ * Korean translation for bootstrap-datepicker
+ * Gu Youn
+ *
+ * DEPRECATED: This language code 'kr' is deprecated and will be removed in 2.0.
+ * Korean support is now in a 'ko' translation file to follow the ISO language
+ * code - http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
+ */
+;(function($){
+ $.fn.datepicker.dates['kr'] = {
+ days: ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"],
+ daysShort: ["일", "월", "화", "수", "목", "금", "토"],
+ daysMin: ["일", "월", "화", "수", "목", "금", "토"],
+ months: ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"],
+ monthsShort: ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"]
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.lt.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.lt.js
new file mode 100755
index 000000000..41e378f16
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.lt.js
@@ -0,0 +1,16 @@
+/**
+ * Lithuanian translation for bootstrap-datepicker
+ * Šarūnas Gliebus
+ */
+
+;(function($){
+ $.fn.datepicker.dates['lt'] = {
+ days: ["Sekmadienis", "Pirmadienis", "Antradienis", "Trečiadienis", "Ketvirtadienis", "Penktadienis", "Šeštadienis"],
+ daysShort: ["S", "Pr", "A", "T", "K", "Pn", "Š"],
+ daysMin: ["Sk", "Pr", "An", "Tr", "Ke", "Pn", "Št"],
+ months: ["Sausis", "Vasaris", "Kovas", "Balandis", "Gegužė", "Birželis", "Liepa", "Rugpjūtis", "Rugsėjis", "Spalis", "Lapkritis", "Gruodis"],
+ monthsShort: ["Sau", "Vas", "Kov", "Bal", "Geg", "Bir", "Lie", "Rugp", "Rugs", "Spa", "Lap", "Gru"],
+ today: "Šiandien",
+ weekStart: 1
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.lv.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.lv.js
new file mode 100755
index 000000000..8433f7f4a
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.lv.js
@@ -0,0 +1,16 @@
+/**
+ * Latvian translation for bootstrap-datepicker
+ * Artis Avotins
+ */
+
+;(function($){
+ $.fn.datepicker.dates['lv'] = {
+ days: ["Svētdiena", "Pirmdiena", "Otrdiena", "Trešdiena", "Ceturtdiena", "Piektdiena", "Sestdiena"],
+ daysShort: ["Sv", "P", "O", "T", "C", "Pk", "S"],
+ daysMin: ["Sv", "Pr", "Ot", "Tr", "Ce", "Pk", "Se"],
+ months: ["Janvāris", "Februāris", "Marts", "Aprīlis", "Maijs", "Jūnijs", "Jūlijs", "Augusts", "Septembris", "Oktobris", "Novembris", "Decembris"],
+ monthsShort: ["Jan", "Feb", "Mar", "Apr", "Mai", "Jūn", "Jūl", "Aug", "Sep", "Okt", "Nov", "Dec"],
+ today: "Šodien",
+ weekStart: 1
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.me.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.me.js
new file mode 100755
index 000000000..e581325d3
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.me.js
@@ -0,0 +1,17 @@
+/**
+ * Montenegrin translation for bootstrap-datepicker
+ * Miodrag Nikač
+ */
+;(function($){
+ $.fn.datepicker.dates['me'] = {
+ days: ["Nedjelja","Ponedjeljak", "Utorak", "Srijeda", "Četvrtak", "Petak", "Subota"],
+ daysShort: ["Ned", "Pon", "Uto", "Sri", "Čet", "Pet", "Sub"],
+ daysMin: ["Ne", "Po", "Ut", "Sr", "Če", "Pe", "Su"],
+ months: ["Januar", "Februar", "Mart", "April", "Maj", "Jun", "Jul", "Avgust", "Septembar", "Oktobar", "Novembar", "Decembar"],
+ monthsShort: ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Avg", "Sep", "Okt", "Nov", "Dec"],
+ today: "Danas",
+ weekStart: 1,
+ clear: "Izbriši",
+ format: "dd.mm.yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.mk.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.mk.js
new file mode 100755
index 000000000..2f041baad
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.mk.js
@@ -0,0 +1,15 @@
+/**
+ * Macedonian translation for bootstrap-datepicker
+ * Marko Aleksic
+ */
+;(function($){
+ $.fn.datepicker.dates['mk'] = {
+ days: ["Недела", "Понеделник", "Вторник", "Среда", "Четврток", "Петок", "Сабота"],
+ daysShort: ["Нед", "Пон", "Вто", "Сре", "Чет", "Пет", "Саб"],
+ daysMin: ["Не", "По", "Вт", "Ср", "Че", "Пе", "Са"],
+ months: ["Јануари", "Февруари", "Март", "Април", "Мај", "Јуни", "Јули", "Август", "Септември", "Октомври", "Ноември", "Декември"],
+ monthsShort: ["Јан", "Фев", "Мар", "Апр", "Мај", "Јун", "Јул", "Авг", "Сеп", "Окт", "Ное", "Дек"],
+ today: "Денес",
+ format: "dd.mm.yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.mn.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.mn.js
new file mode 100755
index 000000000..b3a66e8b2
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.mn.js
@@ -0,0 +1,17 @@
+/**
+ * Mongolian translation for bootstrap-datepicker
+ * Andrey Torsunov
+ */
+;(function($){
+ $.fn.datepicker.dates['mn'] = {
+ days: ["Ням", "Даваа", "Мягмар", "Лхагва", "Пүрэв", "Баасан", "Бямба"],
+ daysShort: ["Ням", "Дав", "Мяг", "Лха", "Пүр", "Баа", "Бям"],
+ daysMin: ["Ня", "Да", "Мя", "Лх", "Пү", "Ба", "Бя"],
+ months: ["Хулгана", "Үхэр", "Бар", "Туулай", "Луу", "Могой", "Морь", "Хонь", "Бич", "Тахиа", "Нохой", "Гахай"],
+ monthsShort: ["Хул", "Үхэ", "Бар", "Туу", "Луу", "Мог", "Мор", "Хон", "Бич", "Тах", "Нох", "Гах"],
+ today: "Өнөөдөр",
+ clear: "Тодорхой",
+ format: "yyyy.mm.dd",
+ weekStart: 1
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ms.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ms.js
new file mode 100755
index 000000000..8bb4194ae
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ms.js
@@ -0,0 +1,15 @@
+/**
+ * Malay translation for bootstrap-datepicker
+ * Ateman Faiz
+ */
+;(function($){
+ $.fn.datepicker.dates['ms'] = {
+ days: ["Ahad", "Isnin", "Selasa", "Rabu", "Khamis", "Jumaat", "Sabtu"],
+ daysShort: ["Aha", "Isn", "Sel", "Rab", "Kha", "Jum", "Sab"],
+ daysMin: ["Ah", "Is", "Se", "Ra", "Kh", "Ju", "Sa"],
+ months: ["Januari", "Februari", "Mac", "April", "Mei", "Jun", "Julai", "Ogos", "September", "Oktober", "November", "Disember"],
+ monthsShort: ["Jan", "Feb", "Mar", "Apr", "Mei", "Jun", "Jul", "Ogo", "Sep", "Okt", "Nov", "Dis"],
+ today: "Hari Ini",
+ clear: "Bersihkan"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.nb.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.nb.js
new file mode 100755
index 000000000..9d138c123
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.nb.js
@@ -0,0 +1,14 @@
+/**
+ * Norwegian (bokmål) translation for bootstrap-datepicker
+ * Fredrik Sundmyhr
+ */
+;(function($){
+ $.fn.datepicker.dates['nb'] = {
+ days: ["Søndag", "Mandag", "Tirsdag", "Onsdag", "Torsdag", "Fredag", "Lørdag"],
+ daysShort: ["Søn", "Man", "Tir", "Ons", "Tor", "Fre", "Lør"],
+ daysMin: ["Sø", "Ma", "Ti", "On", "To", "Fr", "Lø"],
+ months: ["Januar", "Februar", "Mars", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Desember"],
+ monthsShort: ["Jan", "Feb", "Mar", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Des"],
+ today: "I Dag"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.nl-BE.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.nl-BE.js
new file mode 100755
index 000000000..5bd5c70f5
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.nl-BE.js
@@ -0,0 +1,17 @@
+/**
+ * Belgium-Dutch translation for bootstrap-datepicker
+ * Julien Poulin
+ */
+;(function($){
+ $.fn.datepicker.dates['nl-BE'] = {
+ days: ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"],
+ daysShort: ["zo", "ma", "di", "wo", "do", "vr", "za"],
+ daysMin: ["zo", "ma", "di", "wo", "do", "vr", "za"],
+ months: ["januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"],
+ monthsShort: ["jan", "feb", "mrt", "apr", "mei", "jun", "jul", "aug", "sep", "okt", "nov", "dec"],
+ today: "Vandaag",
+ clear: "Leegmaken",
+ weekStart: 1,
+ format: "dd/mm/yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.nl.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.nl.js
new file mode 100755
index 000000000..79267159d
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.nl.js
@@ -0,0 +1,17 @@
+/**
+ * Dutch translation for bootstrap-datepicker
+ * Reinier Goltstein
+ */
+;(function($){
+ $.fn.datepicker.dates['nl'] = {
+ days: ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"],
+ daysShort: ["zo", "ma", "di", "wo", "do", "vr", "za"],
+ daysMin: ["zo", "ma", "di", "wo", "do", "vr", "za"],
+ months: ["januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"],
+ monthsShort: ["jan", "feb", "mrt", "apr", "mei", "jun", "jul", "aug", "sep", "okt", "nov", "dec"],
+ today: "Vandaag",
+ clear: "Wissen",
+ weekStart: 1,
+ format: "dd-mm-yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.no.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.no.js
new file mode 100755
index 000000000..75890bdab
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.no.js
@@ -0,0 +1,16 @@
+/**
+ * Norwegian translation for bootstrap-datepicker
+ **/
+;(function($){
+ $.fn.datepicker.dates['no'] = {
+ days: ['Søndag', 'Mandag', 'Tirsdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lørdag'],
+ daysShort: ['Søn', 'Man', 'Tir', 'Ons', 'Tor', 'Fre', 'Lør'],
+ daysMin: ['Sø', 'Ma', 'Ti', 'On', 'To', 'Fr', 'Lø'],
+ months: ['Januar', 'Februar', 'Mars', 'April', 'Mai', 'Juni', 'Juli', 'August', 'September', 'Oktober', 'November', 'Desember'],
+ monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Des'],
+ today: 'I dag',
+ clear: 'Nullstill',
+ weekStart: 1,
+ format: 'dd.mm.yyyy'
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.pl.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.pl.js
new file mode 100755
index 000000000..74e02ff05
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.pl.js
@@ -0,0 +1,17 @@
+/**
+ * Polish translation for bootstrap-datepicker
+ * Robert
+ */
+;(function($){
+ $.fn.datepicker.dates['pl'] = {
+ days: ["niedziela", "poniedziałek", "wtorek", "środa", "czwartek", "piątek", "sobota"],
+ daysShort: ["niedz.", "pon.", "wt.", "śr.", "czw.", "piąt.", "sob."],
+ daysMin: ["ndz.", "pn.", "wt.", "śr.", "czw.", "pt.", "sob."],
+ months: ["styczeń", "luty", "marzec", "kwiecień", "maj", "czerwiec", "lipiec", "sierpień", "wrzesień", "październik", "listopad", "grudzień"],
+ monthsShort: ["sty.", "lut.", "mar.", "kwi.", "maj", "cze.", "lip.", "sie.", "wrz.", "paź.", "lis.", "gru."],
+ today: "dzisiaj",
+ weekStart: 1,
+ clear: "wyczyść",
+ format: "dd.mm.yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.pt-BR.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.pt-BR.js
new file mode 100755
index 000000000..44106ffef
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.pt-BR.js
@@ -0,0 +1,16 @@
+/**
+ * Brazilian translation for bootstrap-datepicker
+ * Cauan Cabral
+ */
+;(function($){
+ $.fn.datepicker.dates['pt-BR'] = {
+ days: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"],
+ daysShort: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"],
+ daysMin: ["Do", "Se", "Te", "Qu", "Qu", "Se", "Sa"],
+ months: ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"],
+ monthsShort: ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"],
+ today: "Hoje",
+ clear: "Limpar",
+ format: "dd/mm/yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.pt.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.pt.js
new file mode 100755
index 000000000..67dff3edd
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.pt.js
@@ -0,0 +1,17 @@
+/**
+ * Portuguese translation for bootstrap-datepicker
+ * Original code: Cauan Cabral
+ * Tiago Melo
+ */
+;(function($){
+ $.fn.datepicker.dates['pt'] = {
+ days: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"],
+ daysShort: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"],
+ daysMin: ["Do", "Se", "Te", "Qu", "Qu", "Se", "Sa"],
+ months: ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"],
+ monthsShort: ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"],
+ today: "Hoje",
+ clear: "Limpar",
+ format: "dd/mm/yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ro.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ro.js
new file mode 100755
index 000000000..bef2b9ba3
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ro.js
@@ -0,0 +1,16 @@
+/**
+ * Romanian translation for bootstrap-datepicker
+ * Cristian Vasile
+ */
+;(function($){
+ $.fn.datepicker.dates['ro'] = {
+ days: ["Duminică", "Luni", "Marţi", "Miercuri", "Joi", "Vineri", "Sâmbătă"],
+ daysShort: ["Dum", "Lun", "Mar", "Mie", "Joi", "Vin", "Sâm"],
+ daysMin: ["Du", "Lu", "Ma", "Mi", "Jo", "Vi", "Sâ"],
+ months: ["Ianuarie", "Februarie", "Martie", "Aprilie", "Mai", "Iunie", "Iulie", "August", "Septembrie", "Octombrie", "Noiembrie", "Decembrie"],
+ monthsShort: ["Ian", "Feb", "Mar", "Apr", "Mai", "Iun", "Iul", "Aug", "Sep", "Oct", "Nov", "Dec"],
+ today: "Astăzi",
+ clear: "Șterge",
+ weekStart: 1
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.rs-latin.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.rs-latin.js
new file mode 100755
index 000000000..d13766adb
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.rs-latin.js
@@ -0,0 +1,16 @@
+/**
+ * Serbian latin translation for bootstrap-datepicker
+ * Bojan Milosavlević
+ */
+;(function($){
+ $.fn.datepicker.dates['rs-latin'] = {
+ days: ["Nedelja","Ponedeljak", "Utorak", "Sreda", "Četvrtak", "Petak", "Subota"],
+ daysShort: ["Ned", "Pon", "Uto", "Sre", "Čet", "Pet", "Sub"],
+ daysMin: ["N", "Po", "U", "Sr", "Č", "Pe", "Su"],
+ months: ["Januar", "Februar", "Mart", "April", "Maj", "Jun", "Jul", "Avgust", "Septembar", "Oktobar", "Novembar", "Decembar"],
+ monthsShort: ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Avg", "Sep", "Okt", "Nov", "Dec"],
+ today: "Danas",
+ weekStart: 1,
+ format: "dd.mm.yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.rs.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.rs.js
new file mode 100755
index 000000000..ec22e5a81
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.rs.js
@@ -0,0 +1,16 @@
+/**
+ * Serbian cyrillic translation for bootstrap-datepicker
+ * Bojan Milosavlević
+ */
+;(function($){
+ $.fn.datepicker.dates['rs'] = {
+ days: ["Недеља","Понедељак", "Уторак", "Среда", "Четвртак", "Петак", "Субота"],
+ daysShort: ["Нед", "Пон", "Уто", "Сре", "Чет", "Пет", "Суб"],
+ daysMin: ["Н", "По", "У", "Ср", "Ч", "Пе", "Су"],
+ months: ["Јануар", "Фебруар", "Март", "Април", "Мај", "Јун", "Јул", "Август", "Септембар", "Октобар", "Новембар", "Децембар"],
+ monthsShort: ["Јан", "Феб", "Мар", "Апр", "Мај", "Јун", "Јул", "Авг", "Сеп", "Окт", "Нов", "Дец"],
+ today: "Данас",
+ weekStart: 1,
+ format: "dd.mm.yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ru.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ru.js
new file mode 100755
index 000000000..f13947c12
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.ru.js
@@ -0,0 +1,17 @@
+/**
+ * Russian translation for bootstrap-datepicker
+ * Victor Taranenko
+ */
+;(function($){
+ $.fn.datepicker.dates['ru'] = {
+ days: ["Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота"],
+ daysShort: ["Вск", "Пнд", "Втр", "Срд", "Чтв", "Птн", "Суб"],
+ daysMin: ["Вс", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"],
+ months: ["Январь", "Февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь", "Декабрь"],
+ monthsShort: ["Янв", "Фев", "Мар", "Апр", "Май", "Июн", "Июл", "Авг", "Сен", "Окт", "Ноя", "Дек"],
+ today: "Сегодня",
+ clear: "Очистить",
+ format: "dd.mm.yyyy",
+ weekStart: 1
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.sk.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.sk.js
new file mode 100755
index 000000000..f8e2d2352
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.sk.js
@@ -0,0 +1,16 @@
+/**
+ * Slovak translation for bootstrap-datepicker
+ * Marek Lichtner
+ * Fixes by Michal Remiš
+ */
+;(function($){
+ $.fn.datepicker.dates["sk"] = {
+ days: ["Nedeľa", "Pondelok", "Utorok", "Streda", "Štvrtok", "Piatok", "Sobota"],
+ daysShort: ["Ned", "Pon", "Uto", "Str", "Štv", "Pia", "Sob"],
+ daysMin: ["Ne", "Po", "Ut", "St", "Št", "Pia", "So"],
+ months: ["Január", "Február", "Marec", "Apríl", "Máj", "Jún", "Júl", "August", "September", "Október", "November", "December"],
+ monthsShort: ["Jan", "Feb", "Mar", "Apr", "Máj", "Jún", "Júl", "Aug", "Sep", "Okt", "Nov", "Dec"],
+ today: "Dnes",
+ format: "dd.mm.yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.sl.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.sl.js
new file mode 100755
index 000000000..1b308583d
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.sl.js
@@ -0,0 +1,14 @@
+/**
+ * Slovene translation for bootstrap-datepicker
+ * Gregor Rudolf
+ */
+;(function($){
+ $.fn.datepicker.dates['sl'] = {
+ days: ["Nedelja", "Ponedeljek", "Torek", "Sreda", "Četrtek", "Petek", "Sobota"],
+ daysShort: ["Ned", "Pon", "Tor", "Sre", "Čet", "Pet", "Sob"],
+ daysMin: ["Ne", "Po", "To", "Sr", "Če", "Pe", "So"],
+ months: ["Januar", "Februar", "Marec", "April", "Maj", "Junij", "Julij", "Avgust", "September", "Oktober", "November", "December"],
+ monthsShort: ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Avg", "Sep", "Okt", "Nov", "Dec"],
+ today: "Danes"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.sq.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.sq.js
new file mode 100755
index 000000000..11f94693e
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.sq.js
@@ -0,0 +1,15 @@
+/**
+ * Albanian translation for bootstrap-datepicker
+ * Tomor Pupovci
+ */
+;(function($){
+ $.fn.datepicker.dates['sq'] = {
+ days: ["E Diel", "E Hënë", "E Martē", "E Mërkurë", "E Enjte", "E Premte", "E Shtunë"],
+ daysShort: ["Die", "Hën", "Mar", "Mër", "Enj", "Pre", "Shtu"],
+ daysMin: ["Di", "Hë", "Ma", "Më", "En", "Pr", "Sht"],
+ months: ["Janar", "Shkurt", "Mars", "Prill", "Maj", "Qershor", "Korrik", "Gusht", "Shtator", "Tetor", "Nëntor", "Dhjetor"],
+ monthsShort: ["Jan", "Shk", "Mar", "Pri", "Maj", "Qer", "Korr", "Gu", "Sht", "Tet", "Nën", "Dhjet"],
+ today: "Sot"
+ };
+}(jQuery));
+
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.sr-latin.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.sr-latin.js
new file mode 100755
index 000000000..058796336
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.sr-latin.js
@@ -0,0 +1,16 @@
+/**
+ * Serbian latin translation for bootstrap-datepicker
+ * Bojan Milosavlević
+ */
+;(function($){
+ $.fn.datepicker.dates['sr-latin'] = {
+ days: ["Nedelja","Ponedeljak", "Utorak", "Sreda", "Četvrtak", "Petak", "Subota"],
+ daysShort: ["Ned", "Pon", "Uto", "Sre", "Čet", "Pet", "Sub"],
+ daysMin: ["N", "Po", "U", "Sr", "Č", "Pe", "Su"],
+ months: ["Januar", "Februar", "Mart", "April", "Maj", "Jun", "Jul", "Avgust", "Septembar", "Oktobar", "Novembar", "Decembar"],
+ monthsShort: ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Avg", "Sep", "Okt", "Nov", "Dec"],
+ today: "Danas",
+ weekStart: 1,
+ format: "dd.mm.yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.sr.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.sr.js
new file mode 100755
index 000000000..a0dcb83f3
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.sr.js
@@ -0,0 +1,16 @@
+/**
+ * Serbian cyrillic translation for bootstrap-datepicker
+ * Bojan Milosavlević
+ */
+;(function($){
+ $.fn.datepicker.dates['sr'] = {
+ days: ["Недеља","Понедељак", "Уторак", "Среда", "Четвртак", "Петак", "Субота"],
+ daysShort: ["Нед", "Пон", "Уто", "Сре", "Чет", "Пет", "Суб"],
+ daysMin: ["Н", "По", "У", "Ср", "Ч", "Пе", "Су"],
+ months: ["Јануар", "Фебруар", "Март", "Април", "Мај", "Јун", "Јул", "Август", "Септембар", "Октобар", "Новембар", "Децембар"],
+ monthsShort: ["Јан", "Феб", "Мар", "Апр", "Мај", "Јун", "Јул", "Авг", "Сеп", "Окт", "Нов", "Дец"],
+ today: "Данас",
+ weekStart: 1,
+ format: "dd.mm.yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.sv.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.sv.js
new file mode 100755
index 000000000..947a2c2d3
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.sv.js
@@ -0,0 +1,17 @@
+/**
+ * Swedish translation for bootstrap-datepicker
+ * Patrik Ragnarsson
+ */
+;(function($){
+ $.fn.datepicker.dates['sv'] = {
+ days: ["Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag"],
+ daysShort: ["Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"],
+ daysMin: ["Sö", "Må", "Ti", "On", "To", "Fr", "Lö"],
+ months: ["Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"],
+ monthsShort: ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"],
+ today: "Idag",
+ format: "yyyy-mm-dd",
+ weekStart: 1,
+ clear: "Rensa"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.sw.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.sw.js
new file mode 100755
index 000000000..0e447b83f
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.sw.js
@@ -0,0 +1,15 @@
+/**
+ * Swahili translation for bootstrap-datepicker
+ * Edwin Mugendi
+ * Source: http://scriptsource.org/cms/scripts/page.php?item_id=entry_detail&uid=xnfaqyzcku
+ */
+;(function($){
+ $.fn.datepicker.dates['sw'] = {
+ days: ["Jumapili", "Jumatatu", "Jumanne", "Jumatano", "Alhamisi", "Ijumaa", "Jumamosi"],
+ daysShort: ["J2", "J3", "J4", "J5", "Alh", "Ij", "J1"],
+ daysMin: ["2", "3", "4", "5", "A", "I", "1"],
+ months: ["Januari", "Februari", "Machi", "Aprili", "Mei", "Juni", "Julai", "Agosti", "Septemba", "Oktoba", "Novemba", "Desemba"],
+ monthsShort: ["Jan", "Feb", "Mac", "Apr", "Mei", "Jun", "Jul", "Ago", "Sep", "Okt", "Nov", "Des"],
+ today: "Leo"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.th.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.th.js
new file mode 100755
index 000000000..562b063c5
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.th.js
@@ -0,0 +1,14 @@
+/**
+ * Thai translation for bootstrap-datepicker
+ * Suchau Jiraprapot
+ */
+;(function($){
+ $.fn.datepicker.dates['th'] = {
+ days: ["อาทิตย์", "จันทร์", "อังคาร", "พุธ", "พฤหัส", "ศุกร์", "เสาร์", "อาทิตย์"],
+ daysShort: ["อา", "จ", "อ", "พ", "พฤ", "ศ", "ส", "อา"],
+ daysMin: ["อา", "จ", "อ", "พ", "พฤ", "ศ", "ส", "อา"],
+ months: ["มกราคม", "กุมภาพันธ์", "มีนาคม", "เมษายน", "พฤษภาคม", "มิถุนายน", "กรกฎาคม", "สิงหาคม", "กันยายน", "ตุลาคม", "พฤศจิกายน", "ธันวาคม"],
+ monthsShort: ["ม.ค.", "ก.พ.", "มี.ค.", "เม.ย.", "พ.ค.", "มิ.ย.", "ก.ค.", "ส.ค.", "ก.ย.", "ต.ค.", "พ.ย.", "ธ.ค."],
+ today: "วันนี้"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.tr.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.tr.js
new file mode 100755
index 000000000..0c8b0de4d
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.tr.js
@@ -0,0 +1,18 @@
+/**
+ * Turkish translation for bootstrap-datepicker
+ * Serkan Algur
+ */
+;(function($){
+ $.fn.datepicker.dates['tr'] = {
+ days: ["Pazar", "Pazartesi", "Salı", "Çarşamba", "Perşembe", "Cuma", "Cumartesi"],
+ daysShort: ["Pz", "Pzt", "Sal", "Çrş", "Prş", "Cu", "Cts"],
+ daysMin: ["Pz", "Pzt", "Sa", "Çr", "Pr", "Cu", "Ct"],
+ months: ["Ocak", "Şubat", "Mart", "Nisan", "Mayıs", "Haziran", "Temmuz", "Ağustos", "Eylül", "Ekim", "Kasım", "Aralık"],
+ monthsShort: ["Oca", "Şub", "Mar", "Nis", "May", "Haz", "Tem", "Ağu", "Eyl", "Eki", "Kas", "Ara"],
+ today: "Bugün",
+ clear: "Temizle",
+ weekStart: 1,
+ format: "dd.mm.yyyy"
+ };
+}(jQuery));
+
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.uk.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.uk.js
new file mode 100755
index 000000000..1c4cf15aa
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.uk.js
@@ -0,0 +1,17 @@
+/**
+ * Ukrainian translation for bootstrap-datepicker
+ * Igor Polynets
+ */
+;(function($){
+ $.fn.datepicker.dates['uk'] = {
+ days: ["Неділя", "Понеділок", "Вівторок", "Середа", "Четвер", "П'ятниця", "Субота"],
+ daysShort: ["Нед", "Пнд", "Втр", "Срд", "Чтв", "Птн", "Суб"],
+ daysMin: ["Нд", "Пн", "Вт", "Ср", "Чт", "Пт", "Сб"],
+ months: ["Cічень", "Лютий", "Березень", "Квітень", "Травень", "Червень", "Липень", "Серпень", "Вересень", "Жовтень", "Листопад", "Грудень"],
+ monthsShort: ["Січ", "Лют", "Бер", "Кві", "Тра", "Чер", "Лип", "Сер", "Вер", "Жов", "Лис", "Гру"],
+ today: "Сьогодні",
+ clear: "Очистити",
+ format: "dd.mm.yyyy",
+ weekStart: 1
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.vi.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.vi.js
new file mode 100755
index 000000000..0e8afc1b5
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.vi.js
@@ -0,0 +1,16 @@
+/**
+ * Vietnamese translation for bootstrap-datepicker
+ * An Vo
+ */
+;(function($){
+ $.fn.datepicker.dates['vi'] = {
+ days: ["Chủ nhật", "Thứ hai", "Thứ ba", "Thứ tư", "Thứ năm", "Thứ sáu", "Thứ bảy"],
+ daysShort: ["CN", "Thứ 2", "Thứ 3", "Thứ 4", "Thứ 5", "Thứ 6", "Thứ 7"],
+ daysMin: ["CN", "T2", "T3", "T4", "T5", "T6", "T7"],
+ months: ["Tháng 1", "Tháng 2", "Tháng 3", "Tháng 4", "Tháng 5", "Tháng 6", "Tháng 7", "Tháng 8", "Tháng 9", "Tháng 10", "Tháng 11", "Tháng 12"],
+ monthsShort: ["Th1", "Th2", "Th3", "Th4", "Th5", "Th6", "Th7", "Th8", "Th9", "Th10", "Th11", "Th12"],
+ today: "Hôm nay",
+ clear: "Xóa",
+ format: "dd/mm/yyyy"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.zh-CN.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.zh-CN.js
new file mode 100755
index 000000000..b927d2c18
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.zh-CN.js
@@ -0,0 +1,18 @@
+/**
+ * Simplified Chinese translation for bootstrap-datepicker
+ * Yuan Cheung
+ */
+;(function($){
+ $.fn.datepicker.dates['zh-CN'] = {
+ days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
+ daysShort: ["周日", "周一", "周二", "周三", "周四", "周五", "周六"],
+ daysMin: ["日", "一", "二", "三", "四", "五", "六"],
+ months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
+ monthsShort: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
+ today: "今日",
+ clear: "清除",
+ format: "yyyy年mm月dd日",
+ titleFormat: "yyyy年mm月",
+ weekStart: 1
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.zh-TW.js b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.zh-TW.js
new file mode 100755
index 000000000..ff241b56f
--- /dev/null
+++ b/app/assets/javascripts/app/lib/bootstrap/locales/bootstrap-datepicker.zh-TW.js
@@ -0,0 +1,18 @@
+/**
+ * Traditional Chinese translation for bootstrap-datepicker
+ * Rung-Sheng Jang
+ * FrankWu Fix more appropriate use of Traditional Chinese habit
+ */
+;(function($){
+ $.fn.datepicker.dates['zh-TW'] = {
+ days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"],
+ daysShort: ["週日", "週一", "週二", "週三", "週四", "週五", "週六"],
+ daysMin: ["日", "一", "二", "三", "四", "五", "六"],
+ months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
+ monthsShort: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"],
+ today: "今天",
+ format: "yyyy年mm月dd日",
+ weekStart: 1,
+ clear: "清除"
+ };
+}(jQuery));
diff --git a/app/assets/javascripts/app/lib/core/jquery-ui-1.11.2.js b/app/assets/javascripts/app/lib/core/jquery-ui-1.11.2.js
index ce8731b07..82ba56e0c 100755
--- a/app/assets/javascripts/app/lib/core/jquery-ui-1.11.2.js
+++ b/app/assets/javascripts/app/lib/core/jquery-ui-1.11.2.js
@@ -3758,2073 +3758,6 @@ $.widget( "ui.buttonset", {
var button = $.ui.button;
-/*!
- * jQuery UI Datepicker 1.11.2
- * http://jqueryui.com
- *
- * Copyright 2014 jQuery Foundation and other contributors
- * Released under the MIT license.
- * http://jquery.org/license
- *
- * http://api.jqueryui.com/datepicker/
- */
-
-
-$.extend($.ui, { datepicker: { version: "1.11.2" } });
-
-var datepicker_instActive;
-
-function datepicker_getZindex( elem ) {
- var position, value;
- while ( elem.length && elem[ 0 ] !== document ) {
- // Ignore z-index if position is set to a value where z-index is ignored by the browser
- // This makes behavior of this function consistent across browsers
- // WebKit always returns auto if the element is positioned
- position = elem.css( "position" );
- if ( position === "absolute" || position === "relative" || position === "fixed" ) {
- // IE returns 0 when zIndex is not specified
- // other browsers return a string
- // we ignore the case of nested elements with an explicit value of 0
- //
- value = parseInt( elem.css( "zIndex" ), 10 );
- if ( !isNaN( value ) && value !== 0 ) {
- return value;
- }
- }
- elem = elem.parent();
- }
-
- return 0;
-}
-/* Date picker manager.
- Use the singleton instance of this class, $.datepicker, to interact with the date picker.
- Settings for (groups of) date pickers are maintained in an instance object,
- allowing multiple different settings on the same page. */
-
-function Datepicker() {
- this._curInst = null; // The current instance in use
- this._keyEvent = false; // If the last event was a key event
- this._disabledInputs = []; // List of date picker inputs that have been disabled
- this._datepickerShowing = false; // True if the popup picker is showing , false if not
- this._inDialog = false; // True if showing within a "dialog", false if not
- this._mainDivId = "ui-datepicker-div"; // The ID of the main datepicker division
- this._inlineClass = "ui-datepicker-inline"; // The name of the inline marker class
- this._appendClass = "ui-datepicker-append"; // The name of the append marker class
- this._triggerClass = "ui-datepicker-trigger"; // The name of the trigger marker class
- this._dialogClass = "ui-datepicker-dialog"; // The name of the dialog marker class
- this._disableClass = "ui-datepicker-disabled"; // The name of the disabled covering marker class
- this._unselectableClass = "ui-datepicker-unselectable"; // The name of the unselectable cell marker class
- this._currentClass = "ui-datepicker-current-day"; // The name of the current day marker class
- this._dayOverClass = "ui-datepicker-days-cell-over"; // The name of the day hover marker class
- this.regional = []; // Available regional settings, indexed by language code
- this.regional[""] = { // Default regional settings
- closeText: "Done", // Display text for close link
- prevText: "Prev", // Display text for previous month link
- nextText: "Next", // Display text for next month link
- currentText: "Today", // Display text for current month link
- monthNames: ["January","February","March","April","May","June",
- "July","August","September","October","November","December"], // Names of months for drop-down and formatting
- monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"], // For formatting
- dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], // For formatting
- dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], // For formatting
- dayNamesMin: ["Su","Mo","Tu","We","Th","Fr","Sa"], // Column headings for days starting at Sunday
- weekHeader: "Wk", // Column header for week of the year
- dateFormat: "mm/dd/yy", // See format options on parseDate
- firstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...
- isRTL: false, // True if right-to-left language, false if left-to-right
- showMonthAfterYear: false, // True if the year select precedes month, false for month then year
- yearSuffix: "" // Additional text to append to the year in the month headers
- };
- this._defaults = { // Global defaults for all the date picker instances
- showOn: "focus", // "focus" for popup on focus,
- // "button" for trigger button, or "both" for either
- showAnim: "fadeIn", // Name of jQuery animation for popup
- showOptions: {}, // Options for enhanced animations
- defaultDate: null, // Used when field is blank: actual date,
- // +/-number for offset from today, null for today
- appendText: "", // Display text following the input box, e.g. showing the format
- buttonText: "...", // Text for trigger button
- buttonImage: "", // URL for trigger button image
- buttonImageOnly: false, // True if the image appears alone, false if it appears on a button
- hideIfNoPrevNext: false, // True to hide next/previous month links
- // if not applicable, false to just disable them
- navigationAsDateFormat: false, // True if date formatting applied to prev/today/next links
- gotoCurrent: false, // True if today link goes back to current selection instead
- changeMonth: false, // True if month can be selected directly, false if only prev/next
- changeYear: false, // True if year can be selected directly, false if only prev/next
- yearRange: "c-10:c+10", // Range of years to display in drop-down,
- // either relative to today's year (-nn:+nn), relative to currently displayed year
- // (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)
- showOtherMonths: false, // True to show dates in other months, false to leave blank
- selectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable
- showWeek: false, // True to show week of the year, false to not show it
- calculateWeek: this.iso8601Week, // How to calculate the week of the year,
- // takes a Date and returns the number of the week for it
- shortYearCutoff: "+10", // Short year values < this are in the current century,
- // > this are in the previous century,
- // string value starting with "+" for current year + value
- minDate: null, // The earliest selectable date, or null for no limit
- maxDate: null, // The latest selectable date, or null for no limit
- duration: "fast", // Duration of display/closure
- beforeShowDay: null, // Function that takes a date and returns an array with
- // [0] = true if selectable, false if not, [1] = custom CSS class name(s) or "",
- // [2] = cell title (optional), e.g. $.datepicker.noWeekends
- beforeShow: null, // Function that takes an input field and
- // returns a set of custom settings for the date picker
- onSelect: null, // Define a callback function when a date is selected
- onChangeMonthYear: null, // Define a callback function when the month or year is changed
- onClose: null, // Define a callback function when the datepicker is closed
- numberOfMonths: 1, // Number of months to show at a time
- showCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)
- stepMonths: 1, // Number of months to step back/forward
- stepBigMonths: 12, // Number of months to step back/forward for the big links
- altField: "", // Selector for an alternate field to store selected dates into
- altFormat: "", // The date format to use for the alternate field
- constrainInput: true, // The input is constrained by the current date format
- showButtonPanel: false, // True to show button panel, false to not show it
- autoSize: false, // True to size the input for the date format, false to leave as is
- disabled: false // The initial disabled state
- };
- $.extend(this._defaults, this.regional[""]);
- this.regional.en = $.extend( true, {}, this.regional[ "" ]);
- this.regional[ "en-US" ] = $.extend( true, {}, this.regional.en );
- this.dpDiv = datepicker_bindHover($("
"));
-}
-
-$.extend(Datepicker.prototype, {
- /* Class name added to elements to indicate already configured with a date picker. */
- markerClassName: "hasDatepicker",
-
- //Keep track of the maximum number of rows displayed (see #7043)
- maxRows: 4,
-
- // TODO rename to "widget" when switching to widget factory
- _widgetDatepicker: function() {
- return this.dpDiv;
- },
-
- /* Override the default settings for all instances of the date picker.
- * @param settings object - the new settings to use as defaults (anonymous object)
- * @return the manager object
- */
- setDefaults: function(settings) {
- datepicker_extendRemove(this._defaults, settings || {});
- return this;
- },
-
- /* Attach the date picker to a jQuery selection.
- * @param target element - the target input field or division or span
- * @param settings object - the new settings to use for this date picker instance (anonymous)
- */
- _attachDatepicker: function(target, settings) {
- var nodeName, inline, inst;
- nodeName = target.nodeName.toLowerCase();
- inline = (nodeName === "div" || nodeName === "span");
- if (!target.id) {
- this.uuid += 1;
- target.id = "dp" + this.uuid;
- }
- inst = this._newInst($(target), inline);
- inst.settings = $.extend({}, settings || {});
- if (nodeName === "input") {
- this._connectDatepicker(target, inst);
- } else if (inline) {
- this._inlineDatepicker(target, inst);
- }
- },
-
- /* Create a new instance object. */
- _newInst: function(target, inline) {
- var id = target[0].id.replace(/([^A-Za-z0-9_\-])/g, "\\\\$1"); // escape jQuery meta chars
- return {id: id, input: target, // associated target
- selectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection
- drawMonth: 0, drawYear: 0, // month being drawn
- inline: inline, // is datepicker inline or not
- dpDiv: (!inline ? this.dpDiv : // presentation div
- datepicker_bindHover($("
")))};
- },
-
- /* Attach the date picker to an input field. */
- _connectDatepicker: function(target, inst) {
- var input = $(target);
- inst.append = $([]);
- inst.trigger = $([]);
- if (input.hasClass(this.markerClassName)) {
- return;
- }
- this._attachments(input, inst);
- input.addClass(this.markerClassName).keydown(this._doKeyDown).
- keypress(this._doKeyPress).keyup(this._doKeyUp);
- this._autoSize(inst);
- $.data(target, "datepicker", inst);
- //If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)
- if( inst.settings.disabled ) {
- this._disableDatepicker( target );
- }
- },
-
- /* Make attachments based on settings. */
- _attachments: function(input, inst) {
- var showOn, buttonText, buttonImage,
- appendText = this._get(inst, "appendText"),
- isRTL = this._get(inst, "isRTL");
-
- if (inst.append) {
- inst.append.remove();
- }
- if (appendText) {
- inst.append = $("" + appendText + " ");
- input[isRTL ? "before" : "after"](inst.append);
- }
-
- input.unbind("focus", this._showDatepicker);
-
- if (inst.trigger) {
- inst.trigger.remove();
- }
-
- showOn = this._get(inst, "showOn");
- if (showOn === "focus" || showOn === "both") { // pop-up date picker when in the marked field
- input.focus(this._showDatepicker);
- }
- if (showOn === "button" || showOn === "both") { // pop-up date picker when button clicked
- buttonText = this._get(inst, "buttonText");
- buttonImage = this._get(inst, "buttonImage");
- inst.trigger = $(this._get(inst, "buttonImageOnly") ?
- $(" ").addClass(this._triggerClass).
- attr({ src: buttonImage, alt: buttonText, title: buttonText }) :
- $(" ").addClass(this._triggerClass).
- html(!buttonImage ? buttonText : $(" ").attr(
- { src:buttonImage, alt:buttonText, title:buttonText })));
- input[isRTL ? "before" : "after"](inst.trigger);
- inst.trigger.click(function() {
- if ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {
- $.datepicker._hideDatepicker();
- } else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {
- $.datepicker._hideDatepicker();
- $.datepicker._showDatepicker(input[0]);
- } else {
- $.datepicker._showDatepicker(input[0]);
- }
- return false;
- });
- }
- },
-
- /* Apply the maximum length for the date format. */
- _autoSize: function(inst) {
- if (this._get(inst, "autoSize") && !inst.inline) {
- var findMax, max, maxI, i,
- date = new Date(2009, 12 - 1, 20), // Ensure double digits
- dateFormat = this._get(inst, "dateFormat");
-
- if (dateFormat.match(/[DM]/)) {
- findMax = function(names) {
- max = 0;
- maxI = 0;
- for (i = 0; i < names.length; i++) {
- if (names[i].length > max) {
- max = names[i].length;
- maxI = i;
- }
- }
- return maxI;
- };
- date.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?
- "monthNames" : "monthNamesShort"))));
- date.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?
- "dayNames" : "dayNamesShort"))) + 20 - date.getDay());
- }
- inst.input.attr("size", this._formatDate(inst, date).length);
- }
- },
-
- /* Attach an inline date picker to a div. */
- _inlineDatepicker: function(target, inst) {
- var divSpan = $(target);
- if (divSpan.hasClass(this.markerClassName)) {
- return;
- }
- divSpan.addClass(this.markerClassName).append(inst.dpDiv);
- $.data(target, "datepicker", inst);
- this._setDate(inst, this._getDefaultDate(inst), true);
- this._updateDatepicker(inst);
- this._updateAlternate(inst);
- //If disabled option is true, disable the datepicker before showing it (see ticket #5665)
- if( inst.settings.disabled ) {
- this._disableDatepicker( target );
- }
- // Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements
- // http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height
- inst.dpDiv.css( "display", "block" );
- },
-
- /* Pop-up the date picker in a "dialog" box.
- * @param input element - ignored
- * @param date string or Date - the initial date to display
- * @param onSelect function - the function to call when a date is selected
- * @param settings object - update the dialog date picker instance's settings (anonymous object)
- * @param pos int[2] - coordinates for the dialog's position within the screen or
- * event - with x/y coordinates or
- * leave empty for default (screen centre)
- * @return the manager object
- */
- _dialogDatepicker: function(input, date, onSelect, settings, pos) {
- var id, browserWidth, browserHeight, scrollX, scrollY,
- inst = this._dialogInst; // internal instance
-
- if (!inst) {
- this.uuid += 1;
- id = "dp" + this.uuid;
- this._dialogInput = $(" ");
- this._dialogInput.keydown(this._doKeyDown);
- $("body").append(this._dialogInput);
- inst = this._dialogInst = this._newInst(this._dialogInput, false);
- inst.settings = {};
- $.data(this._dialogInput[0], "datepicker", inst);
- }
- datepicker_extendRemove(inst.settings, settings || {});
- date = (date && date.constructor === Date ? this._formatDate(inst, date) : date);
- this._dialogInput.val(date);
-
- this._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);
- if (!this._pos) {
- browserWidth = document.documentElement.clientWidth;
- browserHeight = document.documentElement.clientHeight;
- scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
- scrollY = document.documentElement.scrollTop || document.body.scrollTop;
- this._pos = // should use actual width/height below
- [(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];
- }
-
- // move input on screen for focus, but hidden behind dialog
- this._dialogInput.css("left", (this._pos[0] + 20) + "px").css("top", this._pos[1] + "px");
- inst.settings.onSelect = onSelect;
- this._inDialog = true;
- this.dpDiv.addClass(this._dialogClass);
- this._showDatepicker(this._dialogInput[0]);
- if ($.blockUI) {
- $.blockUI(this.dpDiv);
- }
- $.data(this._dialogInput[0], "datepicker", inst);
- return this;
- },
-
- /* Detach a datepicker from its control.
- * @param target element - the target input field or division or span
- */
- _destroyDatepicker: function(target) {
- var nodeName,
- $target = $(target),
- inst = $.data(target, "datepicker");
-
- if (!$target.hasClass(this.markerClassName)) {
- return;
- }
-
- nodeName = target.nodeName.toLowerCase();
- $.removeData(target, "datepicker");
- if (nodeName === "input") {
- inst.append.remove();
- inst.trigger.remove();
- $target.removeClass(this.markerClassName).
- unbind("focus", this._showDatepicker).
- unbind("keydown", this._doKeyDown).
- unbind("keypress", this._doKeyPress).
- unbind("keyup", this._doKeyUp);
- } else if (nodeName === "div" || nodeName === "span") {
- $target.removeClass(this.markerClassName).empty();
- }
- },
-
- /* Enable the date picker to a jQuery selection.
- * @param target element - the target input field or division or span
- */
- _enableDatepicker: function(target) {
- var nodeName, inline,
- $target = $(target),
- inst = $.data(target, "datepicker");
-
- if (!$target.hasClass(this.markerClassName)) {
- return;
- }
-
- nodeName = target.nodeName.toLowerCase();
- if (nodeName === "input") {
- target.disabled = false;
- inst.trigger.filter("button").
- each(function() { this.disabled = false; }).end().
- filter("img").css({opacity: "1.0", cursor: ""});
- } else if (nodeName === "div" || nodeName === "span") {
- inline = $target.children("." + this._inlineClass);
- inline.children().removeClass("ui-state-disabled");
- inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
- prop("disabled", false);
- }
- this._disabledInputs = $.map(this._disabledInputs,
- function(value) { return (value === target ? null : value); }); // delete entry
- },
-
- /* Disable the date picker to a jQuery selection.
- * @param target element - the target input field or division or span
- */
- _disableDatepicker: function(target) {
- var nodeName, inline,
- $target = $(target),
- inst = $.data(target, "datepicker");
-
- if (!$target.hasClass(this.markerClassName)) {
- return;
- }
-
- nodeName = target.nodeName.toLowerCase();
- if (nodeName === "input") {
- target.disabled = true;
- inst.trigger.filter("button").
- each(function() { this.disabled = true; }).end().
- filter("img").css({opacity: "0.5", cursor: "default"});
- } else if (nodeName === "div" || nodeName === "span") {
- inline = $target.children("." + this._inlineClass);
- inline.children().addClass("ui-state-disabled");
- inline.find("select.ui-datepicker-month, select.ui-datepicker-year").
- prop("disabled", true);
- }
- this._disabledInputs = $.map(this._disabledInputs,
- function(value) { return (value === target ? null : value); }); // delete entry
- this._disabledInputs[this._disabledInputs.length] = target;
- },
-
- /* Is the first field in a jQuery collection disabled as a datepicker?
- * @param target element - the target input field or division or span
- * @return boolean - true if disabled, false if enabled
- */
- _isDisabledDatepicker: function(target) {
- if (!target) {
- return false;
- }
- for (var i = 0; i < this._disabledInputs.length; i++) {
- if (this._disabledInputs[i] === target) {
- return true;
- }
- }
- return false;
- },
-
- /* Retrieve the instance data for the target control.
- * @param target element - the target input field or division or span
- * @return object - the associated instance data
- * @throws error if a jQuery problem getting data
- */
- _getInst: function(target) {
- try {
- return $.data(target, "datepicker");
- }
- catch (err) {
- throw "Missing instance data for this datepicker";
- }
- },
-
- /* Update or retrieve the settings for a date picker attached to an input field or division.
- * @param target element - the target input field or division or span
- * @param name object - the new settings to update or
- * string - the name of the setting to change or retrieve,
- * when retrieving also "all" for all instance settings or
- * "defaults" for all global defaults
- * @param value any - the new value for the setting
- * (omit if above is an object or to retrieve a value)
- */
- _optionDatepicker: function(target, name, value) {
- var settings, date, minDate, maxDate,
- inst = this._getInst(target);
-
- if (arguments.length === 2 && typeof name === "string") {
- return (name === "defaults" ? $.extend({}, $.datepicker._defaults) :
- (inst ? (name === "all" ? $.extend({}, inst.settings) :
- this._get(inst, name)) : null));
- }
-
- settings = name || {};
- if (typeof name === "string") {
- settings = {};
- settings[name] = value;
- }
-
- if (inst) {
- if (this._curInst === inst) {
- this._hideDatepicker();
- }
-
- date = this._getDateDatepicker(target, true);
- minDate = this._getMinMaxDate(inst, "min");
- maxDate = this._getMinMaxDate(inst, "max");
- datepicker_extendRemove(inst.settings, settings);
- // reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided
- if (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {
- inst.settings.minDate = this._formatDate(inst, minDate);
- }
- if (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {
- inst.settings.maxDate = this._formatDate(inst, maxDate);
- }
- if ( "disabled" in settings ) {
- if ( settings.disabled ) {
- this._disableDatepicker(target);
- } else {
- this._enableDatepicker(target);
- }
- }
- this._attachments($(target), inst);
- this._autoSize(inst);
- this._setDate(inst, date);
- this._updateAlternate(inst);
- this._updateDatepicker(inst);
- }
- },
-
- // change method deprecated
- _changeDatepicker: function(target, name, value) {
- this._optionDatepicker(target, name, value);
- },
-
- /* Redraw the date picker attached to an input field or division.
- * @param target element - the target input field or division or span
- */
- _refreshDatepicker: function(target) {
- var inst = this._getInst(target);
- if (inst) {
- this._updateDatepicker(inst);
- }
- },
-
- /* Set the dates for a jQuery selection.
- * @param target element - the target input field or division or span
- * @param date Date - the new date
- */
- _setDateDatepicker: function(target, date) {
- var inst = this._getInst(target);
- if (inst) {
- this._setDate(inst, date);
- this._updateDatepicker(inst);
- this._updateAlternate(inst);
- }
- },
-
- /* Get the date(s) for the first entry in a jQuery selection.
- * @param target element - the target input field or division or span
- * @param noDefault boolean - true if no default date is to be used
- * @return Date - the current date
- */
- _getDateDatepicker: function(target, noDefault) {
- var inst = this._getInst(target);
- if (inst && !inst.inline) {
- this._setDateFromField(inst, noDefault);
- }
- return (inst ? this._getDate(inst) : null);
- },
-
- /* Handle keystrokes. */
- _doKeyDown: function(event) {
- var onSelect, dateStr, sel,
- inst = $.datepicker._getInst(event.target),
- handled = true,
- isRTL = inst.dpDiv.is(".ui-datepicker-rtl");
-
- inst._keyEvent = true;
- if ($.datepicker._datepickerShowing) {
- switch (event.keyCode) {
- case 9: $.datepicker._hideDatepicker();
- handled = false;
- break; // hide on tab out
- case 13: sel = $("td." + $.datepicker._dayOverClass + ":not(." +
- $.datepicker._currentClass + ")", inst.dpDiv);
- if (sel[0]) {
- $.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);
- }
-
- onSelect = $.datepicker._get(inst, "onSelect");
- if (onSelect) {
- dateStr = $.datepicker._formatDate(inst);
-
- // trigger custom callback
- onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);
- } else {
- $.datepicker._hideDatepicker();
- }
-
- return false; // don't submit the form
- case 27: $.datepicker._hideDatepicker();
- break; // hide on escape
- case 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
- -$.datepicker._get(inst, "stepBigMonths") :
- -$.datepicker._get(inst, "stepMonths")), "M");
- break; // previous month/year on page up/+ ctrl
- case 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?
- +$.datepicker._get(inst, "stepBigMonths") :
- +$.datepicker._get(inst, "stepMonths")), "M");
- break; // next month/year on page down/+ ctrl
- case 35: if (event.ctrlKey || event.metaKey) {
- $.datepicker._clearDate(event.target);
- }
- handled = event.ctrlKey || event.metaKey;
- break; // clear on ctrl or command +end
- case 36: if (event.ctrlKey || event.metaKey) {
- $.datepicker._gotoToday(event.target);
- }
- handled = event.ctrlKey || event.metaKey;
- break; // current on ctrl or command +home
- case 37: if (event.ctrlKey || event.metaKey) {
- $.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), "D");
- }
- handled = event.ctrlKey || event.metaKey;
- // -1 day on ctrl or command +left
- if (event.originalEvent.altKey) {
- $.datepicker._adjustDate(event.target, (event.ctrlKey ?
- -$.datepicker._get(inst, "stepBigMonths") :
- -$.datepicker._get(inst, "stepMonths")), "M");
- }
- // next month/year on alt +left on Mac
- break;
- case 38: if (event.ctrlKey || event.metaKey) {
- $.datepicker._adjustDate(event.target, -7, "D");
- }
- handled = event.ctrlKey || event.metaKey;
- break; // -1 week on ctrl or command +up
- case 39: if (event.ctrlKey || event.metaKey) {
- $.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), "D");
- }
- handled = event.ctrlKey || event.metaKey;
- // +1 day on ctrl or command +right
- if (event.originalEvent.altKey) {
- $.datepicker._adjustDate(event.target, (event.ctrlKey ?
- +$.datepicker._get(inst, "stepBigMonths") :
- +$.datepicker._get(inst, "stepMonths")), "M");
- }
- // next month/year on alt +right
- break;
- case 40: if (event.ctrlKey || event.metaKey) {
- $.datepicker._adjustDate(event.target, +7, "D");
- }
- handled = event.ctrlKey || event.metaKey;
- break; // +1 week on ctrl or command +down
- default: handled = false;
- }
- } else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home
- $.datepicker._showDatepicker(this);
- } else {
- handled = false;
- }
-
- if (handled) {
- event.preventDefault();
- event.stopPropagation();
- }
- },
-
- /* Filter entered characters - based on date format. */
- _doKeyPress: function(event) {
- var chars, chr,
- inst = $.datepicker._getInst(event.target);
-
- if ($.datepicker._get(inst, "constrainInput")) {
- chars = $.datepicker._possibleChars($.datepicker._get(inst, "dateFormat"));
- chr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);
- return event.ctrlKey || event.metaKey || (chr < " " || !chars || chars.indexOf(chr) > -1);
- }
- },
-
- /* Synchronise manual entry and field/alternate field. */
- _doKeyUp: function(event) {
- var date,
- inst = $.datepicker._getInst(event.target);
-
- if (inst.input.val() !== inst.lastVal) {
- try {
- date = $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
- (inst.input ? inst.input.val() : null),
- $.datepicker._getFormatConfig(inst));
-
- if (date) { // only if valid
- $.datepicker._setDateFromField(inst);
- $.datepicker._updateAlternate(inst);
- $.datepicker._updateDatepicker(inst);
- }
- }
- catch (err) {
- }
- }
- return true;
- },
-
- /* Pop-up the date picker for a given input field.
- * If false returned from beforeShow event handler do not show.
- * @param input element - the input field attached to the date picker or
- * event - if triggered by focus
- */
- _showDatepicker: function(input) {
- input = input.target || input;
- if (input.nodeName.toLowerCase() !== "input") { // find from button/image trigger
- input = $("input", input.parentNode)[0];
- }
-
- if ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here
- return;
- }
-
- var inst, beforeShow, beforeShowSettings, isFixed,
- offset, showAnim, duration;
-
- inst = $.datepicker._getInst(input);
- if ($.datepicker._curInst && $.datepicker._curInst !== inst) {
- $.datepicker._curInst.dpDiv.stop(true, true);
- if ( inst && $.datepicker._datepickerShowing ) {
- $.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );
- }
- }
-
- beforeShow = $.datepicker._get(inst, "beforeShow");
- beforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};
- if(beforeShowSettings === false){
- return;
- }
- datepicker_extendRemove(inst.settings, beforeShowSettings);
-
- inst.lastVal = null;
- $.datepicker._lastInput = input;
- $.datepicker._setDateFromField(inst);
-
- if ($.datepicker._inDialog) { // hide cursor
- input.value = "";
- }
- if (!$.datepicker._pos) { // position below input
- $.datepicker._pos = $.datepicker._findPos(input);
- $.datepicker._pos[1] += input.offsetHeight; // add the height
- }
-
- isFixed = false;
- $(input).parents().each(function() {
- isFixed |= $(this).css("position") === "fixed";
- return !isFixed;
- });
-
- offset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};
- $.datepicker._pos = null;
- //to avoid flashes on Firefox
- inst.dpDiv.empty();
- // determine sizing offscreen
- inst.dpDiv.css({position: "absolute", display: "block", top: "-1000px"});
- $.datepicker._updateDatepicker(inst);
- // fix width for dynamic number of date pickers
- // and adjust position before showing
- offset = $.datepicker._checkOffset(inst, offset, isFixed);
- inst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?
- "static" : (isFixed ? "fixed" : "absolute")), display: "none",
- left: offset.left + "px", top: offset.top + "px"});
-
- if (!inst.inline) {
- showAnim = $.datepicker._get(inst, "showAnim");
- duration = $.datepicker._get(inst, "duration");
- inst.dpDiv.css( "z-index", datepicker_getZindex( $( input ) ) + 1 );
- $.datepicker._datepickerShowing = true;
-
- if ( $.effects && $.effects.effect[ showAnim ] ) {
- inst.dpDiv.show(showAnim, $.datepicker._get(inst, "showOptions"), duration);
- } else {
- inst.dpDiv[showAnim || "show"](showAnim ? duration : null);
- }
-
- if ( $.datepicker._shouldFocusInput( inst ) ) {
- inst.input.focus();
- }
-
- $.datepicker._curInst = inst;
- }
- },
-
- /* Generate the date picker content. */
- _updateDatepicker: function(inst) {
- this.maxRows = 4; //Reset the max number of rows being displayed (see #7043)
- datepicker_instActive = inst; // for delegate hover events
- inst.dpDiv.empty().append(this._generateHTML(inst));
- this._attachHandlers(inst);
-
- var origyearshtml,
- numMonths = this._getNumberOfMonths(inst),
- cols = numMonths[1],
- width = 17,
- activeCell = inst.dpDiv.find( "." + this._dayOverClass + " a" );
-
- if ( activeCell.length > 0 ) {
- datepicker_handleMouseover.apply( activeCell.get( 0 ) );
- }
-
- inst.dpDiv.removeClass("ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4").width("");
- if (cols > 1) {
- inst.dpDiv.addClass("ui-datepicker-multi-" + cols).css("width", (width * cols) + "em");
- }
- inst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? "add" : "remove") +
- "Class"]("ui-datepicker-multi");
- inst.dpDiv[(this._get(inst, "isRTL") ? "add" : "remove") +
- "Class"]("ui-datepicker-rtl");
-
- if (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {
- inst.input.focus();
- }
-
- // deffered render of the years select (to avoid flashes on Firefox)
- if( inst.yearshtml ){
- origyearshtml = inst.yearshtml;
- setTimeout(function(){
- //assure that inst.yearshtml didn't change.
- if( origyearshtml === inst.yearshtml && inst.yearshtml ){
- inst.dpDiv.find("select.ui-datepicker-year:first").replaceWith(inst.yearshtml);
- }
- origyearshtml = inst.yearshtml = null;
- }, 0);
- }
- },
-
- // #6694 - don't focus the input if it's already focused
- // this breaks the change event in IE
- // Support: IE and jQuery <1.9
- _shouldFocusInput: function( inst ) {
- return inst.input && inst.input.is( ":visible" ) && !inst.input.is( ":disabled" ) && !inst.input.is( ":focus" );
- },
-
- /* Check positioning to remain on screen. */
- _checkOffset: function(inst, offset, isFixed) {
- var dpWidth = inst.dpDiv.outerWidth(),
- dpHeight = inst.dpDiv.outerHeight(),
- inputWidth = inst.input ? inst.input.outerWidth() : 0,
- inputHeight = inst.input ? inst.input.outerHeight() : 0,
- viewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),
- viewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());
-
- offset.left -= (this._get(inst, "isRTL") ? (dpWidth - inputWidth) : 0);
- offset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;
- offset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;
-
- // now check if datepicker is showing outside window viewport - move to a better place if so.
- offset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?
- Math.abs(offset.left + dpWidth - viewWidth) : 0);
- offset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?
- Math.abs(dpHeight + inputHeight) : 0);
-
- return offset;
- },
-
- /* Find an object's position on the screen. */
- _findPos: function(obj) {
- var position,
- inst = this._getInst(obj),
- isRTL = this._get(inst, "isRTL");
-
- while (obj && (obj.type === "hidden" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {
- obj = obj[isRTL ? "previousSibling" : "nextSibling"];
- }
-
- position = $(obj).offset();
- return [position.left, position.top];
- },
-
- /* Hide the date picker from view.
- * @param input element - the input field attached to the date picker
- */
- _hideDatepicker: function(input) {
- var showAnim, duration, postProcess, onClose,
- inst = this._curInst;
-
- if (!inst || (input && inst !== $.data(input, "datepicker"))) {
- return;
- }
-
- if (this._datepickerShowing) {
- showAnim = this._get(inst, "showAnim");
- duration = this._get(inst, "duration");
- postProcess = function() {
- $.datepicker._tidyDialog(inst);
- };
-
- // DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed
- if ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {
- inst.dpDiv.hide(showAnim, $.datepicker._get(inst, "showOptions"), duration, postProcess);
- } else {
- inst.dpDiv[(showAnim === "slideDown" ? "slideUp" :
- (showAnim === "fadeIn" ? "fadeOut" : "hide"))]((showAnim ? duration : null), postProcess);
- }
-
- if (!showAnim) {
- postProcess();
- }
- this._datepickerShowing = false;
-
- onClose = this._get(inst, "onClose");
- if (onClose) {
- onClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : ""), inst]);
- }
-
- this._lastInput = null;
- if (this._inDialog) {
- this._dialogInput.css({ position: "absolute", left: "0", top: "-100px" });
- if ($.blockUI) {
- $.unblockUI();
- $("body").append(this.dpDiv);
- }
- }
- this._inDialog = false;
- }
- },
-
- /* Tidy up after a dialog display. */
- _tidyDialog: function(inst) {
- inst.dpDiv.removeClass(this._dialogClass).unbind(".ui-datepicker-calendar");
- },
-
- /* Close date picker if clicked elsewhere. */
- _checkExternalClick: function(event) {
- if (!$.datepicker._curInst) {
- return;
- }
-
- var $target = $(event.target),
- inst = $.datepicker._getInst($target[0]);
-
- if ( ( ( $target[0].id !== $.datepicker._mainDivId &&
- $target.parents("#" + $.datepicker._mainDivId).length === 0 &&
- !$target.hasClass($.datepicker.markerClassName) &&
- !$target.closest("." + $.datepicker._triggerClass).length &&
- $.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||
- ( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {
- $.datepicker._hideDatepicker();
- }
- },
-
- /* Adjust one of the date sub-fields. */
- _adjustDate: function(id, offset, period) {
- var target = $(id),
- inst = this._getInst(target[0]);
-
- if (this._isDisabledDatepicker(target[0])) {
- return;
- }
- this._adjustInstDate(inst, offset +
- (period === "M" ? this._get(inst, "showCurrentAtPos") : 0), // undo positioning
- period);
- this._updateDatepicker(inst);
- },
-
- /* Action for current link. */
- _gotoToday: function(id) {
- var date,
- target = $(id),
- inst = this._getInst(target[0]);
-
- if (this._get(inst, "gotoCurrent") && inst.currentDay) {
- inst.selectedDay = inst.currentDay;
- inst.drawMonth = inst.selectedMonth = inst.currentMonth;
- inst.drawYear = inst.selectedYear = inst.currentYear;
- } else {
- date = new Date();
- inst.selectedDay = date.getDate();
- inst.drawMonth = inst.selectedMonth = date.getMonth();
- inst.drawYear = inst.selectedYear = date.getFullYear();
- }
- this._notifyChange(inst);
- this._adjustDate(target);
- },
-
- /* Action for selecting a new month/year. */
- _selectMonthYear: function(id, select, period) {
- var target = $(id),
- inst = this._getInst(target[0]);
-
- inst["selected" + (period === "M" ? "Month" : "Year")] =
- inst["draw" + (period === "M" ? "Month" : "Year")] =
- parseInt(select.options[select.selectedIndex].value,10);
-
- this._notifyChange(inst);
- this._adjustDate(target);
- },
-
- /* Action for selecting a day. */
- _selectDay: function(id, month, year, td) {
- var inst,
- target = $(id);
-
- if ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {
- return;
- }
-
- inst = this._getInst(target[0]);
- inst.selectedDay = inst.currentDay = $("a", td).html();
- inst.selectedMonth = inst.currentMonth = month;
- inst.selectedYear = inst.currentYear = year;
- this._selectDate(id, this._formatDate(inst,
- inst.currentDay, inst.currentMonth, inst.currentYear));
- },
-
- /* Erase the input field and hide the date picker. */
- _clearDate: function(id) {
- var target = $(id);
- this._selectDate(target, "");
- },
-
- /* Update the input field with the selected date. */
- _selectDate: function(id, dateStr) {
- var onSelect,
- target = $(id),
- inst = this._getInst(target[0]);
-
- dateStr = (dateStr != null ? dateStr : this._formatDate(inst));
- if (inst.input) {
- inst.input.val(dateStr);
- }
- this._updateAlternate(inst);
-
- onSelect = this._get(inst, "onSelect");
- if (onSelect) {
- onSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]); // trigger custom callback
- } else if (inst.input) {
- inst.input.trigger("change"); // fire the change event
- }
-
- if (inst.inline){
- this._updateDatepicker(inst);
- } else {
- this._hideDatepicker();
- this._lastInput = inst.input[0];
- if (typeof(inst.input[0]) !== "object") {
- inst.input.focus(); // restore focus
- }
- this._lastInput = null;
- }
- },
-
- /* Update any alternate field to synchronise with the main field. */
- _updateAlternate: function(inst) {
- var altFormat, date, dateStr,
- altField = this._get(inst, "altField");
-
- if (altField) { // update alternate field too
- altFormat = this._get(inst, "altFormat") || this._get(inst, "dateFormat");
- date = this._getDate(inst);
- dateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));
- $(altField).each(function() { $(this).val(dateStr); });
- }
- },
-
- /* Set as beforeShowDay function to prevent selection of weekends.
- * @param date Date - the date to customise
- * @return [boolean, string] - is this date selectable?, what is its CSS class?
- */
- noWeekends: function(date) {
- var day = date.getDay();
- return [(day > 0 && day < 6), ""];
- },
-
- /* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.
- * @param date Date - the date to get the week for
- * @return number - the number of the week within the year that contains this date
- */
- iso8601Week: function(date) {
- var time,
- checkDate = new Date(date.getTime());
-
- // Find Thursday of this week starting on Monday
- checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));
-
- time = checkDate.getTime();
- checkDate.setMonth(0); // Compare with Jan 1
- checkDate.setDate(1);
- return Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;
- },
-
- /* Parse a string value into a date object.
- * See formatDate below for the possible formats.
- *
- * @param format string - the expected format of the date
- * @param value string - the date in the above format
- * @param settings Object - attributes include:
- * shortYearCutoff number - the cutoff year for determining the century (optional)
- * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
- * dayNames string[7] - names of the days from Sunday (optional)
- * monthNamesShort string[12] - abbreviated names of the months (optional)
- * monthNames string[12] - names of the months (optional)
- * @return Date - the extracted date value or null if value is blank
- */
- parseDate: function (format, value, settings) {
- if (format == null || value == null) {
- throw "Invalid arguments";
- }
-
- value = (typeof value === "object" ? value.toString() : value + "");
- if (value === "") {
- return null;
- }
-
- var iFormat, dim, extra,
- iValue = 0,
- shortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,
- shortYearCutoff = (typeof shortYearCutoffTemp !== "string" ? shortYearCutoffTemp :
- new Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),
- dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
- dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
- monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
- monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
- year = -1,
- month = -1,
- day = -1,
- doy = -1,
- literal = false,
- date,
- // Check whether a format character is doubled
- lookAhead = function(match) {
- var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
- if (matches) {
- iFormat++;
- }
- return matches;
- },
- // Extract a number from the string value
- getNumber = function(match) {
- var isDoubled = lookAhead(match),
- size = (match === "@" ? 14 : (match === "!" ? 20 :
- (match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
- minSize = (match === "y" ? size : 1),
- digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
- num = value.substring(iValue).match(digits);
- if (!num) {
- throw "Missing number at position " + iValue;
- }
- iValue += num[0].length;
- return parseInt(num[0], 10);
- },
- // Extract a name from the string value and convert to an index
- getName = function(match, shortNames, longNames) {
- var index = -1,
- names = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {
- return [ [k, v] ];
- }).sort(function (a, b) {
- return -(a[1].length - b[1].length);
- });
-
- $.each(names, function (i, pair) {
- var name = pair[1];
- if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
- index = pair[0];
- iValue += name.length;
- return false;
- }
- });
- if (index !== -1) {
- return index + 1;
- } else {
- throw "Unknown name at position " + iValue;
- }
- },
- // Confirm that a literal character matches the string value
- checkLiteral = function() {
- if (value.charAt(iValue) !== format.charAt(iFormat)) {
- throw "Unexpected literal at position " + iValue;
- }
- iValue++;
- };
-
- for (iFormat = 0; iFormat < format.length; iFormat++) {
- if (literal) {
- if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
- literal = false;
- } else {
- checkLiteral();
- }
- } else {
- switch (format.charAt(iFormat)) {
- case "d":
- day = getNumber("d");
- break;
- case "D":
- getName("D", dayNamesShort, dayNames);
- break;
- case "o":
- doy = getNumber("o");
- break;
- case "m":
- month = getNumber("m");
- break;
- case "M":
- month = getName("M", monthNamesShort, monthNames);
- break;
- case "y":
- year = getNumber("y");
- break;
- case "@":
- date = new Date(getNumber("@"));
- year = date.getFullYear();
- month = date.getMonth() + 1;
- day = date.getDate();
- break;
- case "!":
- date = new Date((getNumber("!") - this._ticksTo1970) / 10000);
- year = date.getFullYear();
- month = date.getMonth() + 1;
- day = date.getDate();
- break;
- case "'":
- if (lookAhead("'")){
- checkLiteral();
- } else {
- literal = true;
- }
- break;
- default:
- checkLiteral();
- }
- }
- }
-
- if (iValue < value.length){
- extra = value.substr(iValue);
- if (!/^\s+/.test(extra)) {
- throw "Extra/unparsed characters found in date: " + extra;
- }
- }
-
- if (year === -1) {
- year = new Date().getFullYear();
- } else if (year < 100) {
- year += new Date().getFullYear() - new Date().getFullYear() % 100 +
- (year <= shortYearCutoff ? 0 : -100);
- }
-
- if (doy > -1) {
- month = 1;
- day = doy;
- do {
- dim = this._getDaysInMonth(year, month - 1);
- if (day <= dim) {
- break;
- }
- month++;
- day -= dim;
- } while (true);
- }
-
- date = this._daylightSavingAdjust(new Date(year, month - 1, day));
- if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
- throw "Invalid date"; // E.g. 31/02/00
- }
- return date;
- },
-
- /* Standard date formats. */
- ATOM: "yy-mm-dd", // RFC 3339 (ISO 8601)
- COOKIE: "D, dd M yy",
- ISO_8601: "yy-mm-dd",
- RFC_822: "D, d M y",
- RFC_850: "DD, dd-M-y",
- RFC_1036: "D, d M y",
- RFC_1123: "D, d M yy",
- RFC_2822: "D, d M yy",
- RSS: "D, d M y", // RFC 822
- TICKS: "!",
- TIMESTAMP: "@",
- W3C: "yy-mm-dd", // ISO 8601
-
- _ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +
- Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),
-
- /* Format a date object into a string value.
- * The format can be combinations of the following:
- * d - day of month (no leading zero)
- * dd - day of month (two digit)
- * o - day of year (no leading zeros)
- * oo - day of year (three digit)
- * D - day name short
- * DD - day name long
- * m - month of year (no leading zero)
- * mm - month of year (two digit)
- * M - month name short
- * MM - month name long
- * y - year (two digit)
- * yy - year (four digit)
- * @ - Unix timestamp (ms since 01/01/1970)
- * ! - Windows ticks (100ns since 01/01/0001)
- * "..." - literal text
- * '' - single quote
- *
- * @param format string - the desired format of the date
- * @param date Date - the date value to format
- * @param settings Object - attributes include:
- * dayNamesShort string[7] - abbreviated names of the days from Sunday (optional)
- * dayNames string[7] - names of the days from Sunday (optional)
- * monthNamesShort string[12] - abbreviated names of the months (optional)
- * monthNames string[12] - names of the months (optional)
- * @return string - the date in the above format
- */
- formatDate: function (format, date, settings) {
- if (!date) {
- return "";
- }
-
- var iFormat,
- dayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,
- dayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,
- monthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,
- monthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,
- // Check whether a format character is doubled
- lookAhead = function(match) {
- var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
- if (matches) {
- iFormat++;
- }
- return matches;
- },
- // Format a number, with leading zero if necessary
- formatNumber = function(match, value, len) {
- var num = "" + value;
- if (lookAhead(match)) {
- while (num.length < len) {
- num = "0" + num;
- }
- }
- return num;
- },
- // Format a name, short or long as requested
- formatName = function(match, value, shortNames, longNames) {
- return (lookAhead(match) ? longNames[value] : shortNames[value]);
- },
- output = "",
- literal = false;
-
- if (date) {
- for (iFormat = 0; iFormat < format.length; iFormat++) {
- if (literal) {
- if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
- literal = false;
- } else {
- output += format.charAt(iFormat);
- }
- } else {
- switch (format.charAt(iFormat)) {
- case "d":
- output += formatNumber("d", date.getDate(), 2);
- break;
- case "D":
- output += formatName("D", date.getDay(), dayNamesShort, dayNames);
- break;
- case "o":
- output += formatNumber("o",
- Math.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
- break;
- case "m":
- output += formatNumber("m", date.getMonth() + 1, 2);
- break;
- case "M":
- output += formatName("M", date.getMonth(), monthNamesShort, monthNames);
- break;
- case "y":
- output += (lookAhead("y") ? date.getFullYear() :
- (date.getYear() % 100 < 10 ? "0" : "") + date.getYear() % 100);
- break;
- case "@":
- output += date.getTime();
- break;
- case "!":
- output += date.getTime() * 10000 + this._ticksTo1970;
- break;
- case "'":
- if (lookAhead("'")) {
- output += "'";
- } else {
- literal = true;
- }
- break;
- default:
- output += format.charAt(iFormat);
- }
- }
- }
- }
- return output;
- },
-
- /* Extract all possible characters from the date format. */
- _possibleChars: function (format) {
- var iFormat,
- chars = "",
- literal = false,
- // Check whether a format character is doubled
- lookAhead = function(match) {
- var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
- if (matches) {
- iFormat++;
- }
- return matches;
- };
-
- for (iFormat = 0; iFormat < format.length; iFormat++) {
- if (literal) {
- if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
- literal = false;
- } else {
- chars += format.charAt(iFormat);
- }
- } else {
- switch (format.charAt(iFormat)) {
- case "d": case "m": case "y": case "@":
- chars += "0123456789";
- break;
- case "D": case "M":
- return null; // Accept anything
- case "'":
- if (lookAhead("'")) {
- chars += "'";
- } else {
- literal = true;
- }
- break;
- default:
- chars += format.charAt(iFormat);
- }
- }
- }
- return chars;
- },
-
- /* Get a setting value, defaulting if necessary. */
- _get: function(inst, name) {
- return inst.settings[name] !== undefined ?
- inst.settings[name] : this._defaults[name];
- },
-
- /* Parse existing date and initialise date picker. */
- _setDateFromField: function(inst, noDefault) {
- if (inst.input.val() === inst.lastVal) {
- return;
- }
-
- var dateFormat = this._get(inst, "dateFormat"),
- dates = inst.lastVal = inst.input ? inst.input.val() : null,
- defaultDate = this._getDefaultDate(inst),
- date = defaultDate,
- settings = this._getFormatConfig(inst);
-
- try {
- date = this.parseDate(dateFormat, dates, settings) || defaultDate;
- } catch (event) {
- dates = (noDefault ? "" : dates);
- }
- inst.selectedDay = date.getDate();
- inst.drawMonth = inst.selectedMonth = date.getMonth();
- inst.drawYear = inst.selectedYear = date.getFullYear();
- inst.currentDay = (dates ? date.getDate() : 0);
- inst.currentMonth = (dates ? date.getMonth() : 0);
- inst.currentYear = (dates ? date.getFullYear() : 0);
- this._adjustInstDate(inst);
- },
-
- /* Retrieve the default date shown on opening. */
- _getDefaultDate: function(inst) {
- return this._restrictMinMax(inst,
- this._determineDate(inst, this._get(inst, "defaultDate"), new Date()));
- },
-
- /* A date may be specified as an exact value or a relative one. */
- _determineDate: function(inst, date, defaultDate) {
- var offsetNumeric = function(offset) {
- var date = new Date();
- date.setDate(date.getDate() + offset);
- return date;
- },
- offsetString = function(offset) {
- try {
- return $.datepicker.parseDate($.datepicker._get(inst, "dateFormat"),
- offset, $.datepicker._getFormatConfig(inst));
- }
- catch (e) {
- // Ignore
- }
-
- var date = (offset.toLowerCase().match(/^c/) ?
- $.datepicker._getDate(inst) : null) || new Date(),
- year = date.getFullYear(),
- month = date.getMonth(),
- day = date.getDate(),
- pattern = /([+\-]?[0-9]+)\s*(d|D|w|W|m|M|y|Y)?/g,
- matches = pattern.exec(offset);
-
- while (matches) {
- switch (matches[2] || "d") {
- case "d" : case "D" :
- day += parseInt(matches[1],10); break;
- case "w" : case "W" :
- day += parseInt(matches[1],10) * 7; break;
- case "m" : case "M" :
- month += parseInt(matches[1],10);
- day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
- break;
- case "y": case "Y" :
- year += parseInt(matches[1],10);
- day = Math.min(day, $.datepicker._getDaysInMonth(year, month));
- break;
- }
- matches = pattern.exec(offset);
- }
- return new Date(year, month, day);
- },
- newDate = (date == null || date === "" ? defaultDate : (typeof date === "string" ? offsetString(date) :
- (typeof date === "number" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));
-
- newDate = (newDate && newDate.toString() === "Invalid Date" ? defaultDate : newDate);
- if (newDate) {
- newDate.setHours(0);
- newDate.setMinutes(0);
- newDate.setSeconds(0);
- newDate.setMilliseconds(0);
- }
- return this._daylightSavingAdjust(newDate);
- },
-
- /* Handle switch to/from daylight saving.
- * Hours may be non-zero on daylight saving cut-over:
- * > 12 when midnight changeover, but then cannot generate
- * midnight datetime, so jump to 1AM, otherwise reset.
- * @param date (Date) the date to check
- * @return (Date) the corrected date
- */
- _daylightSavingAdjust: function(date) {
- if (!date) {
- return null;
- }
- date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
- return date;
- },
-
- /* Set the date(s) directly. */
- _setDate: function(inst, date, noChange) {
- var clear = !date,
- origMonth = inst.selectedMonth,
- origYear = inst.selectedYear,
- newDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));
-
- inst.selectedDay = inst.currentDay = newDate.getDate();
- inst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();
- inst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();
- if ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {
- this._notifyChange(inst);
- }
- this._adjustInstDate(inst);
- if (inst.input) {
- inst.input.val(clear ? "" : this._formatDate(inst));
- }
- },
-
- /* Retrieve the date(s) directly. */
- _getDate: function(inst) {
- var startDate = (!inst.currentYear || (inst.input && inst.input.val() === "") ? null :
- this._daylightSavingAdjust(new Date(
- inst.currentYear, inst.currentMonth, inst.currentDay)));
- return startDate;
- },
-
- /* Attach the onxxx handlers. These are declared statically so
- * they work with static code transformers like Caja.
- */
- _attachHandlers: function(inst) {
- var stepMonths = this._get(inst, "stepMonths"),
- id = "#" + inst.id.replace( /\\\\/g, "\\" );
- inst.dpDiv.find("[data-handler]").map(function () {
- var handler = {
- prev: function () {
- $.datepicker._adjustDate(id, -stepMonths, "M");
- },
- next: function () {
- $.datepicker._adjustDate(id, +stepMonths, "M");
- },
- hide: function () {
- $.datepicker._hideDatepicker();
- },
- today: function () {
- $.datepicker._gotoToday(id);
- },
- selectDay: function () {
- $.datepicker._selectDay(id, +this.getAttribute("data-month"), +this.getAttribute("data-year"), this);
- return false;
- },
- selectMonth: function () {
- $.datepicker._selectMonthYear(id, this, "M");
- return false;
- },
- selectYear: function () {
- $.datepicker._selectMonthYear(id, this, "Y");
- return false;
- }
- };
- $(this).bind(this.getAttribute("data-event"), handler[this.getAttribute("data-handler")]);
- });
- },
-
- /* Generate the HTML for the current state of the date picker. */
- _generateHTML: function(inst) {
- var maxDraw, prevText, prev, nextText, next, currentText, gotoDate,
- controls, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,
- monthNames, monthNamesShort, beforeShowDay, showOtherMonths,
- selectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,
- cornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,
- printDate, dRow, tbody, daySettings, otherMonth, unselectable,
- tempDate = new Date(),
- today = this._daylightSavingAdjust(
- new Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time
- isRTL = this._get(inst, "isRTL"),
- showButtonPanel = this._get(inst, "showButtonPanel"),
- hideIfNoPrevNext = this._get(inst, "hideIfNoPrevNext"),
- navigationAsDateFormat = this._get(inst, "navigationAsDateFormat"),
- numMonths = this._getNumberOfMonths(inst),
- showCurrentAtPos = this._get(inst, "showCurrentAtPos"),
- stepMonths = this._get(inst, "stepMonths"),
- isMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),
- currentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :
- new Date(inst.currentYear, inst.currentMonth, inst.currentDay))),
- minDate = this._getMinMaxDate(inst, "min"),
- maxDate = this._getMinMaxDate(inst, "max"),
- drawMonth = inst.drawMonth - showCurrentAtPos,
- drawYear = inst.drawYear;
-
- if (drawMonth < 0) {
- drawMonth += 12;
- drawYear--;
- }
- if (maxDate) {
- maxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),
- maxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));
- maxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);
- while (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {
- drawMonth--;
- if (drawMonth < 0) {
- drawMonth = 11;
- drawYear--;
- }
- }
- }
- inst.drawMonth = drawMonth;
- inst.drawYear = drawYear;
-
- prevText = this._get(inst, "prevText");
- prevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,
- this._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),
- this._getFormatConfig(inst)));
-
- prev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?
- "" + prevText + " " :
- (hideIfNoPrevNext ? "" : "" + prevText + " "));
-
- nextText = this._get(inst, "nextText");
- nextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,
- this._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),
- this._getFormatConfig(inst)));
-
- next = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?
- "" + nextText + " " :
- (hideIfNoPrevNext ? "" : "" + nextText + " "));
-
- currentText = this._get(inst, "currentText");
- gotoDate = (this._get(inst, "gotoCurrent") && inst.currentDay ? currentDate : today);
- currentText = (!navigationAsDateFormat ? currentText :
- this.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));
-
- controls = (!inst.inline ? "" +
- this._get(inst, "closeText") + " " : "");
-
- buttonPanel = (showButtonPanel) ? "" + (isRTL ? controls : "") +
- (this._isInRange(inst, gotoDate) ? "" + currentText + " " : "") + (isRTL ? "" : controls) + "
" : "";
-
- firstDay = parseInt(this._get(inst, "firstDay"),10);
- firstDay = (isNaN(firstDay) ? 0 : firstDay);
-
- showWeek = this._get(inst, "showWeek");
- dayNames = this._get(inst, "dayNames");
- dayNamesMin = this._get(inst, "dayNamesMin");
- monthNames = this._get(inst, "monthNames");
- monthNamesShort = this._get(inst, "monthNamesShort");
- beforeShowDay = this._get(inst, "beforeShowDay");
- showOtherMonths = this._get(inst, "showOtherMonths");
- selectOtherMonths = this._get(inst, "selectOtherMonths");
- defaultDate = this._getDefaultDate(inst);
- html = "";
- dow;
- for (row = 0; row < numMonths[0]; row++) {
- group = "";
- this.maxRows = 4;
- for (col = 0; col < numMonths[1]; col++) {
- selectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));
- cornerClass = " ui-corner-all";
- calender = "";
- if (isMultiMonth) {
- calender += "";
- }
- calender += "
" +
- "";
- thead = (showWeek ? "" + this._get(inst, "weekHeader") + " " : "");
- for (dow = 0; dow < 7; dow++) { // days of the week
- day = (dow + firstDay) % 7;
- thead += "= 5 ? " class='ui-datepicker-week-end'" : "") + ">" +
- "" + dayNamesMin[day] + " ";
- }
- calender += thead + " ";
- daysInMonth = this._getDaysInMonth(drawYear, drawMonth);
- if (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {
- inst.selectedDay = Math.min(inst.selectedDay, daysInMonth);
- }
- leadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;
- curRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate
- numRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)
- this.maxRows = numRows;
- printDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));
- for (dRow = 0; dRow < numRows; dRow++) { // create date picker rows
- calender += "";
- tbody = (!showWeek ? "" : "" +
- this._get(inst, "calculateWeek")(printDate) + " ");
- for (dow = 0; dow < 7; dow++) { // create date picker days
- daySettings = (beforeShowDay ?
- beforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, ""]);
- otherMonth = (printDate.getMonth() !== drawMonth);
- unselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||
- (minDate && printDate < minDate) || (maxDate && printDate > maxDate);
- tbody += "" + // actions
- (otherMonth && !showOtherMonths ? " " : // display for other months
- (unselectable ? "" + printDate.getDate() + " " : "" + printDate.getDate() + " ")) + " "; // display selectable date
- printDate.setDate(printDate.getDate() + 1);
- printDate = this._daylightSavingAdjust(printDate);
- }
- calender += tbody + " ";
- }
- drawMonth++;
- if (drawMonth > 11) {
- drawMonth = 0;
- drawYear++;
- }
- calender += "
" + (isMultiMonth ? "
" +
- ((numMonths[0] > 0 && col === numMonths[1]-1) ? "
" : "") : "");
- group += calender;
- }
- html += group;
- }
- html += buttonPanel;
- inst._keyEvent = false;
- return html;
- },
-
- /* Generate the month and year header. */
- _generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,
- secondary, monthNames, monthNamesShort) {
-
- var inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,
- changeMonth = this._get(inst, "changeMonth"),
- changeYear = this._get(inst, "changeYear"),
- showMonthAfterYear = this._get(inst, "showMonthAfterYear"),
- html = "",
- monthHtml = "";
-
- // month selection
- if (secondary || !changeMonth) {
- monthHtml += "" + monthNames[drawMonth] + " ";
- } else {
- inMinYear = (minDate && minDate.getFullYear() === drawYear);
- inMaxYear = (maxDate && maxDate.getFullYear() === drawYear);
- monthHtml += "";
- for ( month = 0; month < 12; month++) {
- if ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {
- monthHtml += "" + monthNamesShort[month] + " ";
- }
- }
- monthHtml += " ";
- }
-
- if (!showMonthAfterYear) {
- html += monthHtml + (secondary || !(changeMonth && changeYear) ? " " : "");
- }
-
- // year selection
- if ( !inst.yearshtml ) {
- inst.yearshtml = "";
- if (secondary || !changeYear) {
- html += "" + drawYear + " ";
- } else {
- // determine range of years to display
- years = this._get(inst, "yearRange").split(":");
- thisYear = new Date().getFullYear();
- determineYear = function(value) {
- var year = (value.match(/c[+\-].*/) ? drawYear + parseInt(value.substring(1), 10) :
- (value.match(/[+\-].*/) ? thisYear + parseInt(value, 10) :
- parseInt(value, 10)));
- return (isNaN(year) ? thisYear : year);
- };
- year = determineYear(years[0]);
- endYear = Math.max(year, determineYear(years[1] || ""));
- year = (minDate ? Math.max(year, minDate.getFullYear()) : year);
- endYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);
- inst.yearshtml += "";
- for (; year <= endYear; year++) {
- inst.yearshtml += "" + year + " ";
- }
- inst.yearshtml += " ";
-
- html += inst.yearshtml;
- inst.yearshtml = null;
- }
- }
-
- html += this._get(inst, "yearSuffix");
- if (showMonthAfterYear) {
- html += (secondary || !(changeMonth && changeYear) ? " " : "") + monthHtml;
- }
- html += "
"; // Close datepicker_header
- return html;
- },
-
- /* Adjust one of the date sub-fields. */
- _adjustInstDate: function(inst, offset, period) {
- var year = inst.drawYear + (period === "Y" ? offset : 0),
- month = inst.drawMonth + (period === "M" ? offset : 0),
- day = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === "D" ? offset : 0),
- date = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));
-
- inst.selectedDay = date.getDate();
- inst.drawMonth = inst.selectedMonth = date.getMonth();
- inst.drawYear = inst.selectedYear = date.getFullYear();
- if (period === "M" || period === "Y") {
- this._notifyChange(inst);
- }
- },
-
- /* Ensure a date is within any min/max bounds. */
- _restrictMinMax: function(inst, date) {
- var minDate = this._getMinMaxDate(inst, "min"),
- maxDate = this._getMinMaxDate(inst, "max"),
- newDate = (minDate && date < minDate ? minDate : date);
- return (maxDate && newDate > maxDate ? maxDate : newDate);
- },
-
- /* Notify change of month/year. */
- _notifyChange: function(inst) {
- var onChange = this._get(inst, "onChangeMonthYear");
- if (onChange) {
- onChange.apply((inst.input ? inst.input[0] : null),
- [inst.selectedYear, inst.selectedMonth + 1, inst]);
- }
- },
-
- /* Determine the number of months to show. */
- _getNumberOfMonths: function(inst) {
- var numMonths = this._get(inst, "numberOfMonths");
- return (numMonths == null ? [1, 1] : (typeof numMonths === "number" ? [1, numMonths] : numMonths));
- },
-
- /* Determine the current maximum date - ensure no time components are set. */
- _getMinMaxDate: function(inst, minMax) {
- return this._determineDate(inst, this._get(inst, minMax + "Date"), null);
- },
-
- /* Find the number of days in a given month. */
- _getDaysInMonth: function(year, month) {
- return 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();
- },
-
- /* Find the day of the week of the first of a month. */
- _getFirstDayOfMonth: function(year, month) {
- return new Date(year, month, 1).getDay();
- },
-
- /* Determines if we should allow a "next/prev" month display change. */
- _canAdjustMonth: function(inst, offset, curYear, curMonth) {
- var numMonths = this._getNumberOfMonths(inst),
- date = this._daylightSavingAdjust(new Date(curYear,
- curMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));
-
- if (offset < 0) {
- date.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));
- }
- return this._isInRange(inst, date);
- },
-
- /* Is the given date in the accepted range? */
- _isInRange: function(inst, date) {
- var yearSplit, currentYear,
- minDate = this._getMinMaxDate(inst, "min"),
- maxDate = this._getMinMaxDate(inst, "max"),
- minYear = null,
- maxYear = null,
- years = this._get(inst, "yearRange");
- if (years){
- yearSplit = years.split(":");
- currentYear = new Date().getFullYear();
- minYear = parseInt(yearSplit[0], 10);
- maxYear = parseInt(yearSplit[1], 10);
- if ( yearSplit[0].match(/[+\-].*/) ) {
- minYear += currentYear;
- }
- if ( yearSplit[1].match(/[+\-].*/) ) {
- maxYear += currentYear;
- }
- }
-
- return ((!minDate || date.getTime() >= minDate.getTime()) &&
- (!maxDate || date.getTime() <= maxDate.getTime()) &&
- (!minYear || date.getFullYear() >= minYear) &&
- (!maxYear || date.getFullYear() <= maxYear));
- },
-
- /* Provide the configuration settings for formatting/parsing. */
- _getFormatConfig: function(inst) {
- var shortYearCutoff = this._get(inst, "shortYearCutoff");
- shortYearCutoff = (typeof shortYearCutoff !== "string" ? shortYearCutoff :
- new Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));
- return {shortYearCutoff: shortYearCutoff,
- dayNamesShort: this._get(inst, "dayNamesShort"), dayNames: this._get(inst, "dayNames"),
- monthNamesShort: this._get(inst, "monthNamesShort"), monthNames: this._get(inst, "monthNames")};
- },
-
- /* Format the given date for display. */
- _formatDate: function(inst, day, month, year) {
- if (!day) {
- inst.currentDay = inst.selectedDay;
- inst.currentMonth = inst.selectedMonth;
- inst.currentYear = inst.selectedYear;
- }
- var date = (day ? (typeof day === "object" ? day :
- this._daylightSavingAdjust(new Date(year, month, day))) :
- this._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));
- return this.formatDate(this._get(inst, "dateFormat"), date, this._getFormatConfig(inst));
- }
-});
-
-/*
- * Bind hover events for datepicker elements.
- * Done via delegate so the binding only occurs once in the lifetime of the parent div.
- * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.
- */
-function datepicker_bindHover(dpDiv) {
- var selector = "button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a";
- return dpDiv.delegate(selector, "mouseout", function() {
- $(this).removeClass("ui-state-hover");
- if (this.className.indexOf("ui-datepicker-prev") !== -1) {
- $(this).removeClass("ui-datepicker-prev-hover");
- }
- if (this.className.indexOf("ui-datepicker-next") !== -1) {
- $(this).removeClass("ui-datepicker-next-hover");
- }
- })
- .delegate( selector, "mouseover", datepicker_handleMouseover );
-}
-
-function datepicker_handleMouseover() {
- if (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {
- $(this).parents(".ui-datepicker-calendar").find("a").removeClass("ui-state-hover");
- $(this).addClass("ui-state-hover");
- if (this.className.indexOf("ui-datepicker-prev") !== -1) {
- $(this).addClass("ui-datepicker-prev-hover");
- }
- if (this.className.indexOf("ui-datepicker-next") !== -1) {
- $(this).addClass("ui-datepicker-next-hover");
- }
- }
-}
-
-/* jQuery extend now ignores nulls! */
-function datepicker_extendRemove(target, props) {
- $.extend(target, props);
- for (var name in props) {
- if (props[name] == null) {
- target[name] = props[name];
- }
- }
- return target;
-}
-
-/* Invoke the datepicker functionality.
- @param options string - a command, optionally followed by additional parameters or
- Object - settings for attaching new datepicker functionality
- @return jQuery object */
-$.fn.datepicker = function(options){
-
- /* Verify an empty collection wasn't passed - Fixes #6976 */
- if ( !this.length ) {
- return this;
- }
-
- /* Initialise the date picker. */
- if (!$.datepicker.initialized) {
- $(document).mousedown($.datepicker._checkExternalClick);
- $.datepicker.initialized = true;
- }
-
- /* Append datepicker main container to body if not exist. */
- if ($("#"+$.datepicker._mainDivId).length === 0) {
- $("body").append($.datepicker.dpDiv);
- }
-
- var otherArgs = Array.prototype.slice.call(arguments, 1);
- if (typeof options === "string" && (options === "isDisabled" || options === "getDate" || options === "widget")) {
- return $.datepicker["_" + options + "Datepicker"].
- apply($.datepicker, [this[0]].concat(otherArgs));
- }
- if (options === "option" && arguments.length === 2 && typeof arguments[1] === "string") {
- return $.datepicker["_" + options + "Datepicker"].
- apply($.datepicker, [this[0]].concat(otherArgs));
- }
- return this.each(function() {
- typeof options === "string" ?
- $.datepicker["_" + options + "Datepicker"].
- apply($.datepicker, [this].concat(otherArgs)) :
- $.datepicker._attachDatepicker(this, options);
- });
-};
-
-$.datepicker = new Datepicker(); // singleton instance
-$.datepicker.initialized = false;
-$.datepicker.uuid = new Date().getTime();
-$.datepicker.version = "1.11.2";
-
-var datepicker = $.datepicker;
-
-
/*!
* jQuery UI Draggable 1.11.2
* http://jqueryui.com
diff --git a/app/assets/javascripts/app/views/layout_ref/ticket_zoom.jst.eco b/app/assets/javascripts/app/views/layout_ref/ticket_zoom.jst.eco
index bbb8b5900..ee94c2127 100644
--- a/app/assets/javascripts/app/views/layout_ref/ticket_zoom.jst.eco
+++ b/app/assets/javascripts/app/views/layout_ref/ticket_zoom.jst.eco
@@ -1,4 +1,4 @@
-
+
@@ -300,4 +300,325 @@ Oliver
+
+
+
\ No newline at end of file
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index c68a94c38..5564e3648 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -35,6 +35,7 @@
//= require ./app/lib/bootstrap/button.js
//= require ./app/lib/bootstrap/collapse.js
//= require ./app/lib/bootstrap/bootstrap-timepicker.js
+//= require ./app/lib/bootstrap/bootstrap-datepicker.js
//= require ./app/lib/rangy/rangy-core.js
//= require ./app/lib/rangy/rangy-classapplier.js
diff --git a/app/assets/stylesheets/zammad.css.scss b/app/assets/stylesheets/zammad.css.scss
index 870f0088c..f6264dd74 100644
--- a/app/assets/stylesheets/zammad.css.scss
+++ b/app/assets/stylesheets/zammad.css.scss
@@ -875,6 +875,10 @@ fieldset > *:not(.form-group) .form-control {
}
}
+.datetime.form-group .controls {
+ position: relative;
+}
+
.form-group + .form-group {
margin-top: 0;
}
@@ -6255,6 +6259,106 @@ output {
}
}
+.datepicker {
+ background: hsl(234,10%,19%);
+ color: white;
+ padding: 0 14px 11px;
+ position: absolute;
+ left: 0 !important;
+ top: 41px !important;
+ min-width: 0;
+ cursor: default;
+
+ .datepicker-switch {
+ padding: 12px 0;
+ font-size: 15px;
+ text-align: center;
+ cursor: pointer;
+
+ &:hover {
+ background: hsl(240,10%,14%);
+ }
+ }
+
+ .next,
+ .prev {
+ cursor: pointer;
+ padding: 12px 9px 0;
+ vertical-align: top;
+ text-align: center;
+
+ .icon {
+ margin-top: 4px;
+ fill: white;
+ opacity: 1;
+ }
+
+ &:hover {
+ background: hsl(240,10%,14%);
+ }
+ }
+
+ .dow {
+ text-transform: uppercase;
+ font-size: 12px;
+ padding: 20px 5px 0;
+ text-align: center;
+ }
+
+ .day {
+ width: 27px;
+ height: 27px;
+ border-radius: 100%;
+ padding: 0;
+ }
+
+ .month,
+ .year {
+ float: left;
+ width: 23%;
+ margin: 1%;
+ padding: 5px 0;
+ }
+
+ .day, .month, .year {
+ text-align: center;
+ font-size: 15px;
+
+ &:not(.disabled) {
+ cursor: pointer;
+ }
+
+ &.disabled,
+ &.old,
+ &.new {
+ color: hsl(0,0%,33%);
+ }
+
+ &.today {
+ background: hsl(240,10%,14%);
+ }
+
+ &.focused {
+ box-shadow: 0 0 0 1px hsl(207,82%,64%) inset;
+ }
+
+ &.active {
+ color: white;
+ background: hsl(207,82%,64%);
+ }
+ }
+
+ .today {
+ text-align: center;
+ padding: 0;
+ cursor: pointer;
+
+ &.hidden {
+ display: none;
+ }
+ }
+}
+
/*
----------------