PageSourceSearch

https://sunda.fo/ease/3rdparty/js/Qodio/q.datetator.jquery.js?v=3.22.0.6-8_0

js sunda.fo collected 2026-10-03 00:11:52 UTC 20,256 bytes, 545 lines download raw bytes

1/*
2 Datetator jQuery Plugin
3 Datetator is a jQuery-based replacement for input boxes, making them date pickers.
4 version 1.2, Dec 11th, 2015
5 by Ingi á Steinamørk
6
7 The MIT License (MIT)
8
9 Copyright (c) 2014 QODIO
10
11 Permission is hereby granted, free of charge, to any person obtaining a copy of
12 this software and associated documentation files (the "Software"), to deal in
13 the Software without restriction, including without limitation the rights to
14 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
15 the Software, and to permit persons to whom the Software is furnished to do so,
16 subject to the following conditions:
17
18 The above copyright notice and this permission notice shall be included in all
19 copies or substantial portions of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
24 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
25 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 */
28
29(function($) {
30	/**
31	 * Datetator
32	 * @param element
33	 * @param options
34	 */
35	$.datetator = function (element, options) {
36		//// ================== SETTINGS ================== ////
37		var defaults = {
38			prefix: 'datetator_',
39			height: 'auto',
40			useDimmer: false,
41			useRemove: true,
42			class: '',
43			language: 'en',
44			labels: {
45				en: {
46					week: 'Wk',
47					dayNames: [
48						'Mo',
49						'Tu',
50						'We',
51						'Th',
52						'Fr',
53						'Sa',
54						'Su'
55					],
56					monthNames: [
57						'January',
58					    'February',
59					    'March',
60					    'April',
61					    'May',
62					    'June',
63					    'July',
64					    'August',
65					    'September',
66					    'October',
67					    'November',
68					    'December'
69					],
70					previousMonth: '«',
71					nextMonth: '»',
72					previousYear: '«',
73					nextYear: '»',
74					empty: 'Remove',
75					today: 'Today',
76					previousMonthTooltip: 'Show previous month',
77					nextMonthTooltip: 'Show next month',
78					previousYearTooltip: 'Show previous year',
79					nextYearTooltip: 'Show next year',
80					emptyTooltip: 'Remove date',
81					todayTooltip: 'Show and choose today\'s date'
82				}
83			}
84		};
85
86		//// ================== PREPARE VARIABLES ================== ////
87		var plugin = this;
88		var $element = $(element);
89		var $holder_element = null;
90		var $input_element = null;
91		var $picker_element = null;
92		var reloadDate = function () {
93			if (!isNaN(new Date($element.val()).getDate())) {
94				return new Date(new Date($element.val()).getFullYear(), new Date($element.val()).getMonth(), 1, 0, 0, 0);
95			} else {
96				return new Date(new Date().getFullYear(), new Date().getMonth(), 1, 0, 0, 0);
97			}
98		};
99		var currentDate = reloadDate();
100		/* For use later when adding support for keyboard
101		var key = {
102			backspace: 8,
103			enter: 13,
104			escape: 27,
105			left: 37,
106			up: 38,
107			right: 39,
108			down: 40
109		};*/
110		plugin.settings = {};
111
112
113
114		//// ================== "INITIALIZE PLUGIN" METHOD ================== ////
115		plugin.init = function () {
116			if (typeof datetator_labels !== 'undefined') {
117				$.extend(defaults.labels, datetator_labels);
118			}
119			plugin.settings = $.extend({}, defaults, options);
120
121			//// CREATE ELEMENTS
122			// dimmer
123			if (plugin.settings.useDimmer) {
124				if ($('#' + plugin.settings.prefix + 'dimmer').length === 0) {
125					var dimmer_element = document.createElement('div');
126					$(dimmer_element).attr('id', plugin.settings.prefix + 'dimmer');
127					$(dimmer_element).hide();
128					$(document.body).prepend(dimmer_element);
129				}
130			}
131			// holder element
132			$holder_element = $(document.createElement('div'));
133			$holder_element.addClass(plugin.settings.prefix + 'holder picker-hidden');
134			$holder_element.css({
135				display: $element.css('display')
136			});
137			$element.after($holder_element);
138			
139			// input element
140			$input_element = $(document.createElement('input'));
141			$input_element.attr('type', 'text');
142			if (element.id !== undefined) {
143				$input_element.attr('id', plugin.settings.prefix + element.id);
144			}
145			if (element.hasAttribute('tabindex')) {
146				$input_element.attr('tabindex', $element.attr('tabindex'));
147			}
148			if (element.hasAttribute('placeholder')) {
149				$input_element.attr('placeholder', $element.attr('placeholder'));
150			}
151			$input_element.addClass(plugin.settings.prefix + 'element picker-hidden ' + plugin.settings.class);
152			$input_element.css({
153				width: $element.css('width'),
154				padding: $element.css('padding'),
155				position: 'relative'
156			});
157			$input_element.attr('readonly', true);
158			if (plugin.settings.height === 'element') {
159				$input_element.css({
160					height: $element.outerHeight() + 'px'
161				});
162			}
163			$holder_element.append($input_element);
164			$element.hide();
165
166			// picker element
167			$picker_element = $(document.createElement('div'));
168			$picker_element.addClass(plugin.settings.prefix + 'picker');
169			$holder_element.append($picker_element);
170
171			//// BIND ELEMENTS EVENTS
172			// source element
173			$element.on('change', function () {
174				currentDate = reloadDate();
175				refreshPicker();
176			});
177			$input_element.on('mouseup', function (e) {
178				e.preventDefault();
179				e.stopPropagation();
180				$input_element.trigger('focus');
181			});
182			$input_element.focus(function () {
183				currentDate = reloadDate();
184				refreshPicker();
185				//$input_element.select();
186			});
187			$input_element.blur(function () {
188				hidePicker();
189			});
190			refreshPicker();
191		};
192
193		
194		//// ================== "REFRESH PICKER" METHOD ================== ////
195		plugin.changeSetting = function (settingToChange, change) {
196			plugin.settings['settingToChange'] = change;
197		};
198		plugin.refresh = function () {
199			refreshPicker();
200		};
201		var refreshPicker = function () {
202			$input_element.val(formatDate(new Date($element.val()), 2));
203
204			$picker_element.empty();
205			$picker_element.on('mousedown', function (e) {
206				e.preventDefault();
207				e.stopPropagation();
208			});
209
210			// NAVIGATION HOLDER
211			var $nav_element = $(document.createElement('div'));
212			$nav_element.addClass(plugin.settings.prefix + 'navigation');
213			$picker_element.append($nav_element);
214			
215			// LINE 1
216			// previous month button
217			var $nav_prev_month_element = $(document.createElement('div'));
218			$nav_prev_month_element.addClass(plugin.settings.prefix + 'button');
219			$nav_prev_month_element.addClass(plugin.settings.prefix + 'previous_month');
220			$nav_prev_month_element.html(plugin.settings.labels[plugin.settings.language].previousMonth.replace('{month}', plugin.settings.labels[plugin.settings.language].monthNames[new Date(new Date(currentDate).setMonth(currentDate.getMonth() - 1)).getMonth()].substring(0, 3)));
221			$nav_prev_month_element.attr('title', plugin.settings.labels[plugin.settings.language].previousMonthTooltip);
222			$nav_prev_month_element.on('click', function (e) {
223				e.preventDefault();
224				e.stopPropagation();
225				previousMonth();
226			});
227			$nav_element.append($nav_prev_month_element);
228			// month holder
229			var $nav_month_element = $(document.createElement('div'));
230			$nav_month_element.addClass(plugin.settings.prefix + 'month');
231			$nav_month_element.html(plugin.settings.labels[plugin.settings.language].monthNames[currentDate.getMonth()]);
232			$nav_element.append($nav_month_element);
233			// next month button
234			var $nav_next_month_element = $(document.createElement('div'));
235			$nav_next_month_element.addClass(plugin.settings.prefix + 'button');
236			$nav_next_month_element.addClass(plugin.settings.prefix + 'next_month');
237			$nav_next_month_element.html(plugin.settings.labels[plugin.settings.language].nextMonth.replace('{month}', plugin.settings.labels[plugin.settings.language].monthNames[new Date(new Date(currentDate).setMonth(currentDate.getMonth() + 1)).getMonth()].substring(0, 3)));
238			$nav_next_month_element.attr('title', plugin.settings.labels[plugin.settings.language].nextMonthTooltip);
239			$nav_next_month_element.on('click', function (e) {
240				e.preventDefault();
241				e.stopPropagation();
242				nextMonth();
243			});
244			$nav_element.append($nav_next_month_element);
245
246			// LINE 2
247			// previous year button
248			var $nav_prev_year_element = $(document.createElement('div'));
249			$nav_prev_year_element.addClass(plugin.settings.prefix + 'button');
250			$nav_prev_year_element.addClass(plugin.settings.prefix + 'previous_year');
251			$nav_prev_year_element.html(plugin.settings.labels[plugin.settings.language].previousYear.replace('{year}', new Date(new Date(currentDate).setYear(currentDate.getFullYear() - 1)).getFullYear().toString()));
252			$nav_prev_year_element.attr('title', plugin.settings.labels[plugin.settings.language].previousYearTooltip);
253			$nav_prev_year_element.on('click', function (e) {
254				e.preventDefault();
255				e.stopPropagation();
256				previousYear();
257			});
258			$nav_element.append($nav_prev_year_element);
259			// year holder
260			var $nav_year_element = $(document.createElement('div'));
261			$nav_year_element.addClass(plugin.settings.prefix + 'year');
262			$nav_year_element.html(currentDate.getFullYear());
263			$nav_element.append($nav_year_element);
264			// next year button
265			var $nav_next_year_element = $(document.createElement('div'));
266			$nav_next_year_element.addClass(plugin.settings.prefix + 'button');
267			$nav_next_year_element.addClass(plugin.settings.prefix + 'next_year');
268			$nav_next_year_element.html(plugin.settings.labels[plugin.settings.language].nextYear.replace('{year}', new Date(new Date(currentDate).setYear(currentDate.getFullYear() + 1)).getFullYear().toString()));
269			$nav_next_year_element.attr('title', plugin.settings.labels[plugin.settings.language].nextYearTooltip);
270			$nav_next_year_element.on('click', function (e) {
271				e.preventDefault();
272				e.stopPropagation();
273				nextYear();
274			});
275			$nav_element.append($nav_next_year_element);
276
277			// CALENDAR HOLDER
278			var $calendar_element = $(document.createElement('table'));
279			$calendar_element.addClass(plugin.settings.prefix + 'calendar');
280			$picker_element.append($calendar_element);
281			// tr element (header)
282			var $calendar_tr_element = $(document.createElement('tr'));
283			$calendar_element.append($calendar_tr_element);
284			// td element (week header)
285			var $calendar_td_element = $(document.createElement('th'));
286			$calendar_td_element.addClass(plugin.settings.prefix + 'week_header');
287			$calendar_td_element.html(plugin.settings.labels[plugin.settings.language].week);
288			$calendar_tr_element.append($calendar_td_element);
289			for (var i = 0; i < 7; i++) {
290				// td element (day header)
291				$calendar_td_element = $(document.createElement('th'));
292				$calendar_td_element.addClass(plugin.settings.prefix + 'day_header');
293				$calendar_td_element.html(plugin.settings.labels[plugin.settings.language].dayNames[i]);
294				$calendar_tr_element.append($calendar_td_element);
295			}
296
297			// DATES
298			var firstDayOfMonth = currentDate;
299			var lastDayOfMonth = new Date(currentDate.getFullYear(), currentDate.getMonth() + 1, currentDate.getDate() - 1);
300			var firstWeekAndYear = getWeekAndYear(firstDayOfMonth);
301			var lastWeekAndYear = getWeekAndYear(lastDayOfMonth);
302			var mondayFirstWeek = getDateOfISOWeek(firstWeekAndYear.week, firstWeekAndYear.year);
303			var sundayLastWeek = getDateOfISOWeek(lastWeekAndYear.week, lastWeekAndYear.year, 6);
304			var initDate = new Date();
305
306			var rows = Math.ceil((getDateDifferenceInDays(mondayFirstWeek, sundayLastWeek)) / 7);
307			for (var row = 0; row < rows; row++) {
308				// tr element
309				var $tr_element = $(document.createElement('tr'));
310				$calendar_element.append($tr_element);
311				// td element (week)
312				var $td_element = $(document.createElement('td'));
313				$td_element.addClass(plugin.settings.prefix + 'week');
314				$td_element.html(getWeekAndYear(new Date(firstDayOfMonth).setDate(firstDayOfMonth.getDate() + (row * 7))).week);
315				$tr_element.append($td_element);
316				for (var x = 0; x < 7; x++) {
317					// td element (day)
318					$td_element = $(document.createElement('td'));
319					var date = new Date(mondayFirstWeek.getFullYear(), mondayFirstWeek.getMonth(), mondayFirstWeek.getDate() + (x + (row * 7)));
320					$td_element.html(date.getDate());
321					$td_element.data('date', date);
322					$td_element.on('click', function () {
323						selectDate($(this).data('date'));
324					});
325					$td_element.addClass(plugin.settings.prefix + 'day');
326					if (formatDate(date, 0) === $element.val()) {
327						$td_element.addClass(plugin.settings.prefix + 'day_active');
328					}
329					if (date < firstDayOfMonth || date > lastDayOfMonth) {
330						$td_element.addClass(plugin.settings.prefix + 'day_other');
331					}
332					if (date.getDay() === 0 || date.getDay() === 6) {
333						$td_element.addClass(plugin.settings.prefix + 'day_weekend');
334					}
335					if (date.toDateString() === initDate.toDateString()) {
336						$td_element.addClass(plugin.settings.prefix + 'day_today');
337					}
338					$tr_element.append($td_element);
339				}
340			}
341			
342			// operations holder
343			var $operations_element = $(document.createElement('div'));
344			$operations_element.addClass(plugin.settings.prefix + 'operations');
345			$picker_element.append($operations_element);
346			// "remove" button
347			if (plugin.settings.useRemove) {
348				var $opr_delete_element = $(document.createElement('div'));
349				$opr_delete_element.addClass(plugin.settings.prefix + 'button');
350				$opr_delete_element.addClass(plugin.settings.prefix + 'empty');
351				$opr_delete_element.html(plugin.settings.labels[plugin.settings.language].empty);
352				$opr_delete_element.attr('title', plugin.settings.labels[plugin.settings.language].emptyTooltip);
353				$opr_delete_element.on('click', function (e) {
354					e.preventDefault();
355					e.stopPropagation();
356					empty();
357				});
358				$operations_element.append($opr_delete_element);
359			}
360			// "today" button
361			var $opr_today_element = $(document.createElement('div'));
362			$opr_today_element.addClass(plugin.settings.prefix + 'button');
363			$opr_today_element.addClass(plugin.settings.prefix + 'today');
364			$opr_today_element.html(plugin.settings.labels[plugin.settings.language].today);
365			$opr_today_element.attr('title', plugin.settings.labels[plugin.settings.language].todayTooltip);
366			$opr_today_element.on('click', function (e) {
367				e.preventDefault();
368				e.stopPropagation();
369				today();
370			});
371			$operations_element.append($opr_today_element);
372
373			if (document.activeElement === $input_element[0]) {
374				showPicker();
375			}
376
377			// place popup
378 			if (($holder_element[0].getBoundingClientRect().bottom + 250) < Math.max(document.documentElement.clientHeight, window.innerHeight || 0)) {
379			    $picker_element.css({
380				    top: $input_element.outerHeight() + 3,
381				    bottom: 'auto'
382			    });
383			} else {
384			    $picker_element.css({
385				    top: 'auto',
386				    bottom: $input_element.outerHeight() + 3
387			    });
388		    }
389
390		};
391
392		
393		//// ================== DATE CHOOSING METHODS ================== ////
394		var today = function () {
395			currentDate.setYear(new Date().getFullYear());
396			currentDate.setMonth(new Date().getMonth());
397			$element.val(formatDate(new Date(), 0));
398			$element.trigger('change');
399			hidePicker();
400		};
401
402		var previousMonth = function () {
403			currentDate.setMonth(currentDate.getMonth() - 1);
404			refreshPicker();
405		};
406		var nextMonth = function () {
407			currentDate.setMonth(currentDate.getMonth() + 1);
408			refreshPicker();
409		};
410		
411		var previousYear = function () {
412			currentDate.setYear(currentDate.getFullYear() - 1);
413			refreshPicker();
414		};
415		var nextYear = function () {
416			currentDate.setYear(currentDate.getFullYear() + 1);
417			refreshPicker();
418		};
419		
420		var selectDate = function (date) {
421			$element.val(formatDate(date, 0));
422			$element.trigger('change');
423			hidePicker();
424		};
425
426		
427		//// ================== OTHER METHODS ================== ////
428		var empty = function () {
429			$element.val('');
430			$element.trigger('change');
431			hidePicker();
432		};
433
434		var showPicker = function () {
435			$holder_element.removeClass('picker-hidden').addClass('picker-visible');
436			if (plugin.settings.useDimmer) {
437				$('#' + plugin.settings.prefix + 'dimmer').show();
438			}
439		};
440		
441		var hidePicker = function () {
442			$holder_element.removeClass('picker-visible').addClass('picker-hidden');
443			if (plugin.settings.useDimmer) {
444				$('#' + plugin.settings.prefix + 'dimmer').hide();
445			}
446		};
447
448		var formatDate = function (date, type) {
449			type = type !== undefined ? type : 1;
450			date = typeof date === 'object' ? date : new Date(date);
451			if (isNaN(date.getDate())) {
452				return '';
453			}
454			var day = date.getDate();
455			var month = date.getMonth() + 1;
456			var year = date.getFullYear();
457			switch (type) {
458				case 0:
459					return year + '-' + (month > 9 ? month : '0' + month) + '-' + (day > 9 ? day : '0' + day);
460					break;
461				case 1:
462					return (day > 9 ? day : '0' + day) + '-' + (month > 9 ? month : '0' + month) + '-' + year;
463					break;
464				case 2:
465					return day + '. ' + plugin.settings.labels[plugin.settings.language].monthNames[month - 1] + ' ' + year;
466					break;
467				case 3:
468					return day + '. ' + plugin.settings.labels[plugin.settings.language].monthNames[month - 1].substring(0, 3) + '. ' + year;
469					break;
470			}
471			return 'Invalid Type';
472		};
473
474		var getWeekAndYear = function(date) {
475			date = new Date(date);
476			date.setHours(0,0,0);
477			date.setDate(date.getDate() + 4 - (date.getDay() || 7));
478			var yearStart = new Date(date.getFullYear(), 0, 1);
479			var weekNo = Math.ceil((((date - yearStart) / 86400000) + 1) / 7);
480			return { week: weekNo, year: date.getFullYear() };
481		};
482
483		var getDateOfISOWeek = function(week, year, weekDay) {
484			weekDay = weekDay ? weekDay : 0;
485			var simple = new Date(year, 0, 1 + (week - 1) * 7);
486			var date =  new Date(simple.setDate((simple.getDay() <= 4) ? (simple.getDate() - simple.getDay() + 1) : (simple.getDate() + 8 - simple.getDay())));
487			return new Date(date.setDate(date.getDate() + weekDay));
488		};
489
490		var getDateDifferenceInDays = function (date1, date2) {
491			var dayMs = 24 * 60 * 60 * 1000;
492			var utc1 = Date.UTC(date1.getFullYear(), date1.getMonth(), date1.getDate());
493			var utc2 = Date.UTC(date2.getFullYear(), date2.getMonth(), date2.getDate());
494			return Math.floor((utc2 - utc1) / dayMs);
495		};
496
497
498		//// ================== "DESTROY" METHOD ================== ////
499		plugin.destroy = function () {
500			$input_element.remove();
501			$.removeData(element, 'datetator');
502			$element.unbind('change', refreshPicker);
503			$element.show();
504			if ($('.datetator').length === 0) {
505				$('#' + plugin.settings.prefix + 'dimmer').remove();
506			}
507		};
508
509		
510		//// ================== INITIALIZE PLUGIN ================== ////
511		plugin.init();
512	};
513
514	
515	//// ================== INSTANTIATE PLUGIN METHOD ================== ////
516	$.fn.datetator = function(options) {
517		options = options !== undefined ? options : {};
518		return this.each(function () {
519			if (typeof(options) === 'object') {
520				if ($(this).data('datetator') === undefined) {
521					var plugin = new $.datetator(this, options);
522					$(this).data('datetator', plugin);
523				}
524			} else if (typeof $(this).data('datetator') !== 'undefined' && $(this).data('datetator')[options]) {
525				$(this).data('datetator')[options].apply(this, Array.prototype.slice.call(arguments, 1));
526			} else {
527				//$.error('Method ' + options + ' does not exist in $.datetator');
528			}
529		});
530	};
531
532}(jQuery));
533
534$(function () {
535	$('.datetator').each(function () {
536		var $this = $(this);
537		var options = {};
538		$.each($this.data(), function (key, value) {
539			if (key.substring(0, 9) === 'datetator') {
540				options[key.substring(9, 10).toLowerCase() + key.substring(10)] = value;
541			}
542		});
543		$this.datetator(options);
544	});
545});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.