PageSourceSearch

https://uniklinika.ru/bitrix/js/main/core/core_date.js

js uniklinika.ru collected 2026-09-28 08:54:49 UTC 36,251 bytes, 1,453 lines download raw bytes

1;(function(){
2
3if (BX.date)
4	return;
5
6BX.date = BX.Main.Date;
7
8/************************************** calendar class **********************************/
9
10var obCalendarSingleton = null;
11
12/*
13params: {
14	node: bind element || document.body
15
16	value - start value in site format (using 'field' param if 'value' does not exist)
17	callback - date check handler. can return false to prevent calendar closing.
18	callback_after - another handler, called after date picking
19
20	field - field to read/write data
21
22	bTime = true - whether to enable time control
23	bHideTime = false - whether to hide time control by default
24
25	currentTime - current UTC time()
26
27}
28*/
29
30
31BX.calendar = function(params)
32{
33	return BX.calendar.get().Show(params);
34};
35
36BX.calendar.get = function()
37{
38	if (!obCalendarSingleton)
39		obCalendarSingleton = new BX.JCCalendar();
40
41	return obCalendarSingleton;
42};
43
44// simple func for compatibility with the oldies
45BX.calendar.InsertDaysBack = function(input, days)
46{
47	if (days != '')
48	{
49		var d = new Date();
50		if(days > 0)
51		{
52			d.setTime(d.valueOf() - days*86400000);
53		}
54
55		input.value = BX.date.format(BX.date.convertBitrixFormat(BX.message('FORMAT_DATE')), d, null);
56	}
57	else
58	{
59		input.value = '';
60	}
61};
62
63BX.calendar.ValueToString = function(value, bTime, bUTC)
64{
65	return BX.date.format(
66		BX.date.convertBitrixFormat(BX.message(bTime ? 'FORMAT_DATETIME' : 'FORMAT_DATE')),
67		value,
68		null,
69		!!bUTC
70	);
71};
72
73BX.calendar.ValueToStringFormat = function(value, bitrixFormat, bUTC)
74{
75	return BX.date.format(
76		BX.date.convertBitrixFormat(bitrixFormat),
77		value,
78		null,
79		!!bUTC
80	);
81};
82
83
84BX.CalendarPeriod =
85{
86	Init: function(inputFrom, inputTo, selPeriod)
87	{
88		if((inputFrom.value != "" || inputTo.value != "") && selPeriod.value == "")
89			selPeriod.value = "interval";
90
91		selPeriod.onchange();
92	},
93
94	ChangeDirectOpts: function(peroidValue, selPParent) // "week" || "others"
95	{
96		var selDirect = BX.findChild(selPParent, {'className':'adm-select adm-calendar-direction'}, true);
97
98		if(peroidValue == "week")
99		{
100			selDirect.options[0].text = BX.message('JSADM_CALEND_PREV_WEEK');
101			selDirect.options[1].text = BX.message('JSADM_CALEND_CURR_WEEK');
102			selDirect.options[2].text = BX.message('JSADM_CALEND_NEXT_WEEK');
103		}
104		else
105		{
106			selDirect.options[0].text = BX.message('JSADM_CALEND_PREV');
107			selDirect.options[1].text = BX.message('JSADM_CALEND_CURR');
108			selDirect.options[2].text = BX.message('JSADM_CALEND_NEXT');
109		}
110	},
111
112	SaveAndClearInput: function(oInput)
113	{
114		if(!window.SavedPeriodValues)
115			window.SavedPeriodValues = {};
116
117		window.SavedPeriodValues[oInput.id] = oInput.value;
118		oInput.value="";
119	},
120
121	RestoreInput: function(oInput)
122	{
123		if(!window.SavedPeriodValues || !window.SavedPeriodValues[oInput.id])
124			return;
125
126		oInput.value = window.SavedPeriodValues[oInput.id];
127		delete(window.SavedPeriodValues[oInput.id]);
128	},
129
130	OnChangeP: function(sel)
131	{
132		var selPParent = sel.parentNode.parentNode;
133		var bShowFrom, bShowTo, bShowDirect, bShowSeparate;
134		bShowFrom = bShowTo = bShowDirect = bShowSeparate = false;
135
136		var inputFromWrap = BX.findChild(selPParent, {'className':'adm-input-wrap adm-calendar-inp adm-calendar-first'});
137		var inputToWrap = BX.findChild(selPParent, {'className':'adm-input-wrap adm-calendar-second'});
138		var selDirectWrap = BX.findChild(selPParent, {'className':'adm-select-wrap adm-calendar-direction'});
139		var separator = BX.findChild(selPParent, {'className':'adm-calendar-separate'});
140		var inputFrom = BX.findChild(selPParent, {'className':'adm-input adm-calendar-from'},true);
141		var inputTo = BX.findChild(selPParent, {'className':'adm-input adm-calendar-to'},true);
142
143		// define who must be shown
144		switch (sel.value)
145		{
146			case "day":
147			case "week":
148			case "month":
149			case "quarter":
150			case "year":
151				bShowDirect=true;
152				BX.CalendarPeriod.OnChangeD(selDirectWrap.children[0]);
153				break;
154
155			case "before":
156				bShowTo = true;
157				break;
158
159			case "after":
160				bShowFrom = true;
161				break;
162
163			case "exact":
164				bShowFrom= true;
165				break;
166
167			case "interval":
168				bShowFrom = bShowTo = bShowSeparate = true;
169				BX.CalendarPeriod.RestoreInput(inputFrom);
170				BX.CalendarPeriod.RestoreInput(inputTo);
171
172				break;
173
174			case "":
175				BX.CalendarPeriod.SaveAndClearInput(inputFrom);
176				BX.CalendarPeriod.SaveAndClearInput(inputTo);
177				break;
178
179			default:
180				break;
181
182		}
183
184		BX.CalendarPeriod.ChangeDirectOpts(sel.value, selPParent);
185
186		inputFromWrap.style.display = (bShowFrom? 'inline-block':'none');
187		inputToWrap.style.display = (bShowTo? 'inline-block':'none');
188		selDirectWrap.style.display = (bShowDirect? 'inline-block':'none');
189		separator.style.display = (bShowSeparate? 'inline-block':'none');
190	},
191
192
193	OnChangeD: function(sel)
194	{
195		var selPParent = sel.parentNode.parentNode;
196		var inputFrom = BX.findChild(selPParent, {'className':'adm-input adm-calendar-from'},true);
197		var inputTo = BX.findChild(selPParent, {'className':'adm-input adm-calendar-to'},true);
198		var selPeriod = BX.findChild(selPParent, {'className':'adm-select adm-calendar-period'},true);
199
200		var offset=0;
201
202		switch (sel.value)
203		{
204			case "previous":
205				offset = -1;
206				break;
207
208			case "next":
209				offset = 1;
210				break;
211
212			case "current":
213			default:
214				break;
215
216		}
217
218		var from = false;
219		var to = false;
220
221		var today = new Date();
222		var year = today.getFullYear();
223		var month = today.getMonth();
224		var day = today.getDate();
225		var dayW = today.getDay();
226
227		if (dayW == 0)
228				dayW = 7;
229
230		switch (selPeriod.value)
231		{
232			case "day":
233				from = new Date(year, month, day+offset, 0, 0, 0);
234				to = new Date(year, month, day+offset, 23, 59, 59);
235				break;
236
237			case "week":
238				from = new Date(year, month, day-dayW+1+offset*7, 0, 0, 0);
239				to = new Date(year, month, day+(7-dayW)+offset*7, 23, 59, 59);
240				break;
241
242			case "month":
243				from = new Date(year, month+offset, 1, 0, 0, 0);
244				to = new Date(year, month+1+offset, 0, 23, 59, 59);
245				break;
246
247			case "quarter":
248				var quarterNum = Math.floor((month/3))+offset;
249				from = new Date(year, 3*(quarterNum), 1, 0, 0, 0);
250				to = new Date(year, 3*(quarterNum+1), 0, 23, 59, 59);
251				break;
252
253			case "year":
254				from = new Date(year+offset, 0, 1, 0, 0, 0);
255				to = new Date(year+1+offset, 0, 0, 23, 59, 59);
256				break;
257
258			default:
259				break;
260		}
261
262		var format = window[inputFrom.name+"_bTime"] ? BX.message('FORMAT_DATETIME') : BX.message('FORMAT_DATE');
263
264		if(from)
265		{
266			inputFrom.value = BX.formatDate(from, format);
267			BX.addClass(inputFrom,"adm-calendar-inp-setted");
268		}
269
270		if(to)
271		{
272			inputTo.value = BX.formatDate(to, format);
273			BX.addClass(inputTo,"adm-calendar-inp-setted");
274		}
275	}
276};
277
278
279BX.JCCalendar = function()
280{
281	this.params = {};
282
283	this.bAmPm = BX.isAmPmMode();
284
285	this.popup = null;
286	this.popup_month = null;
287	this.popup_year = null;
288	this.month_popup_classname = '';
289	this.year_popup_classname = '';
290	this.value = null;
291	this._layers = {};
292	this._current_layer = null;
293
294	this.DIV = null;
295	this.PARTS = {};
296
297	this.weekStart = 0;
298	this.numRows = 6;
299
300	this._create = function(params)
301	{
302		const paramsForPopupWindow = {
303			closeByEsc: true,
304			autoHide: false,
305			content: this._get_content(),
306			bindOptions: { forceBindPosition: true },
307		};
308		if (Boolean(params.fixed) && params.fixed)
309		{
310			paramsForPopupWindow.fixed = params.fixed;
311		}
312
313		this.popup = new BX.PopupWindow(
314			'calendar_popup_' + Math.random(),
315			params.node,
316			paramsForPopupWindow,
317		);
318
319		BX.bind(this.popup.popupContainer, 'click', function(event) {
320			event.stopPropagation();
321		});
322	};
323
324	this._auto_hide_disable = function()
325	{
326		BX.unbind(document, 'click', BX.proxy(this._auto_hide, this));
327	};
328
329	this._auto_hide_enable = function()
330	{
331		BX.bind(document, 'click', BX.proxy(this._auto_hide, this));
332	};
333
334	this._auto_hide = function(e)
335	{
336		this._auto_hide_disable();
337		this.popup.close();
338	};
339
340	this._get_content = function()
341	{
342		var _layer_onclick = BX.delegate(function(e) {
343			e = e||window.event;
344			this.SetDate(
345				new Date(parseInt(BX.proxy_context.getAttribute('data-date'))),
346				(e.type === 'dblclick' || (this.params.bCompatibility && !this.params.bTimeVisibility))
347			)
348		}, this);
349
350		this.DIV = BX.create('DIV', {
351			props: {className: 'bx-calendar'},
352			children: [
353				BX.create('DIV', {
354					props: {
355						className: 'bx-calendar-header'
356					},
357					children: [
358						BX.create('A', {
359							attrs: {href: 'javascript:void(0)'},
360							props: {className: 'bx-calendar-left-arrow'},
361							events: {click: BX.proxy(this._prev, this)}
362						}),
363
364						BX.create('SPAN', {
365							props: {className: 'bx-calendar-header-content'},
366							children: [
367								(this.PARTS.MONTH = BX.create('A', {
368									attrs: {href: 'javascript:void(0)'},
369									props: {className: 'bx-calendar-top-month'},
370									events: {click: BX.proxy(this._menu_month, this)}
371								})),
372
373								(this.PARTS.YEAR = BX.create('A', {
374									attrs: {href: 'javascript:void(0)'},
375									props: {className: 'bx-calendar-top-year'},
376									events: {click: BX.proxy(this._menu_year, this)}
377								}))
378							]
379						}),
380
381						BX.create('A', {
382							attrs: {href: 'javascript:void(0)'},
383							props: {className: 'bx-calendar-right-arrow'},
384							events: {click: BX.proxy(this._next, this)}
385						})
386					]
387				}),
388
389				(this.PARTS.WEEK = BX.create('DIV', {
390					props: {
391						className: 'bx-calendar-name-day-wrap'
392					}
393				})),
394
395				(this.PARTS.LAYERS = BX.create('DIV', {
396					props: {
397						className: 'bx-calendar-cell-block'
398					},
399					events: {
400						click: BX.delegateEvent({className: 'bx-calendar-cell'}, _layer_onclick),
401						dblclick: BX.delegateEvent({className: 'bx-calendar-cell'}, _layer_onclick)
402					}
403				})),
404
405				(this.PARTS.TIME = BX.create('DIV', {
406					props: {
407						className: 'bx-calendar-set-time-wrap'
408					},
409					events: {
410						click: BX.delegateEvent(
411							{attr: 'data-action'},
412							BX.delegate(this._time_actions, this)
413						)
414					},
415					html: '<a href="javascript:void(0)" data-action="time_show" class="bx-calendar-set-time"><i></i>'+BX.message('CAL_TIME_SET')+'</a><div class="bx-calendar-form-block"><span class="bx-calendar-form-text">'+BX.message('CAL_TIME')+'</span><span class="bx-calendar-form"><input type="text" class="bx-calendar-form-input" maxwidth="2" onkeyup="BX.calendar.get()._check_time()" /><span class="bx-calendar-form-separator"></span><input type="text" class="bx-calendar-form-input" maxwidth="2" onkeyup="BX.calendar.get()._check_time()" />'+(this.bAmPm?'<span class="bx-calendar-AM-PM-block"><span class="bx-calendar-AM-PM-text" data-action="time_ampm"></span><span class="bx-calendar-form-arrow-r"><a href="javascript:void(0)" class="bx-calendar-form-arrow-top" data-action="time_ampm_up"><i></i></a><a href="javascript:void(0)" class="bx-calendar-form-arrow-bottom" data-action="time_ampm_down"><i></i></a></span></span>':'')+'</span><a href="javascript:void(0)" data-action="time_hide" class="bx-calendar-form-close"><i></i></a></div>'
416				})),
417
418				(this.PARTS.BUTTONS = BX.create('DIV', {
419					props: {className: 'bx-calendar-button-block'},
420					events: {
421						click: BX.delegateEvent(
422							{attr: 'data-action'},
423							BX.delegate(this._button_actions, this)
424						)
425					},
426					html: '<a href="javascript:void(0)" class="bx-calendar-button bx-calendar-button-select" data-action="submit"><span class="bx-calendar-button-left"></span><span class="bx-calendar-button-text">'+BX.message('CAL_BUTTON')+'</span><span class="bx-calendar-button-right"></span></a><a href="javascript:void(0)" class="bx-calendar-button bx-calendar-button-cancel" data-action="cancel"><span class="bx-calendar-button-left"></span><span class="bx-calendar-button-text">'+BX.message('JS_CORE_WINDOW_CLOSE')+'</span><span class="bx-calendar-button-right"></span></a>'
427				}))
428			]
429		});
430
431		this.PARTS.TIME_INPUT_H = BX.findChild(this.PARTS.TIME, {tag: 'INPUT'}, true);
432		this.PARTS.TIME_INPUT_M = this.PARTS.TIME_INPUT_H.nextSibling.nextSibling;
433
434		if (this.bAmPm)
435			this.PARTS.TIME_AMPM = this.PARTS.TIME_INPUT_M.nextSibling.firstChild;
436
437		var spinner = (new BX.JCSpinner({
438			input: this.PARTS.TIME_INPUT_H,
439			callback_change: BX.proxy(this._check_time, this),
440			bSaveValue: false
441		})).Show();
442		spinner.className = 'bx-calendar-form-arrow-l';
443		this.PARTS.TIME_INPUT_H.parentNode.insertBefore(spinner, this.PARTS.TIME_INPUT_H);
444
445		spinner = (new BX.JCSpinner({
446			input: this.PARTS.TIME_INPUT_M,
447			callback_change: BX.proxy(this._check_time, this),
448			bSaveValue: true
449		})).Show();
450		spinner.className = 'bx-calendar-form-arrow-r';
451		if (!this.PARTS.TIME_INPUT_M.nextSibling)
452			this.PARTS.TIME_INPUT_M.parentNode.appendChild(spinner);
453		else
454			this.PARTS.TIME_INPUT_M.parentNode.insertBefore(spinner, this.PARTS.TIME_INPUT_M.nextSibling);
455
456		for (var i = 0; i < 7; i++)
457		{
458			this.PARTS.WEEK.appendChild(BX.create('SPAN', {
459				props: {
460					className: 'bx-calendar-name-day'
461				},
462				text: BX.message('DOW_' + ((i + this.weekStart) % 7))
463			}));
464		}
465
466		return this.DIV;
467	};
468
469	this._time_actions = function()
470	{
471		switch (BX.proxy_context.getAttribute('data-action'))
472		{
473			case 'time_show':
474				BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
475				if (this.params.bCompatibility)
476				{
477					BX.removeClass(this.PARTS.BUTTONS, 'bx-calendar-buttons-disabled');
478				}
479				this.popup.adjustPosition();
480			break;
481			case 'time_hide':
482				BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
483				if (this.params.bCompatibility)
484				{
485					this._saveChoice('hide');
486					BX.addClass(this.PARTS.BUTTONS, 'bx-calendar-buttons-disabled');
487				}
488				this.popup.adjustPosition();
489			break;
490			case 'time_ampm':
491				this.PARTS.TIME_AMPM.innerHTML = this.PARTS.TIME_AMPM.innerHTML == 'AM' ? 'PM' : 'AM';
492			break;
493			case 'time_ampm_up':
494				this._check_time({bSaveValue: false}, null, 12);
495				return;
496			break;
497			case 'time_ampm_down':
498				this._check_time({bSaveValue: false}, null, -12);
499				return;
500			break;
501		}
502
503		this._check_time();
504	};
505
506	this._button_actions = function()
507	{
508		switch (BX.proxy_context.getAttribute('data-action'))
509		{
510			case 'submit':
511				if (this.params.bCompatibility)
512				{
513					this._saveChoice('show');
514				}
515				this.SaveValue();
516			break;
517			case 'cancel':
518				this.Close();
519			break;
520		}
521	};
522
523	this._saveChoice = function(state)
524	{
525		if (this.params.bCategoryTimeVisibilityOption)
526		{
527			BX.userOptions.save(
528				this.params.bCategoryTimeVisibilityOption,
529				this.params.bNameTimeVisibilityOption,
530				'visibility',
531				(state === 'show' ? 'Y' : 'N')
532			);
533		}
534
535		this._bTimeVisibility = (state === 'show');
536		this.params.bTimeVisibility = this._bTimeVisibility;
537	};
538
539	this._check_time = function(params, value, direction)
540	{
541		var h = parseInt(this.PARTS.TIME_INPUT_H.value.substring(0,5),10)||0,
542			m = parseInt(this.PARTS.TIME_INPUT_M.value.substring(0,5),10)||0,
543			bChanged = false;
544
545		if (!!params && !params.bSaveValue)
546		{
547			this.value.setUTCHours(this.value.getUTCHours() + direction);
548		}
549		else if (!isNaN(h))
550		{
551			if (this.bAmPm)
552			{
553				if (h != 12 && this.PARTS.TIME_AMPM.innerHTML == 'PM')
554				{
555					h += 12;
556				}
557			}
558
559			bChanged = true;
560			this.value.setUTCHours(h % 24);
561		}
562
563		if (!isNaN(m))
564		{
565			bChanged = true;
566			this.value.setUTCMinutes(m % 60);
567		}
568
569		if (bChanged)
570		{
571			this.SetValue(this.value);
572		}
573	};
574
575	this._set_layer = function()
576	{
577		var layerId = parseInt(this.value.getUTCFullYear() + '' + BX.util.str_pad_left(this.value.getUTCMonth()+'', 2, "0"));
578
579		if (!this._layers[layerId])
580		{
581			this._layers[layerId] = this._create_layer();
582			this._layers[layerId].BXLAYERID = layerId;
583		}
584
585		if (this._current_layer)
586		{
587			var v = new Date(this.value.valueOf());
588			v.setUTCHours(0); v.setUTCMinutes(0);
589
590			var cur_value = BX.findChild(this._layers[layerId], {
591					tag: 'A',
592					className: 'bx-calendar-active'
593				}, true),
594				new_value = BX.findChild(this._layers[layerId], {
595					tag: 'A',
596					attr: {
597						'data-date' : v.valueOf() + ''
598					}
599				}, true);
600
601			if (cur_value)
602			{
603				BX.removeClass(cur_value, 'bx-calendar-active');
604			}
605
606			if (new_value)
607			{
608				BX.addClass(new_value, 'bx-calendar-active');
609			}
610
611			this._replace_layer(this._current_layer, this._layers[layerId]);
612		}
613		else
614		{
615			this.PARTS.LAYERS.appendChild(this._layers[layerId]);
616		}
617
618		this._current_layer = this._layers[layerId];
619	};
620
621	this._replace_layer = function(old_layer, new_layer)
622	{
623		if (old_layer != new_layer)
624		{
625			if (!BX.browser.IsIE() || BX.browser.IsDoctype())
626			{
627				var dir = old_layer.BXLAYERID > new_layer.BXLAYERID ? 1 : -1;
628
629				var old_top = 0;
630				var new_top = -dir * old_layer.offsetHeight;
631
632				old_layer.style.position = 'relative';
633				old_layer.style.top = "0px";
634				old_layer.style.zIndex = 5;
635
636				new_layer.style.position = 'absolute';
637				new_layer.style.top = new_top + 'px';
638				new_layer.style.zIndex = 6;
639
640				this.PARTS.LAYERS.appendChild(new_layer);
641
642				var delta = 15;
643
644				var f;
645				(f = function() {
646					new_top += dir * delta;
647					old_top += dir * delta;
648
649					if (dir * new_top < 0)
650					{
651						old_layer.style.top = old_top + 'px';
652						new_layer.style.top = new_top + 'px';
653						setTimeout(f, 10);
654					}
655					else
656					{
657						old_layer.parentNode.removeChild(old_layer);
658
659						new_layer.style.top = "0px";
660						new_layer.style.position = 'static';
661						new_layer.style.zIndex = 0;
662					}
663				})();
664			}
665			else
666			{
667				this.PARTS.LAYERS.replaceChild(new_layer, old_layer);
668			}
669		}
670	};
671
672	this._create_layer = function()
673	{
674		var l = BX.create('DIV', {
675			props: {
676				className: 'bx-calendar-layer'
677			}
678		});
679
680		var month_start = new Date(this.value);
681		month_start.setUTCHours(0);
682		month_start.setUTCMinutes(0);
683
684		month_start.setUTCDate(1);
685
686		if (month_start.getUTCDay() != this.weekStart)
687		{
688			var d = month_start.getUTCDay() - this.weekStart;
689			d += d < 0 ? 7 : 0;
690			month_start.setUTCDate(month_start.getUTCDate()-d);
691		}
692
693		var cur_month = this.value.getUTCMonth(),
694			cur_day = this.value.getUTCDate(),
695			s = '';
696		for (var i = 0; i < this.numRows; i++)
697		{
698			s += '<div class="bx-calendar-range'
699				+(i == this.numRows-1 ? ' bx-calendar-range-noline' : '')
700				+'">';
701
702			for (var j = 0; j < 7; j++)
703			{
704				d = month_start.getUTCDate();
705				var wd = month_start.getUTCDay();
706				var className = 'bx-calendar-cell';
707
708				if (cur_month != month_start.getUTCMonth())
709					className += ' bx-calendar-date-hidden';
710				else if (cur_day == d)
711					className += ' bx-calendar-active';
712
713
714				if (wd == 0 || wd == 6)
715					className += ' bx-calendar-weekend';
716
717				s += '<a href="javascript:void(0)" class="'+className+'" data-date="' + month_start.valueOf() + '">' + d + '</a>';
718
719				month_start.setUTCDate(month_start.getUTCDate()+1);
720			}
721			s += '</div>';
722		}
723
724		l.innerHTML = s;
725
726		return l;
727	};
728
729	this._prev = function()
730	{
731		this.SetMonth(this.value.getUTCMonth()-1);
732	};
733
734	this._next = function()
735	{
736		this.SetMonth(this.value.getUTCMonth()+1);
737	};
738
739	this._menu_month_content = function()
740	{
741		var months = '', cur_month = this.value.getMonth(), i;
742		for (i = 0; i < 12; i++)
743		{
744			months += '<span class="bx-calendar-month'+(i == cur_month ? ' bx-calendar-month-active' : '')+'" data-bx-month="' + i + '">' + BX.message('MONTH_' + (i + 1)) + '</span>';
745		}
746
747		return '<div class="bx-calendar-month-popup"><div class="bx-calendar-month-title" data-bx-month="' + this.value.getUTCMonth() + '">' + BX.message('MONTH_' + (this.value.getUTCMonth() + 1)) + '</div><div class="bx-calendar-month-content">' + months + '</div></div>';
748	};
749
750	this._menu_month = function()
751	{
752		if (!this.popup_month)
753		{
754			this.popup_month = new BX.PopupWindow(
755				'calendar_popup_month_' + Math.random(), this.PARTS.MONTH,
756				{
757					content: this._menu_month_content(),
758					closeByEsc: true,
759					autoHide: true,
760					offsetTop: -29,
761					offsetLeft: -1,
762					className: this.month_popup_classname,
763					events: {
764						onPopupShow: BX.delegate(function() {
765							if (this.popup_year)
766							{
767								this.popup_year.close();
768							}
769						}, this)
770					}
771				}
772			);
773
774			BX.bind(this.popup_month.popupContainer, 'click', BX.proxy(this.month_popup_click, this));
775			this.popup_month.BXMONTH = this.value.getUTCMonth();
776		}
777		else if (this.popup_month.BXMONTH != this.value.getUTCMonth())
778		{
779			this.popup_month.setContent(this._menu_month_content());
780			this.popup_month.BXMONTH = this.value.getUTCMonth();
781		}
782
783		this.popup_month.show();
784	};
785
786	this.month_popup_click = function(e)
787	{
788		var target = e.target || e.srcElement;
789		if (target && target.getAttribute && target.getAttribute('data-bx-month'))
790		{
791			this.SetMonth(parseInt(target.getAttribute('data-bx-month')));
792			this.popup_month.close();
793		}
794	};
795
796	this._menu_year_content = function()
797	{
798		var s = '<div class="bx-calendar-year-popup"><div class="bx-calendar-year-title" data-bx-year="' + this.value.getUTCFullYear() + '">' + this.value.getUTCFullYear() + '</div><div class="bx-calendar-year-content" id="bx-calendar-year-content">';
799
800		for (var i=-3; i <= 3; i++)
801		{
802			s += '<span class="bx-calendar-year-number' + (i == 0?' bx-calendar-year-active' : '') + '" data-bx-year="' + (this.value.getUTCFullYear() - i) + '">' + (this.value.getUTCFullYear() - i)+'</span>';
803		}
804
805		s += '</div><input data-bx-year-input="Y" type="text" class="bx-calendar-year-input" maxlength="4" /></div>';
806
807		return s;
808	};
809
810	this._menu_year = function()
811	{
812		if (!this.popup_year)
813		{
814			this.popup_year = new BX.PopupWindow(
815				'calendar_popup_year_' + Math.random(), this.PARTS.YEAR,
816				{
817					content: this._menu_year_content(),
818					closeByEsc: true,
819					autoHide: true,
820					offsetTop: -29,
821					offsetLeft: -1,
822					className: this.year_popup_classname,
823					events: {
824						onPopupShow: BX.delegate(function() {
825							if (this.popup_month)
826							{
827								this.popup_month.close();
828							}
829						}, this)
830					}
831				}
832			);
833
834			BX.bind(this.popup_year.popupContainer, 'click', BX.proxy(this.year_popup_click, this));
835			BX.bind(this.popup_year.popupContainer, 'keyup', BX.proxy(this.year_popup_keyup, this));
836			this.popup_year.BXYEAR = this.value.getUTCFullYear();
837		}
838		else if (this.popup_year.BXYEAR != this.value.getUTCFullYear())
839		{
840			this.popup_year.setContent(this._menu_year_content());
841			this.popup_year.BXYEAR = this.value.getUTCFullYear();
842		}
843
844		this.popup_year.show();
845	};
846
847	this.year_popup_click = function(e)
848	{
849		var target = e.target || e.srcElement;
850		if (target && target.getAttribute && target.getAttribute('data-bx-year'))
851		{
852			this.SetYear(parseInt(target.getAttribute('data-bx-year')));
853			this.popup_year.close();
854		}
855	};
856	this.year_popup_keyup = function(e)
857	{
858		var target = e.target || e.srcElement;
859		if (target && target.getAttribute && target.getAttribute('data-bx-year-input') == 'Y')
860		{
861			var value = parseInt(target.value);
862			if(value >= 1900 && value <= 2100)
863			{
864				this.SetYear(value);
865				this.popup_year.close();
866			}
867		}
868	};
869
870	this._check_date = function(v)
871	{
872		var res = v;
873
874		if (BX.type.isString(v))
875		{
876			res = BX.parseDate(v, true);
877		}
878
879		if (!BX.type.isDate(res) || isNaN(res.valueOf()))
880		{
881			res = BX.date.convertToUTC(new Date());
882			if (this.params.bHideTime)
883			{
884				res.setUTCHours(0);
885				res.setUTCMinutes(0);
886			}
887		}
888
889		res.setUTCMilliseconds(0);
890		res.setUTCSeconds(0);
891
892		res.BXCHECKED = true;
893
894		return res;
895	};
896};
897
898BX.JCCalendar.prototype.Show = function(params)
899{
900	if (!BX.isReady)
901	{
902		BX.ready(BX.delegate(function() {this.Show(params)}, this));
903		return;
904	}
905
906	params.node = params.node||document.body;
907
908	if (BX.type.isNotEmptyString(params.node))
909	{
910		var n = BX(params.node);
911		if (!n)
912		{
913			n = document.getElementsByName(params.node);
914			if (n && n.length > 0)
915			{
916				n = n[0]
917			}
918		}
919		params.node = n;
920	}
921
922	if (!params.node)
923		return;
924
925	if (!!params.field)
926	{
927		if (BX.type.isString(params.field))
928		{
929			n = BX(params.field);
930			if (!!n)
931			{
932				params.field = n;
933			}
934			else
935			{
936				if (params.form)
937				{
938					if (BX.type.isString(params.form))
939					{
940						params.form = document.forms[params.form];
941					}
942				}
943
944				if (BX.type.isDomNode(params.form) && !!params.form[params.field])
945				{
946					params.field = params.form[params.field];
947				}
948				else
949				{
950					n = document.getElementsByName(params.field);
951					if (n && n.length > 0)
952					{
953						n = n[0];
954						params.field = n;
955					}
956				}
957			}
958
959			if (BX.type.isString(params.field))
960			{
961				params.field = BX(params.field);
962			}
963		}
964	}
965
966	var bShow = !this.popup || !this.popup.isShown() || this.params.node != params.node;
967
968	this.params = params;
969
970	this.params.bCompatibility = (typeof this.params.bCompatibility == 'undefined' ? false : this.params.bCompatibility);
971	this.params.bTimeVisibility = (typeof this.params.bTimeVisibility == 'undefined' ? !this.params.bCompatibility : this.params.bTimeVisibility);
972	if (this.params.bCompatibility)
973	{
974		this.params.bCategoryTimeVisibilityOption = (
975			this.params.bCategoryTimeVisibilityOption ? this.params.bCategoryTimeVisibilityOption : ''
976		);
977		this.params.bNameTimeVisibilityOption = (
978			this.params.bNameTimeVisibilityOption ? this.params.bNameTimeVisibilityOption : 'time_visibility'
979		);
980
981		if (typeof this._bTimeVisibility !== 'undefined')
982		{
983			this.params.bTimeVisibility = this._bTimeVisibility;
984		}
985	}
986
987	this.params.bTime = typeof this.params.bTime == 'undefined' ? true : !!this.params.bTime;
988	this.params.bHideTime = typeof this.params.bHideTime == 'undefined' ? true : !!this.params.bHideTime;
989	this.params.bUseSecond = typeof this.params.bUseSecond == 'undefined' ? true : !!this.params.bUseSecond;
990
991	this.weekStart = parseInt(this.params.weekStart || this.params.weekStart || BX.message('WEEK_START'));
992	if (isNaN(this.weekStart))
993		this.weekStart = 1;
994
995	if (!this.popup)
996	{
997		this._create(this.params);
998	}
999	else
1000	{
1001		this.popup.setBindElement(this.params.node);
1002	}
1003
1004	var bHideTime = !!this.params.bHideTime;
1005	if (this.params.value)
1006	{
1007		this.SetValue(this.params.value);
1008		bHideTime = this.value.getUTCHours() <= 0 && this.value.getUTCMinutes() <= 0;
1009	}
1010	else if (this.params.field)
1011	{
1012		this.SetValue(this.params.field.value);
1013		bHideTime = this.value.getUTCHours() <= 0 && this.value.getUTCMinutes() <= 0;
1014	}
1015	else if (!!this.params.currentTime)
1016	{
1017		this.SetValue(this.params.currentTime);
1018	}
1019	else
1020	{
1021		this.SetValue();
1022	}
1023
1024	if (!!this.params.bTime)
1025	{
1026		this.activateTimeStyle(bHideTime);
1027	}
1028	else
1029	{
1030		this.activateDateStyle(bHideTime);
1031	}
1032
1033	if (bShow)
1034	{
1035		this._auto_hide_disable();
1036		this.popup.show();
1037		setTimeout(BX.proxy(this._auto_hide_enable, this), 0);
1038	}
1039
1040	this.params.bSetFocus = typeof this.params.bSetFocus == 'undefined' ? true : !!this.params.bSetFocus;
1041	if(this.params.bSetFocus)
1042	{
1043		params.node.blur();
1044	}
1045	else
1046	{
1047		BX.bind(params.node, 'keyup', BX.defer(function(){
1048			this.SetValue(params.node.value);
1049			if(!!this.params.bTime)
1050			{
1051				if(this.value.getUTCHours() <= 0 && this.value.getUTCMinutes() <= 0)
1052					BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
1053				else
1054					BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
1055			}
1056		}, this));
1057	}
1058
1059	return this;
1060};
1061
1062BX.JCCalendar.prototype.activateDateStyle = function(bHideTime)
1063{
1064	BX.addClass(this.DIV, 'bx-calendar-time-disabled');
1065
1066	if (!!bHideTime)
1067		BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
1068	else
1069		BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
1070};
1071
1072BX.JCCalendar.prototype.activateTimeStyle = function(bHideTime)
1073{
1074	if (this.params.bCompatibility && !this.params.bTimeVisibility)
1075	{
1076		BX.addClass(this.PARTS.BUTTONS, 'bx-calendar-buttons-disabled');
1077		BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-wrap-simple');
1078		BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
1079	}
1080	else
1081	{
1082		BX.removeClass(this.DIV, 'bx-calendar-time-disabled');
1083
1084		if (!!bHideTime)
1085			BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
1086		else
1087			BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
1088	}
1089};
1090
1091BX.JCCalendar.prototype.SetDay = function(d)
1092{
1093	this.value.setUTCDate(d);
1094	return this.SetValue(this.value);
1095};
1096
1097BX.JCCalendar.prototype.SetMonth = function(m)
1098{
1099	if (this.popup_month)
1100		this.popup_month.close();
1101
1102	this.value.setUTCMonth(m);
1103
1104	if(m < 0)
1105		m += 12;
1106	else if (m >= 12)
1107		m -= 12;
1108
1109	while(this.value.getUTCMonth() > m)
1110	{
1111		this.value.setUTCDate(this.value.getUTCDate()-1);
1112	}
1113
1114	return this.SetValue(this.value);
1115};
1116
1117BX.JCCalendar.prototype.SetYear = function(y)
1118{
1119	if (this.popup_year)
1120		this.popup_year.close();
1121	this.value.setUTCFullYear(y);
1122	return this.SetValue(this.value);
1123};
1124
1125BX.JCCalendar.prototype.SetDate = function(v, bSet)
1126{
1127	v = this._check_date(v);
1128	v.setUTCHours(this.value.getUTCHours());
1129	v.setUTCMinutes(this.value.getUTCMinutes());
1130	v.setUTCSeconds(this.value.getUTCSeconds());
1131
1132	if (this.params.bTime && !bSet)
1133	{
1134		return this.SetValue(v);
1135	}
1136	else
1137	{
1138		this.SetValue(v);
1139		this.SaveValue();
1140	}
1141};
1142
1143BX.JCCalendar.prototype.SetValue = function(v)
1144{
1145	this.value = (v && v.BXCHECKED) ? v : this._check_date(v);
1146
1147	this.PARTS.MONTH.innerHTML = BX.message('MONTH_' + (this.value.getUTCMonth()+1));
1148	this.PARTS.YEAR.innerHTML = this.value.getUTCFullYear();
1149
1150	if (!!this.params.bTime)
1151	{
1152		var h = this.value.getUTCHours();
1153		if (this.bAmPm)
1154		{
1155			if (h >= 12)
1156			{
1157				this.PARTS.TIME_AMPM.innerHTML = 'PM';
1158
1159				if (h != 12)
1160					h -= 12;
1161			}
1162			else
1163			{
1164				this.PARTS.TIME_AMPM.innerHTML = 'AM';
1165
1166				if (h == 0)
1167					h = 12;
1168			}
1169		}
1170
1171		this.PARTS.TIME_INPUT_H.value = BX.util.str_pad_left(h.toString(), 2, "0");
1172		this.PARTS.TIME_INPUT_M.value = BX.util.str_pad_left(this.value.getUTCMinutes().toString(), 2, "0");
1173	}
1174
1175	this._set_layer();
1176
1177	return this;
1178};
1179
1180BX.JCCalendar.prototype.SaveValue = function()
1181{
1182	if (this.popup_month)
1183		this.popup_month.close();
1184	if (this.popup_year)
1185		this.popup_year.close();
1186
1187	var bSetValue = true;
1188	if (!!this.params.callback)
1189	{
1190		var res = this.params.callback.apply(this, [new Date(this.value.valueOf()+this.value.getTimezoneOffset()*60000)]);
1191		if (res === false)
1192			bSetValue = false;
1193	}
1194
1195	if (bSetValue)
1196	{
1197		var bTime = !!this.params.bTime && BX.hasClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
1198
1199		if (this.params.field)
1200		{
1201			var format = BX.message(bTime ? 'FORMAT_DATETIME' : 'FORMAT_DATE');
1202
1203			if(bTime && !this.params.bUseSecond)
1204			{
1205				format = format.replace(':SS', '');
1206			}
1207
1208			this.params.field.value = BX.calendar.ValueToStringFormat(this.value, format, true);
1209			BX.fireEvent(this.params.field, 'change');
1210		}
1211
1212		this.popup.close();
1213
1214		if (!!this.params.callback_after)
1215		{
1216			this.params.callback_after.apply(this, [new Date(this.value.valueOf()+this.value.getTimezoneOffset()*60000), bTime]);
1217		}
1218	}
1219
1220	return this;
1221};
1222
1223BX.JCCalendar.prototype.Close = function()
1224{
1225	if (!!this.popup)
1226		this.popup.close();
1227
1228	return this;
1229};
1230
1231BX.JCSpinner = function(params)
1232{
1233	params = params || {};
1234	this.params = {
1235		input: params.input || null,
1236
1237		delta: params.delta || 1,
1238
1239		timeout_start: params.timeout_start || 1000,
1240		timeout_cont: params.timeout_cont || 150,
1241
1242		callback_start: params.callback_start || null,
1243		callback_change: params.callback_change || null,
1244		callback_finish: params.callback_finish || null,
1245
1246		bSaveValue: typeof params.bSaveValue == 'undefined' ? !!params.input : !!params.bSaveValue
1247	};
1248
1249	this.mousedown = false;
1250	this.direction = 1;
1251};
1252
1253BX.JCSpinner.prototype.Show = function()
1254{
1255	this.node = BX.create('span', {
1256		events: {
1257			mousedown: BX.delegateEvent(
1258				{attr: 'data-dir'},
1259				BX.delegate(this.Start, this)
1260			)
1261		},
1262		html: '<a href="javascript:void(0)" class="bx-calendar-form-arrow bx-calendar-form-arrow-top" data-dir="1"><i></i></a><a href="javascript:void(0)" class="bx-calendar-form-arrow bx-calendar-form-arrow-bottom" data-dir="-1"><i></i></a>'
1263	});
1264	return this.node;
1265};
1266
1267BX.JCSpinner.prototype.Start = function()
1268{
1269	this.mousedown = true;
1270	this.direction = BX.proxy_context.getAttribute('data-dir') > 0 ? 1 : -1;
1271	BX.bind(document, "mouseup", BX.proxy(this.MouseUp, this));
1272	this.ChangeValue(true);
1273};
1274
1275BX.JCSpinner.prototype.ChangeValue = function(bFirst)
1276{
1277	if(!this.mousedown)
1278		return;
1279
1280	if (this.params.input)
1281	{
1282		var v = parseInt(this.params.input.value, 10) + this.params.delta * this.direction;
1283
1284		if (this.params.bSaveValue)
1285			this.params.input.value = v;
1286
1287		if (!!bFirst && this.params.callback_start)
1288			this.params.callback_start(this.params, v, this.direction);
1289
1290		if (this.params.callback_change)
1291			this.params.callback_change(this.params, v, this.direction);
1292
1293		setTimeout(
1294			BX.proxy(this.ChangeValue, this),
1295			!!bFirst ? this.params.timeout_start : this.params.timeout_cont
1296		);
1297	}
1298};
1299
1300BX.JCSpinner.prototype.MouseUp = function()
1301{
1302	this.mousedown = false;
1303	BX.unbind(document, "mouseup", BX.proxy(this.MouseUp, this));
1304
1305	if (this.params.callback_finish)
1306		this.params.callback_finish(this.params, this.params.input.value);
1307};
1308
1309/**************** compatibility hacks ***************************/
1310
1311window.jsCalendar = {
1312	Show: function(obj, field, fieldFrom, fieldTo, bTime, serverTime, form_name, bHideTimebar)
1313	{
1314		return BX.calendar({
1315			node: obj, field: field, form: form_name, bTime: !!bTime, currentTime: serverTime, bHideTimebar: !!bHideTimebar
1316		});
1317	},
1318
1319	ValueToString: BX.calendar.ValueToString
1320};
1321
1322
1323/************ clock popup transferred from timeman **************/
1324
1325BX.CClockSelector = function(params)
1326{
1327	this.params = params;
1328
1329	this.params.popup_buttons = this.params.popup_buttons || [
1330		new BX.PopupWindowButton({
1331			text : BX.message('CAL_BUTTON'),
1332			className : "popup-window-button-create",
1333			events : {click : BX.proxy(this.setValue, this)}
1334		})
1335	];
1336
1337	this.isReady = false;
1338
1339	this.WND = new BX.PopupWindow(
1340		this.params.popup_id || 'clock_selector_popup',
1341		this.params.node,
1342		this.params.popup_config || {
1343			titleBar: BX.message('CAL_TIME'),
1344			offsetLeft: -45,
1345			offsetTop: -135,
1346			autoHide: true,
1347			closeIcon: true,
1348			closeByEsc: true
1349		}
1350	);
1351
1352	this.SHOW = false;
1353	BX.addCustomEvent(this.WND, "onPopupClose", BX.delegate(this.onPopupClose, this));
1354
1355	this.obClocks = {};
1356	this.CLOCK_ID = this.params.clock_id || 'clock_selector';
1357};
1358
1359BX.CClockSelector.prototype.Show = function()
1360{
1361	if (!this.isReady)
1362	{
1363		//BX.timeman.showWait(this.parent.DIV);
1364
1365		BX.addCustomEvent('onClockRegister', BX.proxy(this.onClockRegister, this));
1366		return BX.ajax.get('/bitrix/tools/clock_selector.php', {start_time: this.params.start_time, clock_id: this.CLOCK_ID, sessid: BX.bitrix_sessid()}, BX.delegate(this.Ready, this));
1367	}
1368
1369	this.WND.setButtons(this.params.popup_buttons);
1370	this.WND.show();
1371
1372	this.SHOW = true;
1373
1374	if (window['bxClock_' + this.obClocks[this.CLOCK_ID]])
1375	{
1376		setTimeout("window['bxClock_" + this.obClocks[this.CLOCK_ID] + "'].CalculateCoordinates()", 40);
1377	}
1378
1379	return true;
1380};
1381
1382BX.CClockSelector.prototype.onClockRegister = function(obClocks)
1383{
1384	if (obClocks[this.CLOCK_ID])
1385	{
1386		this.obClocks[this.CLOCK_ID] = obClocks[this.CLOCK_ID];
1387		BX.removeCustomEvent('onClockRegister', BX.proxy(this.onClockRegister, this));
1388	}
1389};
1390
1391BX.CClockSelector.prototype.Ready = function(data)
1392{
1393	this.content = this.CreateContent(data);
1394	this.WND.setContent(this.content);
1395
1396	this.isReady = true;
1397	//BX.timeman.closeWait();
1398
1399	setTimeout(BX.proxy(this.Show, this), 30);
1400};
1401
1402BX.CClockSelector.prototype.CreateContent = function(data)
1403{
1404	return BX.create('DIV', {
1405		events: {click: BX.PreventDefault},
1406		html:
1407			'<div class="bx-tm-popup-clock">' + data + '</div>'
1408	});
1409};
1410
1411BX.CClockSelector.prototype.setValue = function(e)
1412{
1413	if (this.params.callback)
1414	{
1415		var input = BX.findChild(this.content, {tagName: 'INPUT'}, true);
1416		this.params.callback.apply(this.params.node, [input.value]);
1417	}
1418
1419	return BX.PreventDefault(e);
1420};
1421
1422BX.CClockSelector.prototype.closeWnd = function(e)
1423{
1424	this.WND.close();
1425	return (e || window.event) ? BX.PreventDefault(e) : true;
1426};
1427
1428BX.CClockSelector.prototype.setNode = function(node)
1429{
1430	this.WND.setBindElement(node);
1431};
1432
1433BX.CClockSelector.prototype.setTime = function(timestamp)
1434{
1435	this.params.start_time = timestamp;
1436	if (window['bxClock_' + this.obClocks[this.CLOCK_ID]])
1437	{
1438		window['bxClock_' +  this.obClocks[this.CLOCK_ID]].SetTime(parseInt(timestamp/3600), parseInt((timestamp%3600)/60));
1439	}
1440};
1441
1442BX.CClockSelector.prototype.setCallback = function(cb)
1443{
1444	this.params.callback = cb;
1445};
1446
1447BX.CClockSelector.prototype.onPopupClose = function()
1448{
1449	this.SHOW = false;
1450};
1451
1452})();
1453

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.