PageSourceSearch

https://www.dvfu.ru/bitrix/js/main/core/core_date.js?178296505336341

js dvfu.ru collected 2026-10-01 10:17:05 UTC 36,341 bytes, 1,457 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			focusTrap: false,
308		};
309		if (Boolean(params.fixed) && params.fixed)
310		{
311			paramsForPopupWindow.fixed = params.fixed;
312		}
313
314		this.popup = new BX.PopupWindow(
315			'calendar_popup_' + Math.random(),
316			params.node,
317			paramsForPopupWindow,
318		);
319
320		BX.bind(this.popup.popupContainer, 'click', function(event) {
321			event.stopPropagation();
322		});
323	};
324
325	this._auto_hide_disable = function()
326	{
327		BX.unbind(document, 'click', BX.proxy(this._auto_hide, this));
328	};
329
330	this._auto_hide_enable = function()
331	{
332		BX.bind(document, 'click', BX.proxy(this._auto_hide, this));
333	};
334
335	this._auto_hide = function(e)
336	{
337		this._auto_hide_disable();
338		this.popup.close();
339	};
340
341	this._get_content = function()
342	{
343		var _layer_onclick = BX.delegate(function(e) {
344			e = e||window.event;
345			this.SetDate(
346				new Date(parseInt(BX.proxy_context.getAttribute('data-date'))),
347				(e.type === 'dblclick' || (this.params.bCompatibility && !this.params.bTimeVisibility))
348			)
349		}, this);
350
351		this.DIV = BX.create('DIV', {
352			props: {className: 'bx-calendar'},
353			children: [
354				BX.create('DIV', {
355					props: {
356						className: 'bx-calendar-header'
357					},
358					children: [
359						BX.create('A', {
360							attrs: {href: 'javascript:void(0)'},
361							props: {className: 'bx-calendar-left-arrow'},
362							events: {click: BX.proxy(this._prev, this)}
363						}),
364
365						BX.create('SPAN', {
366							props: {className: 'bx-calendar-header-content'},
367							children: [
368								(this.PARTS.MONTH = BX.create('A', {
369									attrs: {href: 'javascript:void(0)'},
370									props: {className: 'bx-calendar-top-month'},
371									events: {click: BX.proxy(this._menu_month, this)}
372								})),
373
374								(this.PARTS.YEAR = BX.create('A', {
375									attrs: {href: 'javascript:void(0)'},
376									props: {className: 'bx-calendar-top-year'},
377									events: {click: BX.proxy(this._menu_year, this)}
378								}))
379							]
380						}),
381
382						BX.create('A', {
383							attrs: {href: 'javascript:void(0)'},
384							props: {className: 'bx-calendar-right-arrow'},
385							events: {click: BX.proxy(this._next, this)}
386						})
387					]
388				}),
389
390				(this.PARTS.WEEK = BX.create('DIV', {
391					props: {
392						className: 'bx-calendar-name-day-wrap'
393					}
394				})),
395
396				(this.PARTS.LAYERS = BX.create('DIV', {
397					props: {
398						className: 'bx-calendar-cell-block'
399					},
400					events: {
401						click: BX.delegateEvent({className: 'bx-calendar-cell'}, _layer_onclick),
402						dblclick: BX.delegateEvent({className: 'bx-calendar-cell'}, _layer_onclick)
403					}
404				})),
405
406				(this.PARTS.TIME = BX.create('DIV', {
407					props: {
408						className: 'bx-calendar-set-time-wrap'
409					},
410					events: {
411						click: BX.delegateEvent(
412							{attr: 'data-action'},
413							BX.delegate(this._time_actions, this)
414						)
415					},
416					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>'
417				})),
418
419				(this.PARTS.BUTTONS = BX.create('DIV', {
420					props: {className: 'bx-calendar-button-block'},
421					events: {
422						click: BX.delegateEvent(
423							{attr: 'data-action'},
424							BX.delegate(this._button_actions, this)
425						)
426					},
427					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>'
428				}))
429			]
430		});
431
432		this.PARTS.TIME_INPUT_H = BX.findChild(this.PARTS.TIME, {tag: 'INPUT'}, true);
433		this.PARTS.TIME_INPUT_M = this.PARTS.TIME_INPUT_H.nextSibling.nextSibling;
434
435		if (this.bAmPm)
436			this.PARTS.TIME_AMPM = this.PARTS.TIME_INPUT_M.nextSibling.firstChild;
437
438		var spinner = (new BX.JCSpinner({
439			input: this.PARTS.TIME_INPUT_H,
440			callback_change: BX.proxy(this._check_time, this),
441			bSaveValue: false
442		})).Show();
443		spinner.className = 'bx-calendar-form-arrow-l';
444		this.PARTS.TIME_INPUT_H.parentNode.insertBefore(spinner, this.PARTS.TIME_INPUT_H);
445
446		spinner = (new BX.JCSpinner({
447			input: this.PARTS.TIME_INPUT_M,
448			callback_change: BX.proxy(this._check_time, this),
449			bSaveValue: true
450		})).Show();
451		spinner.className = 'bx-calendar-form-arrow-r';
452		if (!this.PARTS.TIME_INPUT_M.nextSibling)
453			this.PARTS.TIME_INPUT_M.parentNode.appendChild(spinner);
454		else
455			this.PARTS.TIME_INPUT_M.parentNode.insertBefore(spinner, this.PARTS.TIME_INPUT_M.nextSibling);
456
457		for (var i = 0; i < 7; i++)
458		{
459			this.PARTS.WEEK.appendChild(BX.create('SPAN', {
460				props: {
461					className: 'bx-calendar-name-day'
462				},
463				text: BX.message('DOW_' + ((i + this.weekStart) % 7))
464			}));
465		}
466
467		return this.DIV;
468	};
469
470	this._time_actions = function()
471	{
472		switch (BX.proxy_context.getAttribute('data-action'))
473		{
474			case 'time_show':
475				BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
476				if (this.params.bCompatibility)
477				{
478					BX.removeClass(this.PARTS.BUTTONS, 'bx-calendar-buttons-disabled');
479				}
480				this.popup.adjustPosition();
481			break;
482			case 'time_hide':
483				BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
484				if (this.params.bCompatibility)
485				{
486					this._saveChoice('hide');
487					BX.addClass(this.PARTS.BUTTONS, 'bx-calendar-buttons-disabled');
488				}
489				this.popup.adjustPosition();
490			break;
491			case 'time_ampm':
492				this.PARTS.TIME_AMPM.innerHTML = this.PARTS.TIME_AMPM.innerHTML == 'AM' ? 'PM' : 'AM';
493			break;
494			case 'time_ampm_up':
495				this._check_time({bSaveValue: false}, null, 12);
496				return;
497			break;
498			case 'time_ampm_down':
499				this._check_time({bSaveValue: false}, null, -12);
500				return;
501			break;
502		}
503
504		this._check_time();
505	};
506
507	this._button_actions = function()
508	{
509		switch (BX.proxy_context.getAttribute('data-action'))
510		{
511			case 'submit':
512				if (this.params.bCompatibility)
513				{
514					this._saveChoice('show');
515				}
516				this.SaveValue();
517			break;
518			case 'cancel':
519				this.Close();
520			break;
521		}
522	};
523
524	this._saveChoice = function(state)
525	{
526		if (this.params.bCategoryTimeVisibilityOption)
527		{
528			BX.userOptions.save(
529				this.params.bCategoryTimeVisibilityOption,
530				this.params.bNameTimeVisibilityOption,
531				'visibility',
532				(state === 'show' ? 'Y' : 'N')
533			);
534		}
535
536		this._bTimeVisibility = (state === 'show');
537		this.params.bTimeVisibility = this._bTimeVisibility;
538	};
539
540	this._check_time = function(params, value, direction)
541	{
542		var h = parseInt(this.PARTS.TIME_INPUT_H.value.substring(0,5),10)||0,
543			m = parseInt(this.PARTS.TIME_INPUT_M.value.substring(0,5),10)||0,
544			bChanged = false;
545
546		if (!!params && !params.bSaveValue)
547		{
548			this.value.setUTCHours(this.value.getUTCHours() + direction);
549		}
550		else if (!isNaN(h))
551		{
552			if (this.bAmPm)
553			{
554				if (h != 12 && this.PARTS.TIME_AMPM.innerHTML == 'PM')
555				{
556					h += 12;
557				}
558			}
559
560			bChanged = true;
561			this.value.setUTCHours(h % 24);
562		}
563
564		if (!isNaN(m))
565		{
566			bChanged = true;
567			this.value.setUTCMinutes(m % 60);
568		}
569
570		if (bChanged)
571		{
572			this.SetValue(this.value);
573		}
574	};
575
576	this._set_layer = function()
577	{
578		var layerId = parseInt(this.value.getUTCFullYear() + '' + BX.util.str_pad_left(this.value.getUTCMonth()+'', 2, "0"));
579
580		if (!this._layers[layerId])
581		{
582			this._layers[layerId] = this._create_layer();
583			this._layers[layerId].BXLAYERID = layerId;
584		}
585
586		if (this._current_layer)
587		{
588			var v = new Date(this.value.valueOf());
589			v.setUTCHours(0); v.setUTCMinutes(0);
590
591			var cur_value = BX.findChild(this._layers[layerId], {
592					tag: 'A',
593					className: 'bx-calendar-active'
594				}, true),
595				new_value = BX.findChild(this._layers[layerId], {
596					tag: 'A',
597					attr: {
598						'data-date' : v.valueOf() + ''
599					}
600				}, true);
601
602			if (cur_value)
603			{
604				BX.removeClass(cur_value, 'bx-calendar-active');
605			}
606
607			if (new_value)
608			{
609				BX.addClass(new_value, 'bx-calendar-active');
610			}
611
612			this._replace_layer(this._current_layer, this._layers[layerId]);
613		}
614		else
615		{
616			this.PARTS.LAYERS.appendChild(this._layers[layerId]);
617		}
618
619		this._current_layer = this._layers[layerId];
620	};
621
622	this._replace_layer = function(old_layer, new_layer)
623	{
624		if (old_layer != new_layer)
625		{
626			if (!BX.browser.IsIE() || BX.browser.IsDoctype())
627			{
628				var dir = old_layer.BXLAYERID > new_layer.BXLAYERID ? 1 : -1;
629
630				var old_top = 0;
631				var new_top = -dir * old_layer.offsetHeight;
632
633				old_layer.style.position = 'relative';
634				old_layer.style.top = "0px";
635				old_layer.style.zIndex = 5;
636
637				new_layer.style.position = 'absolute';
638				new_layer.style.top = new_top + 'px';
639				new_layer.style.zIndex = 6;
640
641				this.PARTS.LAYERS.appendChild(new_layer);
642
643				var delta = 15;
644
645				var f;
646				(f = function() {
647					new_top += dir * delta;
648					old_top += dir * delta;
649
650					if (dir * new_top < 0)
651					{
652						old_layer.style.top = old_top + 'px';
653						new_layer.style.top = new_top + 'px';
654						setTimeout(f, 10);
655					}
656					else
657					{
658						old_layer.parentNode.removeChild(old_layer);
659
660						new_layer.style.top = "0px";
661						new_layer.style.position = 'static';
662						new_layer.style.zIndex = 0;
663					}
664				})();
665			}
666			else
667			{
668				this.PARTS.LAYERS.replaceChild(new_layer, old_layer);
669			}
670		}
671	};
672
673	this._create_layer = function()
674	{
675		var l = BX.create('DIV', {
676			props: {
677				className: 'bx-calendar-layer'
678			}
679		});
680
681		var month_start = new Date(this.value);
682		month_start.setUTCHours(0);
683		month_start.setUTCMinutes(0);
684
685		month_start.setUTCDate(1);
686
687		if (month_start.getUTCDay() != this.weekStart)
688		{
689			var d = month_start.getUTCDay() - this.weekStart;
690			d += d < 0 ? 7 : 0;
691			month_start.setUTCDate(month_start.getUTCDate()-d);
692		}
693
694		var cur_month = this.value.getUTCMonth(),
695			cur_day = this.value.getUTCDate(),
696			s = '';
697		for (var i = 0; i < this.numRows; i++)
698		{
699			s += '<div class="bx-calendar-range'
700				+(i == this.numRows-1 ? ' bx-calendar-range-noline' : '')
701				+'">';
702
703			for (var j = 0; j < 7; j++)
704			{
705				d = month_start.getUTCDate();
706				var wd = month_start.getUTCDay();
707				var className = 'bx-calendar-cell';
708
709				if (cur_month != month_start.getUTCMonth())
710					className += ' bx-calendar-date-hidden';
711				else if (cur_day == d)
712					className += ' bx-calendar-active';
713
714
715				if (wd == 0 || wd == 6)
716					className += ' bx-calendar-weekend';
717
718				s += '<a href="javascript:void(0)" class="'+className+'" data-date="' + month_start.valueOf() + '">' + d + '</a>';
719
720				month_start.setUTCDate(month_start.getUTCDate()+1);
721			}
722			s += '</div>';
723		}
724
725		l.innerHTML = s;
726
727		return l;
728	};
729
730	this._prev = function()
731	{
732		this.SetMonth(this.value.getUTCMonth()-1);
733	};
734
735	this._next = function()
736	{
737		this.SetMonth(this.value.getUTCMonth()+1);
738	};
739
740	this._menu_month_content = function()
741	{
742		var months = '', cur_month = this.value.getMonth(), i;
743		for (i = 0; i < 12; i++)
744		{
745			months += '<span class="bx-calendar-month'+(i == cur_month ? ' bx-calendar-month-active' : '')+'" data-bx-month="' + i + '">' + BX.message('MONTH_' + (i + 1)) + '</span>';
746		}
747
748		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>';
749	};
750
751	this._menu_month = function()
752	{
753		if (!this.popup_month)
754		{
755			this.popup_month = new BX.PopupWindow(
756				'calendar_popup_month_' + Math.random(), this.PARTS.MONTH,
757				{
758					content: this._menu_month_content(),
759					closeByEsc: true,
760					autoHide: true,
761					offsetTop: -29,
762					offsetLeft: -1,
763					className: this.month_popup_classname,
764					focusTrap: false,
765					events: {
766						onPopupShow: BX.delegate(function() {
767							if (this.popup_year)
768							{
769								this.popup_year.close();
770							}
771						}, this)
772					}
773				}
774			);
775
776			BX.bind(this.popup_month.popupContainer, 'click', BX.proxy(this.month_popup_click, this));
777			this.popup_month.BXMONTH = this.value.getUTCMonth();
778		}
779		else if (this.popup_month.BXMONTH != this.value.getUTCMonth())
780		{
781			this.popup_month.setContent(this._menu_month_content());
782			this.popup_month.BXMONTH = this.value.getUTCMonth();
783		}
784
785		this.popup_month.show();
786	};
787
788	this.month_popup_click = function(e)
789	{
790		var target = e.target || e.srcElement;
791		if (target && target.getAttribute && target.getAttribute('data-bx-month'))
792		{
793			this.SetMonth(parseInt(target.getAttribute('data-bx-month')));
794			this.popup_month.close();
795		}
796	};
797
798	this._menu_year_content = function()
799	{
800		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">';
801
802		for (var i=-3; i <= 3; i++)
803		{
804			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>';
805		}
806
807		s += '</div><input data-bx-year-input="Y" type="text" class="bx-calendar-year-input" maxlength="4" /></div>';
808
809		return s;
810	};
811
812	this._menu_year = function()
813	{
814		if (!this.popup_year)
815		{
816			this.popup_year = new BX.PopupWindow(
817				'calendar_popup_year_' + Math.random(), this.PARTS.YEAR,
818				{
819					content: this._menu_year_content(),
820					closeByEsc: true,
821					autoHide: true,
822					offsetTop: -29,
823					offsetLeft: -1,
824					className: this.year_popup_classname,
825					focusTrap: false,
826					events: {
827						onPopupShow: BX.delegate(function() {
828							if (this.popup_month)
829							{
830								this.popup_month.close();
831							}
832						}, this)
833					}
834				}
835			);
836
837			BX.bind(this.popup_year.popupContainer, 'click', BX.proxy(this.year_popup_click, this));
838			BX.bind(this.popup_year.popupContainer, 'keyup', BX.proxy(this.year_popup_keyup, this));
839			this.popup_year.BXYEAR = this.value.getUTCFullYear();
840		}
841		else if (this.popup_year.BXYEAR != this.value.getUTCFullYear())
842		{
843			this.popup_year.setContent(this._menu_year_content());
844			this.popup_year.BXYEAR = this.value.getUTCFullYear();
845		}
846
847		this.popup_year.show();
848	};
849
850	this.year_popup_click = function(e)
851	{
852		var target = e.target || e.srcElement;
853		if (target && target.getAttribute && target.getAttribute('data-bx-year'))
854		{
855			this.SetYear(parseInt(target.getAttribute('data-bx-year')));
856			this.popup_year.close();
857		}
858	};
859	this.year_popup_keyup = function(e)
860	{
861		var target = e.target || e.srcElement;
862		if (target && target.getAttribute && target.getAttribute('data-bx-year-input') == 'Y')
863		{
864			var value = parseInt(target.value);
865			if(value >= 1900 && value <= 2100)
866			{
867				this.SetYear(value);
868				this.popup_year.close();
869			}
870		}
871	};
872
873	this._check_date = function(v)
874	{
875		var res = v;
876
877		if (BX.type.isString(v))
878		{
879			res = BX.parseDate(v, true);
880		}
881
882		if (!BX.type.isDate(res) || isNaN(res.valueOf()))
883		{
884			res = BX.date.convertToUTC(new Date());
885			if (this.params.bHideTime)
886			{
887				res.setUTCHours(0);
888				res.setUTCMinutes(0);
889			}
890		}
891
892		res.setUTCMilliseconds(0);
893		res.setUTCSeconds(0);
894
895		res.BXCHECKED = true;
896
897		return res;
898	};
899};
900
901BX.JCCalendar.prototype.Show = function(params)
902{
903	if (!BX.isReady)
904	{
905		BX.ready(BX.delegate(function() {this.Show(params)}, this));
906		return;
907	}
908
909	params.node = params.node||document.body;
910
911	if (BX.type.isNotEmptyString(params.node))
912	{
913		var n = BX(params.node);
914		if (!n)
915		{
916			n = document.getElementsByName(params.node);
917			if (n && n.length > 0)
918			{
919				n = n[0]
920			}
921		}
922		params.node = n;
923	}
924
925	if (!params.node)
926		return;
927
928	if (!!params.field)
929	{
930		if (BX.type.isString(params.field))
931		{
932			n = BX(params.field);
933			if (!!n)
934			{
935				params.field = n;
936			}
937			else
938			{
939				if (params.form)
940				{
941					if (BX.type.isString(params.form))
942					{
943						params.form = document.forms[params.form];
944					}
945				}
946
947				if (BX.type.isDomNode(params.form) && !!params.form[params.field])
948				{
949					params.field = params.form[params.field];
950				}
951				else
952				{
953					n = document.getElementsByName(params.field);
954					if (n && n.length > 0)
955					{
956						n = n[0];
957						params.field = n;
958					}
959				}
960			}
961
962			if (BX.type.isString(params.field))
963			{
964				params.field = BX(params.field);
965			}
966		}
967	}
968
969	var bShow = !this.popup || !this.popup.isShown() || this.params.node != params.node;
970
971	this.params = params;
972
973	this.params.bCompatibility = (typeof this.params.bCompatibility == 'undefined' ? false : this.params.bCompatibility);
974	this.params.bTimeVisibility = (typeof this.params.bTimeVisibility == 'undefined' ? !this.params.bCompatibility : this.params.bTimeVisibility);
975	if (this.params.bCompatibility)
976	{
977		this.params.bCategoryTimeVisibilityOption = (
978			this.params.bCategoryTimeVisibilityOption ? this.params.bCategoryTimeVisibilityOption : ''
979		);
980		this.params.bNameTimeVisibilityOption = (
981			this.params.bNameTimeVisibilityOption ? this.params.bNameTimeVisibilityOption : 'time_visibility'
982		);
983
984		if (typeof this._bTimeVisibility !== 'undefined')
985		{
986			this.params.bTimeVisibility = this._bTimeVisibility;
987		}
988	}
989
990	this.params.bTime = typeof this.params.bTime == 'undefined' ? true : !!this.params.bTime;
991	this.params.bHideTime = typeof this.params.bHideTime == 'undefined' ? true : !!this.params.bHideTime;
992	this.params.bUseSecond = typeof this.params.bUseSecond == 'undefined' ? true : !!this.params.bUseSecond;
993
994	this.weekStart = parseInt(this.params.weekStart || this.params.weekStart || BX.message('WEEK_START'));
995	if (isNaN(this.weekStart))
996		this.weekStart = 1;
997
998	if (!this.popup)
999	{
1000		this._create(this.params);
1001	}
1002	else
1003	{
1004		this.popup.setBindElement(this.params.node);
1005	}
1006
1007	var bHideTime = !!this.params.bHideTime;
1008	if (this.params.value)
1009	{
1010		this.SetValue(this.params.value);
1011		bHideTime = this.value.getUTCHours() <= 0 && this.value.getUTCMinutes() <= 0;
1012	}
1013	else if (this.params.field)
1014	{
1015		this.SetValue(this.params.field.value);
1016		bHideTime = this.value.getUTCHours() <= 0 && this.value.getUTCMinutes() <= 0;
1017	}
1018	else if (!!this.params.currentTime)
1019	{
1020		this.SetValue(this.params.currentTime);
1021	}
1022	else
1023	{
1024		this.SetValue();
1025	}
1026
1027	if (!!this.params.bTime)
1028	{
1029		this.activateTimeStyle(bHideTime);
1030	}
1031	else
1032	{
1033		this.activateDateStyle(bHideTime);
1034	}
1035
1036	if (bShow)
1037	{
1038		this._auto_hide_disable();
1039		this.popup.show();
1040		setTimeout(BX.proxy(this._auto_hide_enable, this), 0);
1041	}
1042
1043	this.params.bSetFocus = typeof this.params.bSetFocus == 'undefined' ? true : !!this.params.bSetFocus;
1044	if(this.params.bSetFocus)
1045	{
1046		params.node.blur();
1047	}
1048	else
1049	{
1050		BX.bind(params.node, 'keyup', BX.defer(function(){
1051			this.SetValue(params.node.value);
1052			if(!!this.params.bTime)
1053			{
1054				if(this.value.getUTCHours() <= 0 && this.value.getUTCMinutes() <= 0)
1055					BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
1056				else
1057					BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
1058			}
1059		}, this));
1060	}
1061
1062	return this;
1063};
1064
1065BX.JCCalendar.prototype.activateDateStyle = function(bHideTime)
1066{
1067	BX.addClass(this.DIV, 'bx-calendar-time-disabled');
1068
1069	if (!!bHideTime)
1070		BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
1071	else
1072		BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
1073};
1074
1075BX.JCCalendar.prototype.activateTimeStyle = function(bHideTime)
1076{
1077	if (this.params.bCompatibility && !this.params.bTimeVisibility)
1078	{
1079		BX.addClass(this.PARTS.BUTTONS, 'bx-calendar-buttons-disabled');
1080		BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-wrap-simple');
1081		BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
1082	}
1083	else
1084	{
1085		BX.removeClass(this.DIV, 'bx-calendar-time-disabled');
1086
1087		if (!!bHideTime)
1088			BX.removeClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
1089		else
1090			BX.addClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
1091	}
1092};
1093
1094BX.JCCalendar.prototype.SetDay = function(d)
1095{
1096	this.value.setUTCDate(d);
1097	return this.SetValue(this.value);
1098};
1099
1100BX.JCCalendar.prototype.SetMonth = function(m)
1101{
1102	if (this.popup_month)
1103		this.popup_month.close();
1104
1105	this.value.setUTCMonth(m);
1106
1107	if(m < 0)
1108		m += 12;
1109	else if (m >= 12)
1110		m -= 12;
1111
1112	while(this.value.getUTCMonth() > m)
1113	{
1114		this.value.setUTCDate(this.value.getUTCDate()-1);
1115	}
1116
1117	return this.SetValue(this.value);
1118};
1119
1120BX.JCCalendar.prototype.SetYear = function(y)
1121{
1122	if (this.popup_year)
1123		this.popup_year.close();
1124	this.value.setUTCFullYear(y);
1125	return this.SetValue(this.value);
1126};
1127
1128BX.JCCalendar.prototype.SetDate = function(v, bSet)
1129{
1130	v = this._check_date(v);
1131	v.setUTCHours(this.value.getUTCHours());
1132	v.setUTCMinutes(this.value.getUTCMinutes());
1133	v.setUTCSeconds(this.value.getUTCSeconds());
1134
1135	if (this.params.bTime && !bSet)
1136	{
1137		return this.SetValue(v);
1138	}
1139	else
1140	{
1141		this.SetValue(v);
1142		this.SaveValue();
1143	}
1144};
1145
1146BX.JCCalendar.prototype.SetValue = function(v)
1147{
1148	this.value = (v && v.BXCHECKED) ? v : this._check_date(v);
1149
1150	this.PARTS.MONTH.innerHTML = BX.message('MONTH_' + (this.value.getUTCMonth()+1));
1151	this.PARTS.YEAR.innerHTML = this.value.getUTCFullYear();
1152
1153	if (!!this.params.bTime)
1154	{
1155		var h = this.value.getUTCHours();
1156		if (this.bAmPm)
1157		{
1158			if (h >= 12)
1159			{
1160				this.PARTS.TIME_AMPM.innerHTML = 'PM';
1161
1162				if (h != 12)
1163					h -= 12;
1164			}
1165			else
1166			{
1167				this.PARTS.TIME_AMPM.innerHTML = 'AM';
1168
1169				if (h == 0)
1170					h = 12;
1171			}
1172		}
1173
1174		this.PARTS.TIME_INPUT_H.value = BX.util.str_pad_left(h.toString(), 2, "0");
1175		this.PARTS.TIME_INPUT_M.value = BX.util.str_pad_left(this.value.getUTCMinutes().toString(), 2, "0");
1176	}
1177
1178	this._set_layer();
1179
1180	return this;
1181};
1182
1183BX.JCCalendar.prototype.SaveValue = function()
1184{
1185	if (this.popup_month)
1186		this.popup_month.close();
1187	if (this.popup_year)
1188		this.popup_year.close();
1189
1190	var bSetValue = true;
1191	if (!!this.params.callback)
1192	{
1193		var res = this.params.callback.apply(this, [new Date(this.value.valueOf()+this.value.getTimezoneOffset()*60000)]);
1194		if (res === false)
1195			bSetValue = false;
1196	}
1197
1198	if (bSetValue)
1199	{
1200		var bTime = !!this.params.bTime && BX.hasClass(this.PARTS.TIME, 'bx-calendar-set-time-opened');
1201
1202		if (this.params.field)
1203		{
1204			var format = BX.message(bTime ? 'FORMAT_DATETIME' : 'FORMAT_DATE');
1205
1206			if(bTime && !this.params.bUseSecond)
1207			{
1208				format = format.replace(':SS', '');
1209			}
1210
1211			this.params.field.value = BX.calendar.ValueToStringFormat(this.value, format, true);
1212			BX.fireEvent(this.params.field, 'change');
1213		}
1214
1215		this.popup.close();
1216
1217		if (!!this.params.callback_after)
1218		{
1219			this.params.callback_after.apply(this, [new Date(this.value.valueOf()+this.value.getTimezoneOffset()*60000), bTime]);
1220		}
1221	}
1222
1223	return this;
1224};
1225
1226BX.JCCalendar.prototype.Close = function()
1227{
1228	if (!!this.popup)
1229		this.popup.close();
1230
1231	return this;
1232};
1233
1234BX.JCSpinner = function(params)
1235{
1236	params = params || {};
1237	this.params = {
1238		input: params.input || null,
1239
1240		delta: params.delta || 1,
1241
1242		timeout_start: params.timeout_start || 1000,
1243		timeout_cont: params.timeout_cont || 150,
1244
1245		callback_start: params.callback_start || null,
1246		callback_change: params.callback_change || null,
1247		callback_finish: params.callback_finish || null,
1248
1249		bSaveValue: typeof params.bSaveValue == 'undefined' ? !!params.input : !!params.bSaveValue
1250	};
1251
1252	this.mousedown = false;
1253	this.direction = 1;
1254};
1255
1256BX.JCSpinner.prototype.Show = function()
1257{
1258	this.node = BX.create('span', {
1259		events: {
1260			mousedown: BX.delegateEvent(
1261				{attr: 'data-dir'},
1262				BX.delegate(this.Start, this)
1263			)
1264		},
1265		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>'
1266	});
1267	return this.node;
1268};
1269
1270BX.JCSpinner.prototype.Start = function()
1271{
1272	this.mousedown = true;
1273	this.direction = BX.proxy_context.getAttribute('data-dir') > 0 ? 1 : -1;
1274	BX.bind(document, "mouseup", BX.proxy(this.MouseUp, this));
1275	this.ChangeValue(true);
1276};
1277
1278BX.JCSpinner.prototype.ChangeValue = function(bFirst)
1279{
1280	if(!this.mousedown)
1281		return;
1282
1283	if (this.params.input)
1284	{
1285		var v = parseInt(this.params.input.value, 10) + this.params.delta * this.direction;
1286
1287		if (this.params.bSaveValue)
1288			this.params.input.value = v;
1289
1290		if (!!bFirst && this.params.callback_start)
1291			this.params.callback_start(this.params, v, this.direction);
1292
1293		if (this.params.callback_change)
1294			this.params.callback_change(this.params, v, this.direction);
1295
1296		setTimeout(
1297			BX.proxy(this.ChangeValue, this),
1298			!!bFirst ? this.params.timeout_start : this.params.timeout_cont
1299		);
1300	}
1301};
1302
1303BX.JCSpinner.prototype.MouseUp = function()
1304{
1305	this.mousedown = false;
1306	BX.unbind(document, "mouseup", BX.proxy(this.MouseUp, this));
1307
1308	if (this.params.callback_finish)
1309		this.params.callback_finish(this.params, this.params.input.value);
1310};
1311
1312/**************** compatibility hacks ***************************/
1313
1314window.jsCalendar = {
1315	Show: function(obj, field, fieldFrom, fieldTo, bTime, serverTime, form_name, bHideTimebar)
1316	{
1317		return BX.calendar({
1318			node: obj, field: field, form: form_name, bTime: !!bTime, currentTime: serverTime, bHideTimebar: !!bHideTimebar
1319		});
1320	},
1321
1322	ValueToString: BX.calendar.ValueToString
1323};
1324
1325
1326/************ clock popup transferred from timeman **************/
1327
1328BX.CClockSelector = function(params)
1329{
1330	this.params = params;
1331
1332	this.params.popup_buttons = this.params.popup_buttons || [
1333		new BX.PopupWindowButton({
1334			text : BX.message('CAL_BUTTON'),
1335			className : "popup-window-button-create",
1336			events : {click : BX.proxy(this.setValue, this)}
1337		})
1338	];
1339
1340	this.isReady = false;
1341
1342	this.WND = new BX.PopupWindow(
1343		this.params.popup_id || 'clock_selector_popup',
1344		this.params.node,
1345		this.params.popup_config || {
1346			titleBar: BX.message('CAL_TIME'),
1347			offsetLeft: -45,
1348			offsetTop: -135,
1349			autoHide: true,
1350			closeIcon: true,
1351			closeByEsc: true,
1352			focusTrap: false,
1353		},
1354	);
1355
1356	this.SHOW = false;
1357	BX.addCustomEvent(this.WND, "onPopupClose", BX.delegate(this.onPopupClose, this));
1358
1359	this.obClocks = {};
1360	this.CLOCK_ID = this.params.clock_id || 'clock_selector';
1361};
1362
1363BX.CClockSelector.prototype.Show = function()
1364{
1365	if (!this.isReady)
1366	{
1367		//BX.timeman.showWait(this.parent.DIV);
1368
1369		BX.addCustomEvent('onClockRegister', BX.proxy(this.onClockRegister, this));
1370		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));
1371	}
1372
1373	this.WND.setButtons(this.params.popup_buttons);
1374	this.WND.show();
1375
1376	this.SHOW = true;
1377
1378	if (window['bxClock_' + this.obClocks[this.CLOCK_ID]])
1379	{
1380		setTimeout("window['bxClock_" + this.obClocks[this.CLOCK_ID] + "'].CalculateCoordinates()", 40);
1381	}
1382
1383	return true;
1384};
1385
1386BX.CClockSelector.prototype.onClockRegister = function(obClocks)
1387{
1388	if (obClocks[this.CLOCK_ID])
1389	{
1390		this.obClocks[this.CLOCK_ID] = obClocks[this.CLOCK_ID];
1391		BX.removeCustomEvent('onClockRegister', BX.proxy(this.onClockRegister, this));
1392	}
1393};
1394
1395BX.CClockSelector.prototype.Ready = function(data)
1396{
1397	this.content = this.CreateContent(data);
1398	this.WND.setContent(this.content);
1399
1400	this.isReady = true;
1401	//BX.timeman.closeWait();
1402
1403	setTimeout(BX.proxy(this.Show, this), 30);
1404};
1405
1406BX.CClockSelector.prototype.CreateContent = function(data)
1407{
1408	return BX.create('DIV', {
1409		events: {click: BX.PreventDefault},
1410		html:
1411			'<div class="bx-tm-popup-clock">' + data + '</div>'
1412	});
1413};
1414
1415BX.CClockSelector.prototype.setValue = function(e)
1416{
1417	if (this.params.callback)
1418	{
1419		var input = BX.findChild(this.content, {tagName: 'INPUT'}, true);
1420		this.params.callback.apply(this.params.node, [input.value]);
1421	}
1422
1423	return BX.PreventDefault(e);
1424};
1425
1426BX.CClockSelector.prototype.closeWnd = function(e)
1427{
1428	this.WND.close();
1429	return (e || window.event) ? BX.PreventDefault(e) : true;
1430};
1431
1432BX.CClockSelector.prototype.setNode = function(node)
1433{
1434	this.WND.setBindElement(node);
1435};
1436
1437BX.CClockSelector.prototype.setTime = function(timestamp)
1438{
1439	this.params.start_time = timestamp;
1440	if (window['bxClock_' + this.obClocks[this.CLOCK_ID]])
1441	{
1442		window['bxClock_' +  this.obClocks[this.CLOCK_ID]].SetTime(parseInt(timestamp/3600), parseInt((timestamp%3600)/60));
1443	}
1444};
1445
1446BX.CClockSelector.prototype.setCallback = function(cb)
1447{
1448	this.params.callback = cb;
1449};
1450
1451BX.CClockSelector.prototype.onPopupClose = function()
1452{
1453	this.SHOW = false;
1454};
1455
1456})();
1457

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.