PageSourceSearch

https://potok.com/bitrix/js/main/core/core_admin_interface.js?1731536645154840

js potok.com collected 2026-10-02 21:43:03 UTC 154,840 bytes, 6,579 lines download raw bytes

1;(function(){
2
3if (!!BX.adminPanel)
4	return;
5
6/*************************** admin panel **************************************/
7
8BX.adminPanel = function()
9{
10	this.buttons = [];
11	this.panel = null;
12
13	this.modifyFormElements = BX.adminFormTools.modifyFormElements;
14	this.modifyFormElement = BX.adminFormTools.modifyFormElement;
15
16	this._showMenu = function(e)
17	{
18		if (this.CONFIG.MENU)
19		{
20			BX.adminShowMenu(this.BUTTON, this.CONFIG.MENU, {active_class: 'adm-header-language-active'});
21		}
22
23		return BX.PreventDefault(e);
24	};
25
26	BX.ready(BX.defer(this.Init, this));
27};
28
29BX.adminPanel.isFixed = BX.False;
30
31BX.adminPanel.prototype.Init = function()
32{
33	this.panel = BX('bx-panel');
34
35	if (!!this.panel)
36	{
37		for (var i = 0; i<this.buttons.length; i++)
38		{
39			this.buttons[i].BUTTON = BX(this.buttons[i].ID);
40			if (this.buttons[i].BUTTON)
41			{
42				if (this.buttons[i].CONFIG.MENU)
43				{
44					this.setButtonMenu(this.buttons[i]);
45				}
46			}
47		}
48
49		(BX.defer(this._recountWrapHeight, this))();
50	}
51};
52
53BX.adminPanel.prototype.registerButton = function(id, config)
54{
55	this.buttons.push({ID: id, CONFIG: config});
56};
57
58BX.adminPanel.prototype.setButtonMenu = function(button)
59{
60	BX.bind(button.BUTTON, 'click', BX.delegate(this._showMenu, button))
61};
62
63BX.adminPanel.prototype.isFixed = function()
64{
65	return (
66		BX.type.isDomNode(this.panel)
67		&& BX.hasClass(document.documentElement, 'adm-header-fixed')
68	);
69};
70
71BX.adminPanel.prototype.Fix = function(el)
72{
73	var bFixed = this.isFixed();
74
75	if (bFixed)
76	{
77		this.panel.parentNode.style.height = 'auto';
78		BX.removeClass(document.documentElement, 'adm-header-fixed');
79		el.title = BX.message('JSADM_PIN_ON');
80	}
81	else
82	{
83		BX.addClass(document.documentElement, 'adm-header-fixed');
84		el.title = BX.message('JSADM_PIN_OFF');
85		(BX.defer(this._recountWrapHeight, this))();
86	}
87
88	BX.userOptions.save('admin_panel', 'settings', 'fix', (bFixed ? 'off':'on'));
89	BX.onCustomEvent('onAdminPanelFix', [!bFixed]);
90};
91
92BX.adminPanel.prototype.addDesktop = function()
93{
94	(new BX.CAdminDialog({
95		'content_url': '/bitrix/components/bitrix/desktop/admin_settings.php?lang='+BX.message('LANGUAGE_ID')+'&bxpublic=Y',
96		'content_post': 'sessid='+BX.bitrix_sessid()+'&type=desktop&desktop_page=0&action=new&desktop_backurl=/bitrix/admin/',
97		'draggable': true,
98		'resizable': true,
99		'buttons': [BX.CAdminDialog.btnSave, BX.CAdminDialog.btnCancel]
100	})).Show();
101};
102
103BX.adminPanel.prototype.recalcDesktopSettingsDialog = function(e)
104{
105	if(!e)
106		e = window.event;
107
108	var col_count = this.value;
109	if (e.type == 'blur' && col_count.length <= 0)
110	{
111		col_count = current_col_count;
112		BX('SETTINGS_COLUMNS').value = col_count;
113	}
114	else if (e.type == 'keyup' && (parseInt(col_count) <= 0	|| parseInt(col_count) >= 10))
115	{
116		current_col_count = col_count = 2;
117		BX('SETTINGS_COLUMNS').value = col_count;
118	}
119	else if (e.type == 'keyup' && col_count.length > 0)
120		current_col_count = col_count;
121
122	var tableNode = BX.findParent(this, {'tag':'tbody'});
123
124	var arItems = BX.findChildren(tableNode, {'tag':'tr', 'class':'bx-gd-admin-settings-col'}, true);
125	if (!arItems)
126		arItems = [];
127
128	for (var i = 0; i < arItems.length; i++)
129	{
130		if (i >= col_count)
131			arItems[i].parentNode.removeChild(arItems[i]);
132	}
133
134	var col_add = col_count - i;
135
136	for (i = 0; i < col_add; i++)
137	{
138		tableNode.appendChild(BX.create('tr', {
139			props: {
140				'className': 'bx-gd-admin-settings-col'
141			},
142			children: [
143				BX.create('td', {
144					attrs: {
145						'width': '40%'
146					},
147					html: BX.message('langGDSettingsDialogRowTitle') + (parseInt(arItems.length) + parseInt(i) + 1)
148				}),
149				BX.create('td', {
150					attrs: {
151						'width': '60%'
152					},
153					children: [
154						BX.create('input', {
155							attrs: {
156								'type': 'text',
157								'size': '5',
158								'maxlength': '6'
159							},
160							props: {
161								'id': 'SETTINGS_COLUMN_WIDTH_' + (arItems.length + i),
162								'name': 'SETTINGS_COLUMN_WIDTH_' + (arItems.length + i),
163								'value': ''
164							}
165						})
166					]
167				})
168			]
169		}));
170	}
171};
172
173BX.adminPanel.prototype.setTitle = function(title)
174{
175	document.title = BX.message('TITLE_PREFIX') + title;
176	var p = BX('adm-title');
177	if (p)
178	{
179		if (p.firstChild && p.firstChild.nodeType == 3)
180		{
181			p.replaceChild(document.createTextNode(title), p.firstChild);
182		}
183		else if (p.firstChild)
184		{
185			p.insertBefore(p.firstChild, document.createTextNode(title));
186		}
187		else
188		{
189			BX.adjust(p, {text: title});
190		}
191	}
192};
193
194BX.adminPanel.prototype._recountWrapHeight = function()
195{
196	if (this.isFixed())
197		BX.adminPanel.panel.parentNode.style.height = BX.adminPanel.panel.offsetHeight + 'px';
198	BX.onCustomEvent(this, 'onAdminPanelChange');
199};
200
201BX.adminPanel.prototype.Notify = function(str)
202{
203	if (!BX.isReady)
204	{
205		var _args = arguments;
206		BX.ready(BX.defer(function() {BX.adminPanel.Notify.apply(this, _args);}));
207		return;
208	}
209
210	if (null == BX.adminPanel.NOTIFY && BX.adminPanel.panel)
211	{
212		BX.adminPanel.NOTIFY = BX.adminPanel.panel.appendChild(BX.create('DIV', {
213			props: {className: 'adm-warning-block'},
214			html:
215				'<span class="adm-warning-text">'+(str||'&nbsp;')+'</span><span class="adm-warning-icon"></span><span onclick="BX.adminPanel.hideNotify(this.parentNode)" class="adm-warning-close"></span>'
216		}));
217
218	}
219	else
220	{
221		if (BX.adminPanel.NOTIFY)
222		{
223			BX.adminPanel.NOTIFY.firstChild.innerHTML = str||'&nbsp;';
224		}
225	}
226
227	BX.removeClass(BX.adminPanel.NOTIFY, 'adm-warning-animate');
228
229	(BX.defer(this._recountWrapHeight, this))();
230	setTimeout(BX.proxy(this._recountWrapHeight, this), 310);
231};
232
233BX.adminPanel.hideNotify =
234BX.adminPanel.prototype.hideNotify = function(element)
235{
236	element = BX.type.isDomNode(element)? element: this;
237
238	if (!!element && !!element.parentNode && !!element.parentNode.parentNode)
239	{
240		element.style.height = element.offsetHeight + "px";
241		setTimeout(function() {BX.addClass(element, 'adm-warning-animate');}, 50);
242	}
243
244	if (BX.type.isDomNode(element) && element.getAttribute('data-ajax') == "Y")
245	{
246		var notifyId = parseInt(element.getAttribute('data-id'));
247		if (notifyId > 0)
248		{
249			BX.ajax({
250				url: '/bitrix/admin/admin_notify.php',
251				method: 'POST',
252				dataType: 'json',
253				data: {'ID' : notifyId, 'sessid': BX.bitrix_sessid()}
254			});
255		}
256	}
257
258	(BX.defer(this._recountWrapHeight, this))();
259	setTimeout(BX.proxy(this._recountWrapHeight, this), 310);
260};
261
262BX.adminPanel.Redirect =
263BX.adminPanel.prototype.Redirect = function(args, url, e)
264{
265	var bShift = false;
266	if(args && args.length > 0)
267		e = args[0];
268	if(!e)
269		e = window.event;
270
271	try{
272		if(e) bShift = e.shiftKey;
273	}catch(e){}
274
275	if(bShift)
276		window.open(url);
277	else
278	{
279		var search = window.location.search;
280		if (search.indexOf("IFRAME_TYPE=PUBLIC_FRAME") !== -1 || search.indexOf("IFRAME_TYPE%3DPUBLIC_FRAME") !== -1)
281		{
282			top.window.location.href=url;
283		}
284		else
285		{
286			window.location.href=url;
287		}
288	}
289};
290
291BX.adminPanel._reShowWait =
292BX.adminPanel.prototype._reShowWait = function()
293{
294	BX.adminPanel.closeWait(this);
295	BX.adminPanel.showWait(this);
296};
297
298BX.adminPanel.showWait =
299BX.adminPanel.prototype.showWait = function(el)
300{
301	if (el && !BX.type.isElementNode(el))
302		el = null;
303	el = el || this;
304
305	if (BX.type.isElementNode(el)
306		&& (el.type == 'button' || el.type == 'submit')
307		&& !!el.name
308		&& BX.util.in_array(el.name.toLowerCase(), ['save', 'apply', 'cancel', 'save_and_add', 'set_filter', 'del_filter', 'template_preview'])
309		)
310	{
311		if (el.disabled == true)
312			return null;
313		BX.defer(function(){el.disabled = true})();
314
315		var bSave = (BX.hasClass(el, 'adm-btn-save') || BX.hasClass(el, 'adm-btn-save')),
316			waiter_parent = BX.findParent(el, BX.is_relative),
317			pos = BX.pos(el, !!waiter_parent);
318
319		el.bxwaiter = (waiter_parent || document.body).appendChild(BX.create('DIV', {
320			props: {className: 'adm-btn-load-img' + (bSave ? '-green' : '')},
321			style: {
322				top: parseInt((pos.bottom + pos.top)/2 - 9) + 'px',
323				left: parseInt((pos.right + pos.left)/2 - 9) + 'px'
324			}
325		}));
326
327		BX.addClass(el, 'adm-btn-load');
328
329		BX.adminPanel.lastWaitElement = el;
330
331		return el.bxwaiter;
332	}
333	return null;
334};
335
336BX.adminPanel.closeWait =
337BX.adminPanel.prototype.closeWait = function(el)
338{
339	if (el && !BX.type.isElementNode(el))
340		el = null;
341	el = el || BX.adminPanel.lastWaitElement || this;
342
343	if (BX.type.isElementNode(el))
344	{
345		if (el.bxwaiter && el.bxwaiter.parentNode)
346		{
347			el.bxwaiter.parentNode.removeChild(el.bxwaiter);
348			el.bxwaiter = null;
349		}
350
351		el.disabled = false;
352		BX.removeClass(el, 'adm-btn-load');
353
354		if (BX.adminPanel.lastWaitElement == el)
355			BX.adminPanel.lastWaitElement = null;
356	}
357
358};
359
360/**************************** admin forms *************************************/
361
362BX.adminFormTools = {
363	modifyFormElements: function(tbl, types)
364	{
365		var el = BX.findFormElements(tbl);
366
367		if (el && el.length > 0)
368		{
369			for (var i = 0; i < el.length; i++)
370			{
371				BX.adminFormTools.modifyFormElement(el[i], types)
372			}
373		}
374	},
375
376	modifyFormElement: function(el, types)
377	{
378		if (typeof types == 'undefined' || !BX.type.isArray(types))
379			types = ['checkbox', 'file'];
380
381		if (el && BX.type.isElementNode(el) && !!el.type)
382		{
383			if (BX.util.in_array('*', types) || BX.util.in_array(el.type, types))
384			{
385				switch(el.type)
386				{
387					case 'checkbox': return BX.adminFormTools.modifyCheckbox(el);
388					case 'file': return BX.adminFormTools.modifyFile(el);
389
390					case 'select-one':
391					case 'select-multiple':
392						return BX.adminFormTools.modifySelect(el);
393
394					case 'button':
395					case 'submit':
396					case 'reset':
397						return BX.adminFormTools.modifyButton(el);
398
399					default: return el;
400				}
401			}
402			else
403			{
404				return el;
405			}
406		}
407		return null;
408	},
409
410	modifyCheckbox: function(el)
411	{
412		if ((!BX.browser.IsIE() || BX.browser.IsIE9()) && BX.type.isElementNode(el) && el.tagName.toUpperCase() == 'INPUT' && el.type.toUpperCase() == 'CHECKBOX')
413		{
414			if (!BX.hasClass(el, 'adm-designed-checkbox') && !BX.hasClass(el, 'ui-ctl-element'))
415			{
416				if (!el.id)
417					el.id = 'designed_checkbox_' + Math.random();
418
419				var label = BX.create('LABEL', {
420					props: {
421						className: 'adm-designed-checkbox-label',
422						htmlFor: el.id,
423						title: el.title
424					}
425				});
426
427				BX.addClass(label, el.className);
428				BX.addClass(el, 'adm-designed-checkbox');
429
430				if (!!el.nextSibling)
431					el.parentNode.insertBefore(label, el.nextSibling);
432				else
433					el.parentNode.appendChild(label);
434			}
435		}
436	},
437
438	modifyFile: function(el)
439	{
440		if (!BX.hasClass(el, 'adm-designed-file') && !el.hasAttribute('data-fileinput'))
441		{
442			var wrap = BX.create('SPAN', {
443				props: {className: 'adm-input-file'},
444				html: '<span>' + (!!el.multiple ? BX.message('JSADM_FILES') : BX.message('JSADM_FILE')) + '</span>'
445			});
446
447			BX.bind(el, 'change', BX.adminFormTools._modified_file_onchange);
448
449			BX.addClass(el, 'adm-designed-file');
450
451			if (el.parentNode)
452				el.parentNode.insertBefore(wrap, el);
453
454			wrap.appendChild(el);
455
456			return wrap;
457		}
458		else
459		{
460			return el;
461		}
462	},
463
464	_modified_file_onchange: function()
465	{
466		var v = this.files || [this.value], s = '';
467		if (!v || v.length <= 0)
468		{
469			s = (!!this.multiple ? BX.message('JSADM_FILES') : BX.message('JSADM_FILE'));
470		}
471		else
472		{
473			s = '';
474			for(var i = 0; i < v.length; i++)
475			{
476				var n = v[i].name || v[i];
477				var p = Math.max(n.lastIndexOf('/'), n.lastIndexOf('\\'));
478				if (p > 0)
479					n = n.substring(p+1, n.length);
480				s += (s == '' ? '' : ', ') + n;
481			}
482		}
483
484		this.parentNode.firstChild.innerHTML = s;
485	},
486
487	// should not be called in modifyFormElements!
488	modifySelect: function(el)
489	{
490		if (BX.type.isElementNode(el) && el.tagName.toUpperCase() == 'SELECT')
491		{
492			if (el.type == 'select-one')
493			{
494				if (!BX.hasClass(el, 'adm-select'))
495				{
496					var wrap = BX.create('SPAN', {
497						props: {className: 'adm-select-wrap'}
498					});
499
500					BX.addClass(el, 'adm-select');
501
502					if (el.parentNode)
503						el.parentNode.insertBefore(wrap, el);
504
505					wrap.appendChild(el);
506
507					return wrap;
508				}
509			}
510		}
511		return null;
512	},
513
514	modifyButton: function(el)
515	{
516		if (BX.type.isElementNode(el) && el.tagName.toUpperCase() == 'INPUT'
517			&& (el.type == 'submit' || el.type == 'reset' || el.type == 'button')
518			&& !BX.hasClass(el, 'adm-btn') && !BX.hasClass(el, 'adm-btn-save') && !BX.hasClass(el, 'adm-btn-green')
519		)
520		{
521			var wrap = BX.create('SPAN', {props: {className: 'adm-btn-wrap ' + el.className}});
522
523			el.className = 'adm-btn';
524
525			if (el.parentNode)
526				el.parentNode.insertBefore(wrap, el);
527
528			wrap.appendChild(el);
529			return wrap;
530		}
531		else
532		{
533			return el;
534		}
535	}
536};
537
538/*************************** admin menu ***************************************/
539
540BX.adminMenu = function()
541{
542	this.activeSection = '';
543	this.oSections = {};
544	this.items = [];
545	this.easing = {};
546
547	var dest = this.dest = {item: null, fav: null};
548	this.dest_cont = {item: null, fav: null};
549
550	this.bMinimized = false;
551
552	var currentDest = null;
553
554	var _admin_fav_callback = function(result){
555		var key = this.BXTYPEKEY;
556		BX('fav_text_' + key).style.display = 'none';
557		if(result)
558		{
559			BX('fav_text_error_' + key).style.display = 'none';
560			BX('fav_text_finish_' + key).style.display = 'inline-block';
561			BX('fav_icon_finish_' + key).style.display = 'inline-block';
562		}
563		else
564		{
565			BX('fav_text_finish_' + key).style.display = 'none';
566			BX('fav_icon_finish_' + key).style.display = 'none';
567			BX('fav_text_error_' + key).style.display = 'inline-block';
568		}
569
570		BX.adminFav.refresh(result);
571
572		this.bxprogress = false;
573		if (!this.bxover)
574		{
575			_ondestdragstop.apply(this);
576		}
577	};
578
579	var _ondestdragfinish = this._ondestdragfinish = {
580		item: BX.delegate(function(node)
581		{
582			if (typeof node.BXMENUITEM == 'undefined' || !this.items[node.BXMENUITEM])
583				return;
584
585			currentDest = 'item';
586			this.dest[currentDest].bxprogress = true;
587
588			var favName = this.items[node.BXMENUITEM].CONFIG.TEXT || node.innerText || node.textContent;
589
590			//adding title before filter name
591			if(this.items[node.BXMENUITEM].CONFIG.TITLE)
592			{
593				var title = BX("adm-title");
594
595				if (title)
596				{
597					var favNameTitle = title.textContent || title.innerText;
598
599					if(favNameTitle)
600						favName = favNameTitle +": "+favName;
601				}
602			}
603
604			BX.adminFav.add(
605				favName,
606				this.items[node.BXMENUITEM].CONFIG.URL,
607				this.items[node.BXMENUITEM].CONFIG.ID,
608				this.items[node.BXMENUITEM].CONFIG.MODULE_ID,
609				BX.proxy(_admin_fav_callback, this.dest.item)
610			);
611
612		}, this),
613		fav: BX.delegate(function(node)
614		{
615			if (typeof node.BXMENUITEM == 'undefined' || !this.items[node.BXMENUITEM] || !this.items[node.BXMENUITEM].CONFIG.FAV_ID)
616				return;
617
618			currentDest = 'fav';
619			this.dest[currentDest].bxprogress = true;
620
621			BX.adminFav.del(this.items[node.BXMENUITEM].CONFIG.FAV_ID, BX.proxy(_admin_fav_callback, this.dest.fav));
622
623		}, this)
624
625	};
626
627	var __r = function(){jsDD.refreshDestArea(this)};
628	var _ondestdragstart = BX.delegate(function(node)
629	{
630		if (typeof node.BXMENUITEM == 'undefined' || !this.items[node.BXMENUITEM])
631			return;
632
633		var key = !!this.items[node.BXMENUITEM].CONFIG.FAV_ID ? 'fav' : 'item';
634
635		this.dest_cont[key].bxprogress = true;
636		BX.adminFav.showDDBlock(this.dest_cont[key], BX.proxy(__r, this.dest[key]));
637
638		BX.bind(window, 'scroll', BX.proxy(__r, this.dest[key]));
639	}, this);
640
641	var _destmsover = function() {this.bxover = true;};
642	var _destmsout = function(){
643		this.bxover = false;
644		setTimeout(BX.delegate(function()
645			{
646				if (!this.bxover && !this.bxprogress)
647					_ondestdragstop.apply(this);
648			}, this), 100);
649	};
650
651	var _ondestdragstop = this._ondestdragstop = BX.delegate(function()
652	{
653		if (!currentDest || currentDest == BX.proxy_context.BXTYPEKEY)
654		{
655			var key = BX.proxy_context.BXTYPEKEY;
656			if (currentDest == BX.proxy_context.BXTYPEKEY)
657			{
658				this.dest_cont.bxover = true;
659
660				BX.bind(BX.proxy_context, 'mouseover', _destmsover);
661				BX.bind(BX.proxy_context, 'mouseout', _destmsout);
662				currentDest = null;
663			}
664			else
665			{
666				BX.adminFav.hideDDBlock(this.dest_cont[key], function() {
667					BX('fav_text_' + key).style.display = 'inline-block';
668					BX('fav_text_error_' + key).style.display = 'none';
669					BX('fav_text_finish_' + key).style.display = 'none';
670					BX('fav_icon_finish_' + key).style.display = 'none';
671				});
672
673				BX.unbind(window, 'scroll', BX.proxy(__r, this.dest[key]));
674
675				BX.unbind(BX.proxy_context, 'mouseover', _destmsover);
676				BX.unbind(BX.proxy_context, 'mouseout', _destmsout);
677
678				BX.unbind(this.dest_cont[key], 'mouseout', BX.proxy(_ondestdragstop, BX.proxy_context));
679			}
680		}
681	}, this);
682
683	this._onitemdragstart = function()
684	{
685		_ondestdragstart(this.NODE);
686
687		if (null == this.MIRROR)
688		{
689			this.MIRROR = document.body.appendChild(BX.create('DIV', {
690				props: {
691					className: BX.hasClass(this.NODE, 'adm-main-menu-item')
692						? 'adm-favorites-main-menu-wrap' : 'adm-favorites-sub-menu-wrap'
693				},
694				html: this.NODE.outerHTML||this.NODE.innerHTML
695			}));
696		}
697
698		this.MIRROR.style.display = 'block';
699	};
700
701	this._onitemdrag = function(x, y)
702	{
703		var wndSize = BX.GetWindowSize();
704
705		var top = parseInt(y - this.MIRROR.offsetHeight/2),
706			left = parseInt(x - this.MIRROR.offsetWidth/2);
707
708		var leftBorder = wndSize.scrollLeft + wndSize.innerWidth-20;
709
710		if (left + this.MIRROR.offsetWidth > leftBorder)
711			left -= left + this.MIRROR.offsetWidth - leftBorder;
712		if (left <= wndSize.scrollLeft)
713			left = wndSize.scrollLeft;
714
715		this.MIRROR.style.left = left + 'px';
716		this.MIRROR.style.top = top + 'px';
717	};
718
719	this._onitemdragstop = function()
720	{
721		this.MIRROR.style.display = 'none';
722	};
723
724	BX.ready(BX.delegate(this.Init, this));
725};
726
727BX.adminMenu.prototype.Init = function()
728{
729	if (!!BX('bx_menu_panel', true))
730	{
731		for (var key in this.dest)
732		{
733			if (!BX('fav_dest_' + key) || !BX('fav_cont_' + key))
734			{
735				continue;
736			}
737
738			this.dest[key] = BX('fav_dest_' + key);
739			this.dest_cont[key] = BX('fav_cont_' + key);
740
741			this.dest[key].BXTYPEKEY = key;
742			this.dest[key].onbxdestdraghover = function() {BX.addClass(this, 'adm-favorites-center-hover')};
743			this.dest[key].onbxdestdraghout = function() {BX.removeClass(this, 'adm-favorites-center-hover')};
744			this.dest[key].onbxdestdragfinish = this._ondestdragfinish[key];
745			this.dest[key].onbxdestdragstop = BX.proxy(this._ondestdragstop, this.dest[key]);
746
747			jsDD.registerDest(this.dest[key]);
748		}
749
750		setTimeout(BX.delegate(this.InitDeferred, this), 200);
751	}
752};
753
754BX.adminMenu.prototype.InitDeferred = function()
755{
756	new BX.adminMenuResizer(BX('bx_menu_panel', true), !!this.bMinimized);
757
758	for(var i=0; i<this.items.length; i++)
759	{
760		this._registerItem(i);
761	}
762};
763
764BX.adminMenu.prototype.showFavorites = function(el)
765{
766	if(!!el)
767		BX.fireEvent(el, 'mouseout');
768
769	this.GlobalMenuClick('desktop');
770
771	if (BX.adminFav.lastId > 0)
772	{
773		var node = BX.findChild(BX('_global_menu_desktop'), {attr: {
774			'data-fav-id': BX.adminFav.lastId
775		}}, true);
776
777		if (!!node)
778		{
779			BX.defer(function(){
780				var pos = BX.pos(node),
781					wndSize = BX.GetWindowSize(),
782					scrollBottom = wndSize.scrollTop + wndSize.innerHeight;
783
784				if (pos.bottom > scrollBottom || pos.top < wndSize.scrollTop)
785				{
786					window.scrollTo(wndSize.scrollLeft, pos.top - parseInt(wndSize.innerHeight/2));
787				}
788
789				BX.addClass(node, 'adm-submenu-current-fav');
790				(new BX.easing({
791					duration : 1200,
792					start:{opacity: 0},
793					finish:{opacity: 100},
794					transition: function(progress) {
795						return Math.abs(Math.sin(3 * Math.PI * progress / 2));
796					},
797					step : function(state){
798						node.style.background = 'rgba(242,245,220,'+(state.opacity/100)+')'
799					},
800					complete: function()
801					{
802						node.style.background = '#f2f5dc';
803						var f = function(){
804							this.style.background = null;
805							BX.removeClass(this, 'adm-submenu-current-fav');
806							BX.unbind(this, 'mouseover', f);
807						};
808						BX.bind(node, 'mouseover', f);
809					}
810				})).animate();
811			})();
812		}
813	}
814};
815
816BX.adminMenu.prototype.itemsStretchScroll = function()
817{
818	this.items.forEach(function(item) {
819		if (item && item.MSOVERMIRROR)
820		{
821			item.MSOVERMIRROR.style.display = 'none';
822		}
823	});
824};
825
826BX.adminMenu.prototype.setMinimizedState = function(state)
827{
828	this.bMinimized = state;
829};
830
831BX.adminMenu.prototype.setActiveSection = function(section_id)
832{
833	this.activeSection = section_id;
834};
835
836BX.adminMenu.prototype.setOpenedSections = function(sSections)
837{
838	var aSect = sSections.split(',');
839	for(var i in aSect)
840	{
841		this.oSections[aSect[i]] = true;
842	}
843};
844
845BX.adminMenu.prototype.GlobalMenuClick = function(id)
846{
847	if (id == this.activeSection)
848	{
849		return;
850	}
851
852	if (!!this.activeSection)
853	{
854		BX.removeClass(BX('global_menu_' + this.activeSection, true), 'adm-main-menu-item-active');
855		//BX.hide(BX('global_submenu_' + this.activeSection, true));
856		BX.removeClass(BX('global_submenu_' + this.activeSection, true), "adm-global-submenu-active adm-global-submenu-animate");
857	}
858
859	this.activeSection = id;
860
861	BX.addClass(BX('global_menu_' + this.activeSection, true), 'adm-main-menu-item-active');
862	//BX.show(BX('global_submenu_' + this.activeSection, true));
863	BX.addClass(BX('global_submenu_' + this.activeSection, true), "adm-global-submenu-active");
864
865	if (BX.browser.isPropertySupported("transition"))
866	{
867		BX('global_submenu_' + id, true).style.opacity = 0;
868		setTimeout(function() { BX.addClass(BX('global_submenu_' + id, true), "adm-global-submenu-animate"); }, 0);
869	}
870
871	BX.onCustomEvent(this, 'onMenuChange');
872};
873
874BX.adminMenu.prototype.startAnimation = function(cell, div_id, opening)
875{
876	if (!this.easing[div_id])
877	{
878		this.easing[div_id] = {
879			icon : BX.findChild(cell, { className : "adm-submenu-item-arrow-icon"}, true),
880			animation : null,
881			opening : opening,
882			childrenCont: cell.childNodes[1],
883			startHeight : 0
884		};
885	}
886
887	if (this.easing[div_id].animation)
888		this.easing[div_id].animation.stop();
889
890	this.easing[div_id].opening = opening;
891	this.easing[div_id].startHeight = this.easing[div_id].childrenCont.offsetHeight;
892	this.easing[div_id].childrenCont.style.overflowY = "hidden";
893	this.easing[div_id].childrenCont.style.height = this.easing[div_id].startHeight + "px";
894
895	BX.addClass(this.easing[div_id].childrenCont, "adm-sub-submenu-block-children-animate");
896
897	if (BX.browser.isPropertySupported("transform"))
898		BX.addClass(this.easing[div_id].icon, "adm-submenu-item-arrow-icon-animate");
899};
900
901BX.adminMenu.prototype.endAnimation = function(div_id)
902{
903	if (!this.easing[div_id])
904		return;
905
906	var opening = this.easing[div_id].opening;
907	var arrowIcon = this.easing[div_id].icon;
908	var divCont = this.easing[div_id].childrenCont;
909	var rotateProperty = BX.browser.isPropertySupported("transform");
910
911	this.easing[div_id].animation = new BX.easing({
912
913		duration : 200,
914
915		start : {
916			rotation: 0,
917			height : this.easing[div_id].startHeight,
918			opacity : opening ? 0 : 100
919		},
920
921		finish : {
922			rotation: opening ? 90 : -90,
923			height : opening ? this.easing[div_id].childrenCont.scrollHeight : 0,
924			opacity : opening ? 100 : 0
925		},
926
927		transition : BX.easing.transitions.linear,
928
929		step : function(state) {
930
931			if (rotateProperty !== false)
932			{
933				arrowIcon.style[rotateProperty] = "rotate(" + state.rotation + "deg)" +
934					(rotateProperty == "WebkitTransform" ? " translate3d(0, 0, 0)" : "" );
935			}
936
937			divCont.style.height = state.height + "px";
938			divCont.style.opacity = state.opacity/100;
939		},
940
941		complete : BX.proxy(function() {
942			arrowIcon.style.cssText = "";
943			divCont.style.cssText = "";
944			BX.removeClass(arrowIcon, "adm-submenu-item-arrow-icon-animate");
945			BX.removeClass(divCont, "adm-sub-submenu-block-children-animate");
946			this.easing[div_id].animation = null;
947		}, this)
948	});
949
950	this.easing[div_id].animation.animate();
951};
952
953BX.adminMenu.prototype.toggleSection = function(cell, div_id, level)
954{
955	var res = !BX.hasClass(cell, 'adm-sub-submenu-open');
956
957	this.startAnimation(cell, div_id, res);
958
959	if (res)
960		BX.addClass(cell, 'adm-sub-submenu-open');
961	else
962		BX.removeClass(cell, 'adm-sub-submenu-open');
963
964	this.endAnimation(div_id);
965
966	if(level <= 2)
967	{
968		this.oSections[div_id] = res;
969
970		var sect='';
971		for(var i in this.oSections)
972		{
973			if(this.oSections[i] == true)
974			{
975				sect += (sect != ''? ',':'')+i;
976			}
977		}
978
979		BX.userOptions.save('admin_menu', 'pos', 'sections', sect);
980	}
981
982	BX.onCustomEvent(this, 'onMenuChange');
983
984	return res;
985};
986
987BX.adminMenu.prototype.toggleDynSection = function(padding, cell, module_id, div_id, level)
988{
989	if (cell.BXLOAD)
990	{
991		this.toggleSection(cell, div_id, level);
992		return;
993	}
994
995	cell.BXLOAD = true;
996	cell.BXLOAD_AJAX = false;
997
998	var img = BX.create('SPAN', {
999		props: {className: 'adm-submenu-loading adm-sub-submenu-block'},
1000		style: {marginLeft: parseInt(padding) + 'px'},
1001		text: BX.message('JS_CORE_LOADING')
1002	});
1003
1004	setTimeout(BX.proxy(function() {
1005		if (!cell.BXLOAD_AJAX)
1006		{
1007			cell.childNodes[1].appendChild(img);
1008			this.toggleSection(cell, div_id, level);
1009		}
1010	}, this), 200);
1011
1012	BX.ajax.get(
1013		'/bitrix/admin/get_menu.php',
1014		{
1015			lang: BX.message('LANGUAGE_ID'),
1016			admin_mnu_module_id: module_id,
1017			admin_mnu_menu_id: div_id
1018		},
1019		BX.proxy(function(result)
1020		{
1021			cell.BXLOAD_AJAX = true;
1022			result = BX.util.trim(result);
1023			if (result != '')
1024			{
1025				var toggleExecuted = img.parentNode ? true : false;
1026				cell.childNodes[1].innerHTML = result;
1027				if (!toggleExecuted)
1028					this.toggleSection(cell, div_id, level);
1029			}
1030			else
1031			{
1032				img.innerHTML = BX.message('JS_CORE_NO_DATA');
1033				if (!img.parentNode)
1034				{
1035					cell.childNodes[1].appendChild(img);
1036					this.toggleSection(cell, div_id, level);
1037				}
1038			}
1039			BX.onCustomEvent(this, 'onMenuChange');
1040		}, this)
1041	);
1042
1043};
1044
1045BX.adminMenu.prototype._item_onmouseover = function()
1046{
1047	this.bxover = true;
1048	setTimeout(BX.proxy(BX.adminMenu.__item_onmouseover, this), 500);
1049};
1050
1051BX.adminMenu.prototype._item_onmouseout = function()
1052{
1053	this.bxover = false;
1054	setTimeout(BX.proxy(BX.adminMenu.__item_onmouseout, this), 50);
1055};
1056
1057BX.adminMenu.prototype.__item_onmouseover = function()
1058{
1059	if (this.bxover)
1060	{
1061		var pos1 = BX.pos(this.NODE.lastChild.lastChild);
1062
1063		if (pos1.right > BX('bx_menu_panel', true).offsetWidth)
1064		{
1065			var pos = BX.pos(this.NODE);
1066
1067			if (!this.MSOVERMIRROR)
1068			{
1069				var bActive = BX.hasClass(this.NODE.parentNode, 'adm-submenu-item-active');
1070				this.MSOVERMIRROR = BX('menu_mirrors_cont').appendChild(BX.create('DIV', {
1071					props: {
1072						className: 'adm-submenu-longname' + (bActive ? ' adm-submenu-active-longname' : '')
1073					},
1074					html: this.NODE.outerHTML||this.NODE.innerHTML
1075				}));
1076			}
1077
1078			BX.adjust(this.MSOVERMIRROR, {
1079				style: {
1080					top: pos.top + 'px',
1081					left: pos.left + 'px',
1082					height: pos.height + 'px',
1083					display: 'inline-block'
1084				}
1085			});
1086		}
1087	}
1088};
1089
1090BX.adminMenu.prototype.__item_onmouseout = function()
1091{
1092	if (!this.bxover && !!this.MSOVERMIRROR)
1093	{
1094		this.MSOVERMIRROR.style.display = 'none';
1095	}
1096};
1097
1098BX.adminMenu.prototype._registerItem = function(i)
1099{
1100	this.items[i].NODE = BX(this.items[i].ID) ? BX(this.items[i].ID) : top.BX(this.items[i].ID);
1101	this.items[i].NODE.BXMENUITEM = i;
1102	if (this.items[i].NODE)
1103	{
1104		this.items[i].NODE.onbxdragstart = BX.delegate(this._onitemdragstart, this.items[i]);
1105		this.items[i].NODE.onbxdrag = BX.delegate(this._onitemdrag, this.items[i]);
1106		this.items[i].NODE.onbxdragstop = BX.delegate(this._onitemdragstop, this.items[i]);
1107
1108		jsDD.registerObject(this.items[i].NODE)
1109	}
1110
1111	var itemType = this.items[i].NODE.getAttribute('data-type');
1112	switch(itemType)
1113	{
1114		case 'submenu-item':
1115			BX.bind(this.items[i].NODE, 'mouseover', BX.proxy(this._item_onmouseover, this.items[i]));
1116			BX.bind(this.items[i].NODE, 'mouseout', BX.proxy(this._item_onmouseout, this.items[i]));
1117		break;
1118	}
1119};
1120
1121BX.adminMenu.prototype.registerItem = function(id, config)
1122{
1123	this.items.push({ID: id, CONFIG: config});
1124
1125	if (BX.isReady)
1126	{
1127		this._registerItem(this.items.length-1);
1128	}
1129};
1130
1131/*************************** admin menu resizer *******************************/
1132
1133BX.adminMenuResizer = function(node, startState)
1134{
1135	this.node = node;
1136	this.bMinimized = !!startState;
1137
1138	this.min_width = 70;
1139	this.denySave = false;
1140
1141	this.scrollLeft = 0;
1142
1143	this.pos = this.pos_final = parseInt(this.node.getAttribute('data-width')) || parseInt(BX.style(this.node, 'width'));
1144
1145	this.dragger = document.body.appendChild(BX.create('DIV', {
1146		props: {className: 'adm-resize-block' + (this.bMinimized ? ' adm-resize-block-close' : '')},
1147		events: {
1148			mouseover: function(){
1149				if (!this.bDrag)
1150				{
1151					var el = this;
1152					el.bxover = true;
1153					setTimeout(function(){
1154						if(el.bxover && !el.bDrag)
1155							BX.addClass(el, 'adm-resize-block-hover');
1156					}, 100);
1157				}
1158			},
1159			mouseout: function(){
1160				var el = this;
1161				el.bxover = false;
1162				setTimeout(function(){
1163					if(!el.bxover)
1164						BX.removeClass(el, 'adm-resize-block-hover');
1165				}, 50);
1166			}
1167		},
1168		style: {left: (this.bMinimized ? 10 : this.pos_final-5) + 'px'}
1169	}));
1170
1171	this.minimizer = this.dragger.appendChild(BX.create('DIV', {
1172		props: {
1173			className: 'adm-resizer-btn' + (this.bMinimized ? ' adm-resizer-btn-close' : '')
1174		},
1175		style: {left: (this.bMinimized ? 10 : this.pos_final-5) + 'px'},
1176		events: {
1177			click: BX.proxy(this.Minimize, this),
1178			mousedown: BX.eventCancelBubble
1179		}
1180	}));
1181
1182	BX.bind(this.dragger, 'dblclick', BX.proxy(this.Minimize, this));
1183
1184	this.dragger.onbxdragstart = BX.delegate(this.Start, this);
1185	this.dragger.onbxdrag = BX.delegate(this.Drag, this);
1186	this.dragger.onbxdragstop = BX.delegate(this.Save, this);
1187
1188	jsDD.registerObject(this.dragger);
1189
1190	BX.bind(window, 'scroll', BX.delegate(this.setDraggerPos, this));
1191	BX.bind(window, 'resize', BX.delegate(this.setDraggerPos, this));
1192	this.setDraggerPos();
1193};
1194
1195BX.adminMenuResizer.prototype.setDraggerPos = function()
1196{
1197	this.scrollLeft = BX.GetWindowScrollPos().scrollLeft;
1198	this.dragger.style.left = this.minimizer.style.left = ((this.bMinimized ? 10 : this.pos-5) - this.scrollLeft) + 'px';
1199};
1200
1201BX.adminMenuResizer.prototype.Start = function()
1202{
1203	if (this.bMinimized)
1204		BX.removeClass(BX.firstChild(this.node), 'adm-main-menu-close');
1205
1206	BX.setUnselectable(document.body);
1207	document.body.style.cursor = 'e-resize';
1208
1209	this.dragger.bDrag = true;
1210	BX.removeClass(this.dragger, 'adm-resize-block-hover');
1211};
1212
1213BX.adminMenuResizer.prototype.Drag = function(x, y)
1214{
1215	if (x >= this.min_width || this.bMinimized)
1216	{
1217		this.denySave = x < this.min_width;
1218
1219		BX.removeClass(this.dragger, 'adm-resize-block-close');
1220		BX.removeClass(this.minimizer, 'adm-resizer-btn-close');
1221
1222		if (this.bMinimized && !this.denySave)
1223		{
1224			BX.removeClass(this.node, 'adm-left-side-wrap-close');
1225			this.bMinimized = false;
1226		}
1227
1228		this.pos = x;
1229		this.node.style.width = this.pos + 'px';
1230		this.setDraggerPos();
1231	}
1232	else if (!this.bMinimized)
1233	{
1234		this.Minimize();
1235		jsDD.stopCurrentDrag();
1236	}
1237
1238	BX.onCustomEvent(BX.adminMenu, 'onAdminMenuResize', [this.pos]);
1239};
1240
1241BX.adminMenuResizer.prototype.Save = function()
1242{
1243	this.dragger.bDrag = false;
1244
1245	if (!this.denySave && !this.bMinimized)
1246	{
1247		this.pos_final = this.pos;
1248	}
1249
1250	if (this.denySave)
1251	{
1252		if (this.bMinimized)
1253			this.Maximize();
1254
1255		this.denySave = false;
1256	}
1257
1258	if (!this.denySave)
1259	{
1260		BX.onCustomEvent(BX.adminMenu, 'onAdminMenuResize', [this.pos]);
1261
1262		BX.setSelectable(document.body);
1263		document.body.style.cursor = '';
1264
1265		// check BX.fireEvent()
1266		if(window.onresize)
1267			window.onresize();
1268
1269		if (!this.bMinimized)
1270			BX.userOptions.save('admin_menu', 'pos', 'width', this.pos_final);
1271
1272		BX.userOptions.save('admin_menu', 'pos', 'ver', this.bMinimized ? 'off' : 'on');
1273	}
1274};
1275
1276BX.adminMenuResizer.prototype.Minimize = function()
1277{
1278	if (this.bMinimized)
1279		return this.Maximize();
1280
1281	BX.addClass(this.minimizer, 'adm-resizer-btn-animate');
1282	BX.addClass(this.node, 'adm-left-side-wrap-close');
1283
1284	var easing = new BX.easing({
1285		duration : 400,
1286		start:{width: this.pos},
1287		finish:{width: 15},
1288		transition: BX.easing.makeEaseOut(BX.easing.transitions.quart),
1289		step : BX.delegate(function(state){
1290			this.node.style.width = state.width + 'px';
1291			this.dragger.style.left = this.minimizer.style.left = (state.width-5-this.scrollLeft) + 'px';
1292
1293			BX.onCustomEvent(BX.adminMenu, 'onAdminMenuResize', [state.width]);
1294		}, this),
1295		complete: BX.delegate(function(){
1296			this.pos = this.pos_final;
1297
1298			BX.addClass(this.minimizer, 'adm-resizer-btn-close');
1299			BX.removeClass(this.minimizer, 'adm-resizer-btn-animate');
1300
1301			BX.addClass(this.dragger, 'adm-resize-block-close');
1302			BX.addClass(BX.firstChild(this.node), 'adm-main-menu-close');
1303
1304			BX.onCustomEvent(BX.adminMenu, 'onAdminMenuResize', [this.pos]);
1305		}, this)
1306	});
1307	easing.animate();
1308
1309	this.bMinimized = true;
1310	this.Save();
1311};
1312
1313BX.adminMenuResizer.prototype.Maximize = function()
1314{
1315	BX.addClass(this.minimizer, 'adm-resizer-btn-animate');
1316	BX.removeClass(this.node, 'adm-left-side-wrap-close');
1317	BX.removeClass(this.dragger, 'adm-resize-block-close');
1318
1319	BX.removeClass(BX.firstChild(this.node), 'adm-main-menu-close');
1320
1321	var easing = new BX.easing({
1322		duration : 400,
1323		start:{width: this.pos < this.min_width ? this.pos : 15},
1324		finish:{width: this.pos_final},
1325		transition: BX.easing.makeEaseOut(BX.easing.transitions.quart),
1326		step : BX.delegate(function(state){
1327			this.node.style.width = state.width + 'px';
1328			this.dragger.style.left = this.minimizer.style.left = (state.
1328width-5-this.scrollLeft) + 'px';
1329
1330			BX.onCustomEvent(BX.adminMenu, 'onAdminMenuResize', [state.width]);
1331		}, this),
1332		complete: BX.delegate(function(){
1333			BX.removeClass(this.minimizer, 'adm-resizer-btn-close');
1334			BX.removeClass(this.minimizer, 'adm-resizer-btn-animate');
1335
1336			BX.onCustomEvent(BX.adminMenu, 'onAdminMenuResize', [15]);
1337		}, this)
1338	});
1339	easing.animate();
1340
1341	this.bMinimized = false;
1342	this.Save();
1343};
1344
1345/*************************** admin favorites **********************************/
1346
1347BX.adminFav = {
1348	url: '/bitrix/admin/favorite_act.php',
1349	lastId: null,
1350	add: function(nameToSave,urlToSave,menu_id,module_id,callback)
1351	{
1352		var urlToSend = BX.adminFav.url + "?act=add&lang="+BX.message('LANGUAGE_ID'),
1353			data = {
1354				sessid: BX.bitrix_sessid(),
1355				name: nameToSave
1356			};
1357
1358		if(urlToSave)
1359			data.addurl = urlToSave;
1360
1361		if(menu_id)
1362			data.menu_id = menu_id;
1363
1364		if (BX.type.isFunction(module_id))
1365		{
1366			callback = module_id;
1367			module_id = '';
1368		}
1369
1370		if(module_id)
1371		{
1372			data.module_id = module_id;
1373		}
1374
1375		if(!callback)
1376		{
1377			callback = function(result)
1378			{
1379				if(result)
1380				{
1381					BX.adminFav.refresh(result);
1382					alert(BX.message('JSADM_FAV_ADD_SUC'));
1383				}
1384				else
1385				{
1386					alert(BX.message('JSADM_FAV_ADD_ERR'));
1387				}
1388			}
1389		}
1390
1391		return BX.ajax.post(urlToSend,data,callback);
1392	},
1393
1394	del: function(id, callback)
1395	{
1396		var urlToSend = BX.adminFav.url + "?act=delete&id="+id,
1397			data = {sessid: BX.bitrix_sessid()};
1398
1399		if(!callback)
1400		{
1401			callback = function(result)
1402			{
1403				if(result)
1404				{
1405					BX.adminFav.refresh(result);
1406					alert(BX.message('JSADM_FAV_DEL_SUC'));
1407				}
1408				else
1409				{
1410					alert(BX.message('JSADM_FAV_DEL_ERR'));
1411				}
1412			}
1413		}
1414
1415		return BX.ajax.post(urlToSend,data,callback);
1416	},
1417
1418	refresh: function(htmlMenu)
1419	{
1420		if(!htmlMenu)
1421			return;
1422
1423		var menu = BX("_global_menu_desktop") ? BX("_global_menu_desktop") : top.BX("_global_menu_desktop");
1424		menu.innerHTML = htmlMenu;
1425
1426		BX.adminFav.setActiveItem();
1427	},
1428
1429	setActiveItem: function()
1430	{
1431		var menu = BX("menucontainer");
1432		var activeItem = BX.findChild(menu, { className: "adm-submenu-item-active"}, true);
1433
1434		if(!activeItem)
1435			return false;
1436
1437		var itemNameLink = BX.findChild(activeItem, { className: "adm-submenu-item-name-link"}, true).href;
1438		var itemNameLinkText = BX.findChild(activeItem, { className: "adm-submenu-item-name-link-text"}, true);
1439
1440		var itemText = itemNameLinkText.textContent || itemNameLinkText.innerText;
1441		itemText =  BX.util.trim(itemText);
1442
1443		var favMenu = BX("_global_menu_desktop");
1444
1445		var favMenuItems = BX.findChildren(favMenu, { className: "adm-sub-submenu-block"}, true);
1446
1447		for(var idx in favMenuItems)
1448		{
1449			var favItemNameLink = BX.findChild(favMenuItems[idx], { className: "adm-submenu-item-name-link"},true).href;
1450			var favItemNameLinkText = BX.findChild(favMenuItems[idx], { className: "adm-submenu-item-name-link-text"}, true);
1451			var favItemText = favItemNameLinkText.textContent || favItemNameLinkText.innerText;
1452			favItemText = BX.util.trim(favItemText);
1453
1454			if((favItemNameLink == itemNameLink) && itemNameLink != "javascript:void(0)")
1455			{
1456				BX.addClass(favMenuItems[idx],"adm-submenu-item-active");
1457				return true;
1458			}
1459
1460			if(itemText && itemText == favItemText)
1461			{
1462				BX.addClass(favMenuItems[idx],"adm-submenu-item-active");
1463				return true;
1464			}
1465		}
1466
1467		return false;
1468	},
1469
1470	setLastId: function(id)
1471	{
1472		BX.adminFav.lastId = id;
1473	},
1474
1475	titleLinkClick: function(el, fav_id, items_id)
1476	{
1477		BX.adminFav.titleLink = el;
1478		BX.adminFav.titleNode = el.parentNode;
1479
1480		if (!el.BXFAVSET)
1481		{
1482			el.BXFAVID = fav_id;
1483			el.BXITEMSID = items_id;
1484
1485			if (!!el.BXFAVID)
1486				BX.adminFav._titleLinkClickDel();
1487			else
1488				BX.adminFav._titleLinkClickAdd();
1489
1490			el.BXFAVSET = true;
1491		}
1492	},
1493
1494	_titleLinkClickAdd: function()
1495	{
1496		BX.adminFav.add(
1497			BX.adminFav.titleNode.textContent||BX.adminFav.titleNode.innerText,
1498			BX.adminHistory.pushSupported ? window.location.pathname+window.location.search : BX('navchain-link').getAttribute('href'),
1499			BX.adminFav.titleLink.BXITEMSID,
1500			'',
1501			function(result) {
1502				if (result)
1503				{
1504					BX.adminFav.refresh(result);
1505
1506					// we should somehow get fav_id here
1507					BX.adminFav.titleLink.BXFAVID = BX.adminFav.lastId;
1508
1509					BX.addClass(BX.adminFav.titleLink, 'adm-fav-link-active');
1510					BX.adminFav.titleLink.title = BX.message('JSADM_FAV_DEL');
1511
1512					BX.unbind(BX.adminFav.titleLink, 'click', BX.adminFav._titleLinkClickAdd);
1513					BX.bind(BX.adminFav.titleLink, 'click', BX.adminFav._titleLinkClickDel);
1514				}
1515				else
1516				{
1517					alert(BX.message('JSADM_FAV_ADD_ERR'));
1518				}
1519			}
1520		);
1521	},
1522
1523	_titleLinkClickDel: function()
1524	{
1525		BX.adminFav.del(
1526			BX.adminFav.titleLink.BXFAVID,
1527			function(result) {
1528				if (result)
1529				{
1530					BX.adminFav.refresh(result);
1531					BX.removeClass(BX.adminFav.titleLink, 'adm-fav-link-active');
1532					BX.adminFav.titleLink.removeAttribute('data-fav-id');
1533					BX.adminFav.titleLink.title = BX.message('JSADM_FAV_ADD');
1534
1535					BX.unbind(BX.adminFav.titleLink, 'click', BX.adminFav._titleLinkClickDel);
1536					BX.bind(BX.adminFav.titleLink, 'click', BX.adminFav._titleLinkClickAdd);
1537				}
1538				else
1539				{
1540					alert(BX.message('JSADM_FAV_DEL_ERR'));
1541				}
1542			}
1543		);
1544	},
1545
1546	onMenuChange: function()
1547	{
1548		if(BX.adminMenu.activeSection =='desktop')
1549			BX.userOptions.save('favorite', 'favorite_menu', 'stick', "Y");
1550		else
1551			BX.userOptions.save('favorite', 'favorite_menu', 'stick', "N");
1552	},
1553
1554	showDDBlock: function(obj, callback)
1555	{
1556		if (!obj.BXVISIBLE)
1557		{
1558			obj.style.display = '';
1559
1560			var start = {property: 0},
1561				finish = {property: -100},
1562
1563				text1 = 'translate(',
1564				text2 = '%,0)',
1565
1566				attr = BX.browser.isPropertySupported('transform');
1567
1568			if (BX.browser.IsIE10())
1569			{
1570				start.property = 0;
1571				finish.property = 33;
1572				attr = 'right';
1573				text1 = '';
1574				text2 = '%';
1575			}
1576			// FF has rendering bugs in this case
1577			else if (!attr || BX.browser.IsFirefox())
1578			{
1579				start.property = -33;
1580				finish.property = 0;
1581				attr = 'right';
1582				text1 = '';
1583				text2 = '%';
1584			}
1585
1586			var easing = new BX.easing({
1587				duration : 500,
1588				start:start,
1589				finish:finish,
1590				complete: callback,
1591				transition : BX.easing.makeEaseInOut(BX.easing.transitions.quart),
1592
1593				step : function(state)
1594				{
1595					obj.style[attr] = text1 + state.property + text2;
1596				}
1597			});
1598
1599			easing.animate();
1600			obj.BXVISIBLE = true;
1601		}
1602	},
1603
1604	hideDDBlock: function(obj, callback)
1605	{
1606		if(obj.BXVISIBLE)
1607		{
1608			var start = {property: -100},
1609				finish = {property: 0},
1610
1611				text1 = 'translate(',
1612				text2 = '%,0)',
1613
1614				attr = BX.browser.isPropertySupported('transform');
1615
1616			if (BX.browser.IsIE10())
1617			{
1618				start.property = 33;
1619				finish.property = -2;
1620				attr = 'right';
1621				text1 = '';
1622				text2 = '%';
1623			}
1624			// FF has rendering bugs in this case
1625			else if (!attr || BX.browser.IsFirefox())
1626			{
1627				start.property = 0;
1628				finish.property = -35;
1629				attr = 'right';
1630				text1 = '';
1631				text2 = '%';
1632			}
1633
1634			var easing = new BX.easing({
1635				duration : 500,
1636				start:start,
1637				finish:finish,
1638				complete: function() {
1639					obj.style.display = 'none';
1640					if (callback)
1641						callback();
1642				},
1643				transition : BX.easing.makeEaseInOut(BX.easing.transitions.quart),
1644
1645				step : function(state){
1646					obj.style[attr] = text1 + state.property + text2;
1647				}
1648			});
1649
1650			easing.animate();
1651			obj.BXVISIBLE = false;
1652		}
1653	},
1654
1655	closeHint: function(obj)
1656	{
1657		obj.parentNode.style.display = "none";
1658		BX.userOptions.save('favorites_menu', "hint", "hide", "Y");
1659	}
1660};
1661
1662/**************************** admin grid ********************************/
1663
1664BX.adminList = function(table_id, params)
1665{
1666	this.table_id = table_id;
1667	this.params = {
1668		context_ctrl: !!(params||{}).context_ctrl,
1669		context_menu: !!(params||{}).context_menu,
1670		FIX_HEADER: !!(params||{}).FIX_HEADER,
1671		FIX_FOOTER: !!(params||{}).FIX_FOOTER
1672	};
1673
1674	this.TABLE = null;
1675	this.CHECKBOX = [];
1676	this.CHECKBOX_DISABLED = [];
1677	this.CHECKBOX_COUNTER = null;
1678
1679	this.num_checked = 0;
1680	this.bSelectAllChecked = false;
1681	this._last_row = null;
1682
1683	BX.ready(BX.defer(this.Init, this));
1684	BX.garbage(BX.proxy(this.Destroy, this));
1685};
1686
1687BX.adminList.prototype.Init = function()
1688{
1689	this.TABLE = BX(this.table_id);
1690
1691	this.LAYOUT = BX(this.table_id + '_result_div');
1692	this.FOOTER = BX(this.table_id + '_footer');
1693	this.FOOTER_EDIT = BX(this.table_id + '_footer_edit');
1694	this.FORM = document.forms['form_' + this.table_id];
1695
1696	this.CHECKBOX_COUNTER = BX(this.table_id + '_selected_count');
1697
1698	this.BUTTON_EDIT = BX('action_edit_button');
1699	this.BUTTON_DELETE = BX('action_delete_button');
1700
1701	if(!!this.FORM)
1702	{
1703		this.ACTION_SELECTOR = this.FORM.elements.action;
1704		this.ACTION_BUTTON = this.FORM.elements.apply;
1705		this.ACTION_TARGET = this.FORM.elements.action_target;
1706
1707		if(this.ACTION_SELECTOR)
1708		{
1709			BX.bind(this.ACTION_SELECTOR, 'change', BX.proxy(this.UpdateCheckboxCounter, this));
1710		}
1711
1712		if(this.ACTION_TARGET)
1713		{
1714			BX.bind(this.ACTION_TARGET, 'click', BX.proxy(this.UpdateCheckboxCounter, this));
1715		}
1716	}
1717
1718	if (!!this.TABLE && this.TABLE.tBodies[0] && this.TABLE.tBodies[0].rows.length > 0)
1719	{
1720		for (var i = 0; i < this.TABLE.tBodies[0].rows.length; i++)
1721		{
1722			if (this.TABLE.tBodies[0].rows[i].oncontextmenu)
1723			{
1724				BX.bind(this.TABLE.tBodies[0].rows[i], 'contextmenu', BX.proxy(function(e)
1725				{
1726					if(!this.params.context_menu)
1727						return;
1728
1729					e = e||window.event;
1730					if(!this.params.context_ctrl && e.ctrlKey || this.params.context_ctrl && !e.ctrlKey || e.target && e.target.tagName.toUpperCase() == 'A')
1731						return;
1732
1733					BX.adminList.ShowMenu({x: e.pageX || (e.clientX + document.body.scrollLeft), y: e.pageY || (e.clientY + document.body.scrollTop)}, BX.proxy_context.oncontextmenu(), BX.proxy_context);
1734
1735					return BX.PreventDefault(e);
1736
1737				}, this))
1738			}
1739
1740			BX.bind(this.TABLE.tBodies[0].rows[i], 'click', BX.proxy(this.RowClick, this));
1741		}
1742	}
1743
1744	var checkboxList = BX.findChildren(this.LAYOUT || this.TABLE, {tagName: 'INPUT', property: {type: 'checkbox'}}, true);
1745	if (!!checkboxList)
1746	{
1747		for (i = 0; i < checkboxList.length; i++)
1748		{
1749			BX.adminFormTools.modifyCheckbox(checkboxList[i]);
1750			if(checkboxList[i].name == 'ID[]')
1751			{
1752				if (!checkboxList[i].disabled)
1753				{
1754					BX.bind(checkboxList[i], 'click', BX.proxy(this._checkboxClick, this));
1755					BX.bind(checkboxList[i].parentNode, 'click', BX.proxy(this._checkboxCellClick, this));
1756					BX.bind(checkboxList[i].parentNode, 'dblclick', BX.PreventDefault);
1757
1758					this.CHECKBOX.push(checkboxList[i]);
1759				}
1760				else
1761				{
1762					this.CHECKBOX_DISABLED.push(checkboxList[i]);
1763				}
1764			}
1765		}
1766	}
1767
1768	var check = BX(this.table_id + '_check_all');
1769
1770	if (this.TABLE && this.TABLE.tHead && !!this.params.FIX_HEADER)
1771	{
1772		if (check)
1773		{
1774			check.checked = false;
1775			this.bSelectAllChecked = false;
1776
1777			var check_id = check.id;
1778			BX.addCustomEvent(this.TABLE.tHead, 'onFixedNodeChangeState', BX.delegate(function(state)
1779			{
1780				if (state)
1781				{
1782					check.setAttribute('id', '');
1783					setTimeout("BX('"+check_id+"').checked="+this.table_id+".bSelectAllChecked", 5);
1784				}
1785				else
1786				{
1787					check.checked = this.bSelectAllChecked;
1788					check.setAttribute('id', check_id);
1789				}
1790			}, this));
1791		}
1792
1793		BX.Fix(this.TABLE.tHead, {type: 'top', limit_node: this.TABLE});
1794	}
1795
1796	if (this.FOOTER || this.FOOTER_EDIT)
1797	{
1798		BX.adminFormTools.modifyFormElements(this.FOOTER || this.FOOTER_EDIT, ['*']);
1799
1800		if (!!this.params.FIX_FOOTER)
1801		{
1802			BX.addCustomEvent(this.FOOTER || this.FOOTER_EDIT, 'onFixedNodeChangeState', function(state) {
1803				if (state)
1804					BX.addClass(this, 'adm-list-table-footer-fixed');
1805				else
1806					BX.removeClass(this, 'adm-list-table-footer-fixed');
1807			});
1808		}
1809	}
1810
1811	if (this.FOOTER_EDIT)
1812	{
1813		if (!!this.params.FIX_FOOTER)
1814		{
1815			BX.Fix(this.FOOTER_EDIT, {type: 'bottom', limit_node: this.TABLE});
1816		}
1817
1818		BX.bindDelegate(this.FOOTER_EDIT, 'click', {property:{type: /button|submit/}}, BX.adminPanel.showWait);
1819	}
1820
1821	if (!!this.LAYOUT)
1822	{
1823		var pos = BX.pos(this.LAYOUT), wndScroll = BX.GetWindowSize();
1824
1825		if (BX.adminPanel.isFixed() && BX.adminPanel.panel)
1826		{
1827			pos.top -= BX.adminPanel.panel.offsetHeight;
1828		}
1829
1830		if (!!this.FOOTER_EDIT)
1831		{
1832			if (!!this.CHECKBOX_DISABLED[0])
1833			{
1834				pos = BX.pos(this.CHECKBOX_DISABLED[0].parentNode);
1835			}
1836
1837			window.scrollTo(wndScroll.scrollLeft, pos.top - parseInt(wndScroll.innerHeight/2));
1838		}
1839		else if (pos.top < wndScroll.scrollTop)
1840		{
1841
1842			window.scrollTo(wndScroll.scrollLeft, pos.top);
1843		}
1844	}
1845
1846	this.UpdateCheckboxCounter();
1847};
1848
1849BX.adminList.prototype.ReInit = function()
1850{
1851	BX.defer(this.Init, this)();
1852};
1853
1854BX.adminList.prototype.GetAdminList = function(url, callback)
1855{
1856	url = BX.util.add_url_param(url, {'mode': 'list', 'table_id': BX.util.urlencode(this.table_id)});
1857
1858	BX.ajax({
1859		method: 'GET',
1860		dataType: 'html',
1861		url: url,
1862		onsuccess: BX.delegate(function(result) {
1863			if (result.length > 0)
1864			{
1865				BX.closeWait(this.LAYOUT);
1866				BX.onCustomEvent(window, "onAdminListLoaded");
1867				this._GetAdminList(result);
1868
1869				if (callback && BX.type.isFunction(callback))
1870					callback(url);
1871			}
1872		}, this),
1873		onfailure: function() {BX.debug('GetAdminList', arguments)}
1874	});
1875};
1876
1877BX.adminList.prototype._GetAdminList = function(result)
1878{
1879	BX.adminPanel.closeWait();
1880
1881	this.Destroy();
1882	this.LAYOUT.innerHTML = result;
1883
1884	this.ReInit();
1885
1886	BX.adminChain.addItems(this.table_id + "_navchain_div");
1887};
1888
1889BX.adminList.prototype.PostAdminList = function(url)
1890{
1891	url = BX.util.remove_url_param(url, ['mode', 'table_id']);
1892	url += (url.indexOf('?') >= 0 ? '&' : '?') + 'mode=frame&table_id='+BX.util.urlencode(this.table_id);
1893
1894	// i can only guess of the sacred meaning of this strange thing. but it had an error in previous version.
1895	try{this.FORM.action.parentNode.removeChild(this.FORM.action);}catch(e){}
1896
1897	this.FORM.action = url;
1898	BX.submit(this.FORM);
1899};
1900
1901BX.adminList.prototype.UpdateCheckboxCounter = function()
1902{
1903	if (!this.CHECKBOX_COUNTER)
1904		return;
1905
1906	var bChecked = this.num_checked > 0 || this.ACTION_TARGET && this.ACTION_TARGET.checked;
1907
1908	if (!bChecked)
1909	{
1910		if (!!this.FOOTER && !!this.params.FIX_FOOTER)
1911			BX.UnFix(this.FOOTER);
1912
1913		BX.removeClass(this.CHECKBOX_COUNTER, 'adm-table-counter-visible');
1914		this.CHECKBOX_COUNTER.lastChild.innerHTML = '0';
1915
1916		if (!!this.ACTION_BUTTON)
1917			this.ACTION_BUTTON.disabled = true;
1918	}
1919	else
1920	{
1921		if (!!this.FOOTER && !!this.params.FIX_FOOTER)
1922			BX.Fix(this.FOOTER, {type: 'bottom', limit_node: this.TABLE.tBodies[0]});
1923
1924		BX.addClass(this.CHECKBOX_COUNTER, 'adm-table-counter-visible');
1925		this.CHECKBOX_COUNTER.lastChild.innerHTML = this.ACTION_TARGET && this.ACTION_TARGET.checked ? BX.message('JSADM_LIST_SELECTEDALL') : this.num_checked;
1926
1927		if (!!this.ACTION_BUTTON)
1928			this.ACTION_BUTTON.disabled = this.ACTION_SELECTOR.selectedIndex <= 0;
1929	}
1930};
1931
1932BX.adminList.prototype.Sort = function(url, bCheckCtrl, args)
1933{
1934	if(bCheckCtrl == true)
1935	{
1936		var e = null, bControl = false;
1937
1938		if(args.length > 0)
1939			e = args[0];
1940		if(!e)
1941			e = window.event;
1942		if(e)
1943			bControl = e.ctrlKey;
1944		url += (bControl? 'desc':'asc');
1945	}
1946
1947	this.GetAdminList(url);
1948};
1949
1950
1951BX.adminList.prototype.RowClick = function(e)
1952{
1953	e = e || window.event;
1954
1955	if (e.button != 0)
1956		return true;
1957
1958	if (e.ctrlKey || e.metaKey || e.shiftKey && !this._last_row)
1959	{
1960		var c = BX.proxy_context.cells[0].firstChild;
1961		c.checked = !c.checked;
1962
1963		this.SelectRow(c, c.checked);
1964
1965		this.UpdateCheckboxCounter();
1966		this.EnableActions();
1967	}
1968
1969	if (e.shiftKey)
1970	{
1971		if (!this._last_row)
1972			this._last_row = BX.proxy_context.parentNode.rows[0];
1973
1974		var tBody = this._last_row.parentNode,
1975			ixStart = Math.min(this._last_row.rowIndex, BX.proxy_context.rowIndex),
1976			ixFinish = Math.max(this._last_row.rowIndex, BX.proxy_context.rowIndex);
1977
1978		for (var i = ixStart; i <= ixFinish; i++)
1979		{
1980			c = tBody.rows[i-1].cells[0].firstChild;
1981			if (!c.checked)
1982			{
1983				c.checked = true;
1984				this.SelectRow(c, c.checked);
1985			}
1986		}
1987
1988		this.UpdateCheckboxCounter();
1989		this.EnableActions();
1990
1991		return BX.PreventDefault(e);
1992	}
1993};
1994
1995BX.adminList.prototype._checkboxClick = function(e)
1996{
1997	if (e.shiftKey || e.ctrlKey || e.metaKey)
1998		return true;
1999
2000	this.SelectRow(BX.proxy_context, BX.proxy_context.checked);
2001
2002	this.UpdateCheckboxCounter();
2003	this.EnableActions();
2004
2005	return BX.eventCancelBubble(e);
2006};
2007
2008BX.adminList.prototype._checkboxCellClick = function(e)
2009{
2010	if (e.shiftKey || e.ctrlKey || e.metaKey)
2011		return true;
2012
2013	var c = BX.proxy_context.firstChild;
2014	c.checked = !c.checked;
2015
2016	this.SelectRow(c, c.checked);
2017
2018	this.UpdateCheckboxCounter();
2019	this.EnableActions();
2020
2021	return BX.PreventDefault(e);
2022};
2023
2024BX.adminList.prototype.SelectRow = function(el, bSelect)
2025{
2026	if (el.tagName.toUpperCase() != 'TR')
2027	{
2028		if (!el.BXROW)
2029		{
2030			el.BXROW = BX.findParent(el, {tag: 'TR'});
2031		}
2032
2033		if (!!el.BXROW)
2034		{
2035			this.SelectRow(el.BXROW, bSelect);
2036		}
2037	}
2038	else
2039	{
2040		if (bSelect)
2041			BX.addClass(el, 'adm-table-row-active');
2042		else
2043			BX.removeClass(el, 'adm-table-row-active');
2044
2045		this._last_row = el;
2046		this.num_checked += bSelect ? 1 : -1;
2047	}
2048};
2049
2050BX.adminList.prototype.SelectAllRows = function(node)
2051{
2052	this.bSelectAllChecked = !!node.checked;
2053
2054	for (var i = 0; i < this.CHECKBOX.length; i++)
2055	{
2056		if(this.CHECKBOX[i].checked != this.bSelectAllChecked && !this.CHECKBOX[i].disabled)
2057		{
2058			this.CHECKBOX[i].checked = this.bSelectAllChecked;
2059			this.SelectRow(this.CHECKBOX[i], this.bSelectAllChecked);
2060		}
2061	}
2062
2063	this.UpdateCheckboxCounter();
2064	this.EnableActions();
2065};
2066
2067BX.adminList.prototype.IsActionEnabled = function(action)
2068{
2069	if(action == 'edit')
2070		return !(this.ACTION_TARGET && this.ACTION_TARGET.checked) && (this.num_checked > 0);
2071	else
2072		return (this.ACTION_TARGET && this.ACTION_TARGET.checked) || (this.num_checked > 0);
2073};
2074
2075BX.adminList.prototype.EnableActions = function()
2076{
2077	if (!!this.BUTTON_EDIT)
2078	{
2079		if (this.IsActionEnabled('edit'))
2080			BX.removeClass(this.BUTTON_EDIT, 'adm-edit-disable');
2081		else
2082			BX.addClass(this.BUTTON_EDIT, 'adm-edit-disable');
2083	}
2084
2085	if (!!this.BUTTON_DELETE)
2086	{
2087		if (this.IsActionEnabled('delete'))
2088			BX.removeClass(this.BUTTON_DELETE, 'adm-edit-disable');
2089		else
2090			BX.addClass(this.BUTTON_DELETE, 'adm-edit-disable');
2091	}
2092};
2093
2094BX.adminList.prototype.Destroy = function()
2095{
2096	this.CHECKBOX = [];
2097	this.CHECKBOX_DISABLED = [];
2098
2099	if (BX.PopupMenu.currentItem && BX.PopupMenu.currentItem.popupWindow.isShown())
2100		BX.PopupMenu.currentItem.popupWindow.close();
2101
2102	if (this.TABLE && this.TABLE.tHead)
2103		BX.UnFix(this.TABLE.tHead);
2104	if (this.FOOTER)
2105	BX.UnFix(this.FOOTER);
2106	if (this.FOOTER_EDIT)
2107		BX.UnFix(this.FOOTER_EDIT);
2108
2109	this._last_row = null;
2110	this.num_checked = 0;
2111};
2112
2113BX.adminList.prototype.ShowSettings = function(url)
2114{
2115	(new BX.CDialog({
2116		content_url: url,
2117		resizable: true,
2118		height: 475,
2119		width: 560
2120	})).Show();
2121};
2122
2123BX.adminList.prototype.SaveSettings =  function(el)
2124{
2125	var sCols='', sBy='', sOrder='', sPageSize;
2126
2127	var oSelect = document.list_settings.selected_columns;
2128	var n = oSelect.length;
2129	for(var i=0; i<n; i++)
2130		sCols += (sCols != ''? ',':'')+oSelect[i].value;
2131
2132	oSelect = document.list_settings.order_field;
2133	if(oSelect)
2134		sBy = oSelect[oSelect.selectedIndex].value;
2135
2136	oSelect = document.list_settings.order_direction;
2137	if(oSelect)
2138		sOrder = oSelect[oSelect.selectedIndex].value;
2139
2140	oSelect = document.list_settings.nav_page_size;
2141	sPageSize = oSelect[oSelect.selectedIndex].value;
2142
2143	var bCommon = (document.list_settings.set_default && document.list_settings.set_default.checked);
2144
2145	BX.userOptions.save('list', this.table_id, 'columns', sCols, bCommon);
2146	BX.userOptions.save('list', this.table_id, 'by', sBy, bCommon);
2147	BX.userOptions.save('list', this.table_id, 'order', sOrder, bCommon);
2148	BX.userOptions.save('list', this.table_id, 'page_size', sPageSize, bCommon);
2149
2150	var url = window.location.href;
2151
2152	BX.WindowManager.Get().showWait(el);
2153	BX.userOptions.send(BX.delegate(function(){
2154		this.GetAdminList(
2155			url,
2156			function(){
2157				BX.WindowManager.Get().closeWait(el);
2158				BX.WindowManager.Get().Close();
2159			}
2160		);
2161	}, this));
2162};
2163
2164BX.adminList.prototype.DeleteSettings = function(bCommon)
2165{
2166	BX.showWait();
2167	var url = window.location.href;
2168	BX.userOptions.del('list', this.table_id, bCommon, BX.delegate(function(){
2169		BX.closeWait();
2170		this.GetAdminList(
2171			url,
2172			function(){BX.WindowManager.Get().Close();}
2173		);
2174	}, this));
2175};
2176
2177BX.adminList._onpopupmenushow = function(){BX.addClass(this, 'adm-list-row-active');};
2178BX.adminList._onpopupmenuclose = function(){BX.removeClass(this, 'adm-list-row-active');};
2179
2180BX.adminList.ShowMenu = function(el, menu, el_row)
2181{
2182	if (!!menu && menu.length > 0)
2183	{
2184		if (!!el_row)
2185		{
2186			BX.addCustomEvent(el, 'onAdminMenuShow', BX.proxy(BX.adminList._onpopupmenushow, el_row));
2187			BX.addCustomEvent(el, 'onAdminMenuClose', BX.proxy(BX.adminList._onpopupmenuclose, el_row));
2188		}
2189
2190		var menuParams = {active_class: 'adm-list-table-popup-active'};
2191		var search = window.location.search;
2192		if (search.indexOf("IFRAME_TYPE=PUBLIC_FRAME") !== -1 || search.indexOf("IFRAME_TYPE%3DPUBLIC_FRAME") !== -1)
2193		{
2194			menuParams.public_frame = '1';
2195		}
2196		BX.adminShowMenu(el, menu, menuParams);
2197	}
2198};
2199
2200BX.adminList.showPublicMenu = function(element, listAction)
2201{
2202	var actionPopupItems = [];
2203
2204	if (listAction.length)
2205	{
2206		for (var k = 0; k < listAction.length; k++)
2207		{
2208			var popupItems = {
2209				text : listAction[k].TEXT
2210			};
2211			if (BX.type.isNotEmptyString(listAction[k].ONCLICK))
2212			{
2213				popupItems["onclick"] = listAction[k].ONCLICK;
2214			}
2215			else if (BX.type.isNotEmptyString(listAction[k].LINK))
2216			{
2217				popupItems["href"] = listAction[k].LINK;
2218			}
2219			if (BX.type.isArray(listAction[k].MENU) && listAction[k].MENU.length)
2220			{
2221				var popupChild = [], childs = listAction[k].MENU;
2222				childs.forEach(function(child) {
2223					var childData = {
2224						text: child.TEXT
2225					};
2226					if (BX.type.isNotEmptyString(child.ONCLICK))
2227					{
2228						childData["onclick"] = child.ONCLICK;
2229					}
2230					else if (BX.type.isNotEmptyString(child.LINK))
2231					{
2232						childData["href"] = child.LINK;
2233					}
2234					popupChild.push(childData);
2235				}, this);
2236				if (popupChild.length)
2237				{
2238					popupItems["items"] = popupChild;
2239				}
2240			}
2241			actionPopupItems.push(popupItems);
2242		}
2243	}
2244
2245	var buttonRect = element.getBoundingClientRect();
2246	var actionPopupObject = BX.PopupMenu.create(
2247		"context-menu-" + BX.util.getRandomString(3),
2248		element,
2249		actionPopupItems,
2250		{
2251			closeByEsc : true,
2252			angle: true,
2253			offsetLeft: buttonRect.width/2,
2254			zIndex: -3
2255		}
2256	);
2257	if(actionPopupObject)
2258	{
2259		actionPopupObject.popupWindow.show();
2260	}
2261};
2262
2263/*** BX.adminUiFilter (BX.Main.Filter) ***/
2264BX.adminUiFilter = function(filterId, params)
2265{
2266	this.filterId = filterId;
2267
2268	this.init();
2269};
2270
2271BX.adminUiFilter.prototype.init = function()
2272{
2273	BX.addCustomEvent("BX.Main.Filter:apply", this.onApplyFilter);
2274	BX.addCustomEvent("BX.Main.Filter:show", this.onShow);
2275};
2276
2277BX.adminUiFilter.prototype.onApplyFilter = function(id, data, ctx, promise, params)
2278{
2279	if (!ctx.grid || (ctx.grid && !(ctx.grid instanceof BX.Main.grid)))
2280	{
2281		params.autoResolve = false;
2282
2283		BX.ajax.post(window.location.toString(), {}, function(result) {
2284			promise.fulfill();
2285			window.location.reload();
2286		});
2287	}
2288};
2289
2290BX.adminUiFilter.prototype.onShow = function(filterObject)
2291{
2292	BX.onCustomEvent(window, "onAdminFilterInited", [{filterId: this.filterId}]);
2293};
2294
2295BX.adminUserFilterHandler = function(params)
2296{
2297	this.filterId = params.filterId;
2298	this.fieldId = params.fieldId;
2299	this.languageId = params.languageId;
2300	this.selfFolderUrl = params.selfFolderUrl;
2301
2302	this.init();
2303};
2304
2305BX.adminUserFilterHandler.prototype.init = function()
2306{
2307	this.control = null;
2308	this.userSearchWindow = null;
2309
2310	BX.addCustomEvent(window, "BX.Main.Filter:customEntityFocus", BX.proxy(this.onCustomEntitySelectorOpen, this));
2311};
2312
2313BX.adminUserFilterHandler.prototype.openWindow = function()
2314{
2315	var url = this.selfFolderUrl+"user_search.php?lang="+this.languageId+"&JSFUNC=setUserId_"+this.fieldId,
2316		params = "scrollbars=yes,resizable=yes,width=760,height=500,top="+Math.floor((screen.height-
2317			560)/2-14)+",left="+Math.floor((screen.width - 760)/2-5);
2318	this.userSearchWindow = window.open(url, '', params);
2319	if (this.userSearchWindow)
2320	{
2321		this.userSearchWindow.onbeforeunload = function(e) {
2322			setTimeout(function() {
2323				this.userSearchWindow = null;
2324			}.bind(this), 300);
2325		}.bind(this);
2326	}
2327};
2328
2329BX.adminUserFilterHandler.prototype.closeWindow = function()
2330{
2331	this.userSearchWindow.close();
2332	setTimeout(function() {
2333		this.userSearchWindow = null;
2334	}.bind(this), 300);
2335};
2336
2337BX.adminUserFilterHandler.prototype.setSelected = function(userId)
2338{
2339	if (this.control)
2340	{
2341		var node = this.control.getLabelNode();
2342		node.value = '';
2343
2344		BX.ajax.post(this.selfFolderUrl+"get_user.php",
2345			{
2346				ID: userId,
2347				ajax: "Y",
2348				format: "Y",
2349				sessid: BX.bitrix_sessid()
2350			},
2351			BX.proxy(function(result) {
2352				result = BX.parseJSON(result, {});
2353				var userLabel = userId;
2354				if (result["NAME"])
2355				{
2356					userLabel = result["NAME"];
2357				}
2358				this.control.setData(userLabel, userId);
2359			}, this)
2360		);
2361
2362		this.closeWindow();
2363	}
2364};
2365
2366BX.adminUserFilterHandler.prototype.onCustomEntitySelectorOpen = function(control)
2367{
2368	if (!this.userSearchWindow && control.getId() === this.fieldId)
2369	{
2370		this.control = control;
2371		this.openWindow();
2372	}
2373};
2374
2375BX.adminProductFilterHandler = function(params)
2376{
2377	this.filterId = params.filterId;
2378	this.fieldId = params.fieldId;
2379	this.languageId = params.languageId;
2380	this.publicMode = params.publicMode;
2381	this.selfFolderUrl = params.selfFolderUrl;
2382
2383	this.init();
2384};
2385
2386BX.adminProductFilterHandler.prototype.init = function()
2387{
2388	BX.addCustomEvent(window, "BX.Main.Filter:customEntityFocus", BX.proxy(this.onCustomEntitySelectorOpen, this));
2389
2390	this.control = null;
2391	this.popup = null;
2392};
2393
2394BX.adminProductFilterHandler.prototype.onCustomEntitySelectorOpen = function(control)
2395{
2396	if (control.getId() === this.fieldId)
2397	{
2398		this.control = control;
2399		this.showProductSearchDialog();
2400	}
2401};
2402
2403BX.adminProductFilterHandler.prototype.showProductSearchDialog = function()
2404{
2405	this.popup = this.makeProductSearchDialog({
2406		caller: this.fieldId,
2407		lang: this.languageId,
2408		callback: "FillProductFields_"+this.fieldId
2409	});
2410
2411	var content = this.popup.GetContent();
2412	BX.bind(content.parentNode.parentNode, "mousedown", function(event) {
2413		event.stopPropagation();
2414	});
2415
2416	this.popup.Show();
2417};
2418
2419BX.adminProductFilterHandler.prototype.makeProductSearchDialog = function(params)
2420{
2421	var caller = params.caller || "",
2422		lang = params.lang || "ru",
2423		siteId = params.siteId || "",
2424		callback = params.callback || "",
2425		storeId = params.storeId || "0",
2426		contentUrl = "/bitrix/tools/sale/product_search_dialog.php?lang="+lang+"&LID="+siteId+"&caller=" + caller
2427			+ "&func_name="+callback+"&STORE_FROM_ID="+storeId;
2428
2429	if (this.publicMode === "Y")
2430	{
2431		contentUrl = contentUrl + "&public_mode=Y";
2432	}
2433
2434	var popup = new BX.CDialog({
2435		content_url: contentUrl,
2436		height: Math.max(500, window.innerHeight-400),
2437		width: Math.max(800, window.innerWidth-400),
2438		draggable: true,
2439		resizable: true,
2440		min_height: 500,
2441		min_width: 800,
2442		zIndex: 2000
2443	});
2444	BX.addCustomEvent(popup, "onWindowRegister", BX.defer(function(){
2445		popup.Get().style.position = "fixed";
2446		popup.Get().style.top = (parseInt(popup.Get().style.top) - BX.GetWindowScrollPos().scrollTop) + "px";
2447	}));
2448	return popup;
2449};
2450
2451BX.adminProductFilterHandler.prototype.closeProductSearchDialog = function()
2452{
2453	if (this.popup)
2454	{
2455		this.popup.Close();
2456	}
2457};
2458
2459BX.adminProductFilterHandler.prototype.setSelected = function(productId, productName)
2460{
2461	if (this.control)
2462	{
2463		var node = this.control.getLabelNode();
2464		node.value = '';
2465		this.control.setData(productName, productId);
2466	}
2467};
2468
2469/*** BX.adminUiList (BX.Main.grid) ***/
2470BX.adminUiList = function(gridId, params)
2471{
2472	this.gridId = gridId;
2473	this.publicMode = (params.publicMode ? params.publicMode : false);
2474	this.showTotalCountHtml = (params.showTotalCountHtml ? params.showTotalCountHtml : false);
2475	this.serviceUrl = (params.serviceUrl ? params.serviceUrl : "");
2476
2477	this.init();
2478};
2479
2480BX.adminUiList.prototype.init = function()
2481{
2482	this.basePageUrl = window.location.pathname;
2483	this.serviceUrl = (this.serviceUrl ? this.serviceUrl : this.basePageUrl);
2484	this.gridUrl = window.location.pathname + window.location.search;
2485
2486	BX.addCustomEvent("SidePanel.Slider:onMessage", BX.proxy(this.onMessage, this));
2487	BX.addCustomEvent('AdminUiList:onReloadGrid', BX.proxy(this.onReloadGrid, this));
2488
2489	BX.addCustomEvent(window, "Grid::beforeRequest", BX.proxy(this.onBeforeRequest, this));
2490	BX.addCustomEvent(window, "Grid::updated", BX.proxy(this.onUpdated, this));
2491
2492	this.bindShowTotalCount();
2493};
2494
2495BX.adminUiList.prototype.onUpdated = function(gridObject)
2496{
2497	this.bindShowTotalCount();
2498};
2499
2500BX.adminUiList.prototype.bindShowTotalCount = function()
2501{
2502	if (this.showTotalCountHtml)
2503	{
2504		BX.bind(BX(this.gridId + "_show_total_count"), "click", BX.proxy(this.onShowTotalCount, this));
2505	}
2506};
2507
2508BX.adminUiList.prototype.onShowTotalCount = function(event)
2509{
2510	BX.ajax({
2511		url: this.serviceUrl,
2512		method: "POST",
2513		dataType: "json",
2514		data: {
2515			"action": "getTotalCount",
2516		},
2517		onsuccess: BX.proxy(function(response) {
2518			if (response.hasOwnProperty("totalCountHtml"))
2519			{
2520				BX(this.gridId + "_show_total_count").parentElement.innerHTML = response.totalCountHtml;
2521			}
2522		}, this)
2523	});
2524
2525	event.preventDefault();
2526};
2527
2528BX.adminUiList.prototype.onMessage = function(SidePanelEvent)
2529{
2530	if (
2531		!(SidePanelEvent instanceof BX.SidePanel.MessageEvent)
2532		&& !(SidePanelEvent instanceof top.BX.SidePanel.MessageEvent)
2533	)
2534	{
2535		return;
2536	}
2537
2538	var data = BX.type.isPlainObject(SidePanelEvent.getData()) ? SidePanelEvent.getData() : {};
2539
2540	if (data.hasOwnProperty("listActions") && data.listActions.length)
2541	{
2542		data.listActions.forEach(function(action) {
2543			switch (action)
2544			{
2545				case "reloadTopPage":
2546					var url = this.basePageUrl;
2547					if (data["reloadTopUrlParams"])
2548					{
2549						url = url + data["reloadTopUrlParams"];
2550					}
2551					window.location.href = url;
2552					break;
2553			}
2554		}, this);
2555	}
2556	else
2557	{
2558		var eventType = SidePanelEvent.getEventId(),
2559			listCancelTypes = ["cancel", "dontsave"];
2560
2561		if (BX.util.in_array(eventType, listCancelTypes))
2562		{
2563			return;
2564		}
2565	}
2566
2567	this.onReloadGrid();
2568};
2569
2570BX.adminUiList.prototype.onReloadGrid = function()
2571{
2572	var reloadParams = { apply_filter: 'Y'};
2573	var gridObject;
2574
2575	if (BX.Reflection.getClass('top.BX.Main.gridManager.getById'))
2576	{
2577		gridObject = top.BX.Main.gridManager.getById(this.gridId);
2578	}
2579
2580	if (gridObject === null && BX.Reflection.getClass('BX.Main.gridManager.getById'))
2581	{
2582		gridObject = BX.Main.gridManager.getById(this.gridId);
2583	}
2584
2585	if (gridObject && gridObject.hasOwnProperty('instance'))
2586	{
2587		gridObject.instance.reloadTable('POST', reloadParams, false, this.gridUrl);
2588	}
2589};
2590
2591BX.adminUiList.prototype.onBeforeRequest = function(gridData, requestParams)
2592{
2593	if (BX.type.isPlainObject(requestParams.data))
2594	{
2595		var data = requestParams.data;
2596		requestParams.data = this.getDataWithPreparedCustomFields(data);
2597	}
2598
2599	if (this.publicMode)
2600	{
2601		requestParams.url =	BX.util.add_url_param(requestParams.url, {
2602			"sessid": BX.bitrix_sessid(),
2603			"public": "Y"
2604		});
2605	}
2606	else
2607	{
2608		if (BX.type.isNotEmptyString(requestParams.url))
2609		{
2610			requestParams.url = requestParams.url +
2611				((requestParams.url.indexOf("?") < 0) ? "" : "&") + window.location.search.slice(1);
2612		}
2613		else
2614		{
2615			requestParams.url = this.basePageUrl+window.location.search;
2616		}
2617	}
2618};
2619
2620BX.adminUiList.prototype.getDataWithPreparedCustomFields = function(data)
2621{
2622	if (BX.type.isPlainObject(data.FIELDS))
2623	{
2624		for (var rowId in data.FIELDS)
2625		{
2626			var rowData = null;
2627			if (data.FIELDS.hasOwnProperty(rowId))
2628			{
2629				rowData = data.FIELDS[rowId];
2630			}
2631			if (BX.type.isPlainObject(rowData))
2632			{
2633				for (var field in rowData)
2634				{
2635					if (rowData.hasOwnProperty(field) && field.indexOf("_custom") !== -1)
2636					{
2637						if (BX.type.isPlainObject(rowData[field]))
2638						{
2639							var customFields = {};
2640							Object.keys(rowData[field]).forEach(function(inputName, index) {
2641								if (rowData[field].hasOwnProperty(inputName))
2642								{
2643									customFields[index] = customFields[index] || {};
2644									customFields[index]["name"] = inputName;
2645									customFields[index]["value"] = rowData[field][inputName];
2646								}
2647							});
2648							rowData[field] = customFields;
2649							delete rowData[field.replace("_custom", "")];
2650						}
2651					}
2652				}
2653			}
2654		}
2655	}
2656
2657	return data;
2658};
2659
2660BX.adminUiList.SendSelected = function(gridId)
2661{
2662	var gridInstance = BX.Main.gridManager.getById(gridId).instance;
2663	var values = gridInstance.getActionsPanel().getValues();
2664	var selectedRows = gridInstance.getRows().getSelectedIds();
2665	var data = Object.assign({
2666		ID: selectedRows,
2667		action: values
2668	}, values);
2669	gridInstance.reloadTable("POST", data);
2670};
2671
2672/*** BX.adminSidePanel (BX.SidePanel) ***/
2673BX.adminSidePanel = function(params)
2674{
2675	this.params = BX.type.isPlainObject(params) ? params : {};
2676
2677	this.publicMode = this.params.publicMode ? Boolean(this.params.publicMode) : false;
2678
2679	this.init();
2680};
2681
2682BX.adminSidePanel.prototype.init = function()
2683{
2684	BX.addCustomEvent("AdminSidePanel:onSendRequest", BX.proxy(this.onSendRequest, this));
2685	BX.addCustomEvent("SidePanel.Slider:onMessage", BX.proxy(this.onMessage, this));
2686
2687	this.checkActionByUrl();
2688};
2689
2690BX.adminSidePanel.prototype.checkActionByUrl = function()
2691{
2692	var search = window.location.search;
2693	if (search.indexOf("sidePanelAction=") !== -1 || search.indexOf("sidePanelAction%3D") !== -1)
2694	{
2695		var urlParams = search.substring(1), action;
2696		if (BX.type.isNotEmptyString(urlParams))
2697		{
2698			var params = urlParams.split("&");
2699			for (var i = 0; i < params.length; i++)
2700			{
2701				var pair = params[i].split("="), key = pair[0];
2702				if (key === "sidePanelAction")
2703				{
2704					action = BX.type.isNotEmptyString(pair[1]) ? pair[1] : false;
2705					break;
2706				}
2707			}
2708			if (action)
2709			{
2710				var postParams = {};
2711				switch (action)
2712				{
2713					case "save":
2714						postParams["listActions"] = ["destroy"];
2715						break;
2716					case "saveAndReload":
2717						postParams["listActions"] = ["destroy", "reloadTopPage"];
2718						search = search.replace("&IFRAME=Y&IFRAME_TYPE=SIDE_SLIDER&sidePanelAction="+action, "");
2719						postParams["reloadTopUrlParams"] = search;
2720						break;
2721					case "apply":
2722						search = search.replace("&sidePanelAction="+action, "");
2723						postParams["reloadCurrentUrlParams"] = search;
2724						postParams["listActions"] = ["reloadCurrentPage"];
2725						break;
2726				}
2727				top.BX.onCustomEvent("SidePanel:postMessage", [window, action, postParams]);
2728			}
2729		}
2730	}
2731};
2732
2733BX.adminSidePanel.prototype.onMessage = function(SidePanelEvent)
2734{
2735	if (!(SidePanelEvent instanceof top.BX.SidePanel.MessageEvent))
2736	{
2737		return;
2738	}
2739
2740	var sender = SidePanelEvent.getSender();
2741	var previousSlider = SidePanelEvent.getSlider();
2742	var previousSliderWindow = previousSlider ? previousSlider.getWindow() : window;
2743	var data = BX.type.isPlainObject(SidePanelEvent.getData()) ? SidePanelEvent.getData() : {};
2744	var eventType = SidePanelEvent.getEventId();
2745
2746	if (!(sender instanceof top.BX.SidePanel.Slider) || !eventType)
2747	{
2748		return;
2749	}
2750
2751	if (data.hasOwnProperty("listActions") && data.listActions.length)
2752	{
2753		data.listActions.forEach(function(action) {
2754			switch (action)
2755			{
2756				case "closeAndOpen":
2757					sender.close(true);
2758					if (data.hasOwnProperty("addUrl") && BX.type.isNotEmptyString(data.addUrl))
2759						this.onOpenPage(data.addUrl);
2760					break;
2761				case "close":
2762					sender.close((eventType === "save"));
2763					break;
2764				case "destroy":
2765					sender.destroy();
2766					break;
2767				case "reload":
2768					if (data.hasOwnProperty("formParams") && data.formParams.hasOwnProperty("reloadUrl"))
2769					{
2770						if (this.publicMode)
2771						{
2772							data.formParams.reloadUrl = data.formParams.reloadUrl + (
2773								(data.formParams.reloadUrl.indexOf("?") < 0) ? "?" : "&");
2774							if (data.formParams.reloadUrl.indexOf("publicSidePanel") < 0)
2775							{
2776								data.formParams.reloadUrl = data.formParams.reloadUrl+"publicSidePanel=Y";
2777							}
2778						}
2779						sender.getWindow().location.href = data.formParams.reloadUrl;
2780					}
2781					else
2782					{
2783						sender.getWindow().location.reload();
2784					}
2785					break;
2786				case "reloadCurrentPage":
2787					if (data["reloadCurrentUrlParams"])
2788					{
2789						sender.getWindow().location.search = data["reloadCurrentUrlParams"];
2790					}
2791					break;
2792			}
2793		}, this);
2794	}
2795	else
2796	{
2797		switch (eventType)
2798		{
2799			case "save":
2800			case "save_and_conduct":
2801			case "cancellation":
2802				sender.destroy();
2803				break;
2804			case "save_and_add":
2805				sender.close(true);
2806				if (data.hasOwnProperty("addUrl") && BX.type.isNotEmptyString(data.addUrl))
2807					this.onOpenPage(data.addUrl);
2808				break;
2809			case "apply":
2810			case "save_document":
2811				break;
2812			case "cancel":
2813			case "dontsave":
2814				sender.close(false);
2815				break;
2816		}
2817	}
2818
2819	var listApplyTypes = ["save", "apply", "save_document", "save_and_conduct"];
2820
2821	if (previousSlider && BX.util.in_array(eventType, listApplyTypes))
2822	{
2823		var dictionary = previousSlider.getData(),
2824			formInstance = dictionary.get("adminTabControlInstance"),
2825			urlParams = {"IFRAME":"Y", "IFRAME_TYPE": "SIDE_SLIDER"};
2826		if (formInstance)
2827		{
2828			var tabId = previousSliderWindow.BX(formInstance.name+"_active_tab") ?
2829				previousSliderWindow.BX(formInstance.name+'_active_tab').value : null;
2830			if (tabId)
2831			{
2832				urlParams[formInstance.name+"_active_tab"] = tabId;
2833				previousSliderWindow.location.href = BX.util.add_url_param(previousSlider.getUrl(), urlParams);
2834			}
2835			else
2836			{
2837				previousSliderWindow.location.reload();
2838			}
2839		}
2840	}
2841};
2842
2843BX.adminSidePanel.onOpenPage = BX.adminSidePanel.prototype.onOpenPage = function(url, skipModification)
2844{
2845	if (top.BX.admin && top.BX.admin.dynamic_mode_show_borders)
2846	{
2847		return;
2848	}
2849
2850	if (top.BX.SidePanel.Instance)
2851	{
2852		if (skipModification)
2853		{
2854			top.BX.SidePanel.Instance.open(url);
2855		}
2856		else
2857		{
2858			var adminSidePanel = top.window["adminSidePanel"], optionsOpen = {};
2859			if (adminSidePanel.publicMode)
2860			{
2861				url = BX.util.add_url_param(url, {"publicSidePanel": "Y"});
2862				optionsOpen.allowChangeHistory = false;
2863			}
2864
2865			top.BX.SidePanel.Instance.open(url, optionsOpen);
2866		}
2867	}
2868};
2869
2870BX.adminSidePanel.setDefaultQueryParams = BX.adminSidePanel.prototype.setDefaultQueryParams = function(url)
2871{
2872	if (url.indexOf("IFRAME") === -1)
2873	{
2874		url = BX.util.add_url_param(url, {"IFRAME": "Y"});
2875	}
2876
2877	if (url.indexOf("IFRAME_TYPE") === -1)
2878	{
2879		url = BX.util.add_url_param(url, {"IFRAME_TYPE": "SIDE_SLIDER"});
2880	}
2881
2882	var adminSidePanel = top.window["adminSidePanel"];
2883	if (adminSidePanel && adminSidePanel.publicMode)
2884	{
2885		url = BX.util.add_url_param(url, {"publicSidePanel": "Y"});
2886	}
2887
2888	return url;
2889};
2890
2891BX.adminSidePanel.prototype.onSendRequest = function(url)
2892{
2893	if (!BX.type.isNotEmptyString(url))
2894	{
2895		return;
2896	}
2897
2898	var params = {};
2899
2900	BX.ajax.post(BX.adminSidePanel.setDefaultQueryParams(url),
2901		{
2902			sessid: BX.bitrix_sessid()
2903		},
2904		BX.delegate(function(result) {
2905			result = BX.parseJSON(result, {});
2906			if (result && result.status)
2907			{
2908				if (result.status === 'success')
2909				{
2910					if (result.hasOwnProperty('listActions'))
2911						params['listActions'] = BX.type.isArray(result['listActions']) ? result['listActions'] : [];
2912					if (BX.SidePanel.Instance && BX.SidePanel.Instance.getTopSlider())
2913					{
2914						top.BX.onCustomEvent('SidePanel:postMessage', [
2915							BX.SidePanel.Instance.getTopSlider().getWindow(), "request", params]);
2916					}
2917				}
2918				else if(result.status === 'error')
2919				{
2920					alert(result.message.replace(/<br>/gi, ''));
2921				}
2922			}
2923			else
2924			{
2925				alert('Wrong response format');
2926			}
2927		}, this)
2928	);
2929};
2930
2931/*** BX.adminTabControl ***/
2932BX.adminTabControl = function (name, unique_name, aTabs, params)
2933{
2934	this.name = name;
2935	this.unique_name = unique_name;
2936	this.form = null;
2937	this.aTabs = aTabs;
2938	this.params = BX.type.isPlainObject(params) ? params : {};
2939
2940	this.backUrl = this.params.hasOwnProperty("backUrl") && BX.type.isNotEmptyString(this.params.backUrl) ?
2941		this.params.backUrl : null;
2942	this.isSidePanel = !!(this.params.hasOwnProperty("isSidePanel") &&
2943		BX.type.isNotEmptyString(this.params.isSidePanel) && this.params.isSidePanel === "Y");
2944	this.isPublicFrame = !!(this.params.hasOwnProperty("isPublicFrame") &&
2945		BX.type.isNotEmptyString(this.params.isPublicFrame) && this.params.isPublicFrame === "Y");
2946	this.publicSidePanel = !!(this.params.hasOwnProperty("publicSidePanel") &&
2947		BX.type.isNotEmptyString(this.params.publicSidePanel) && this.params.publicSidePanel === "Y");
2948	this.isActiveConfirm = false;
2949
2950	this.bInited = false;
2951	this.bFixed = {top: true, bottom: true};
2952
2953	this.bExpandTabs = false;
2954	this.aTabsDisabled = {};
2955
2956	this.bPublicMode = false;
2957
2958	this.PreInit();
2959};
2960
2961BX.adminTabControl.prototype.PreInit = function(bSkipInit)
2962{
2963	for (var tab = 0; tab < this.aTabs.length; tab++)
2964	{
2965		this.aTabs[tab].CONTENT = BX(this.aTabs[tab]["DIV"]);
2966
2967		var tbl = BX(this.aTabs[tab]["DIV"]+'_edit_table');
2968		if (!!tbl)
2969		{
2970			for(var k = 0; k < tbl.tBodies.length; k++)
2971			 {
2972				var n = tbl.tBodies[k].rows.length;
2973				for (var i = 0; i < n; i++)
2974				{
2975					if (tbl.tBodies[k].rows[i].cells.length > 1)
2976					{
2977						BX.addClass(tbl.tBodies[k].rows[i].cells[0], 'adm-detail-content-cell-l');
2978						BX.addClass(tbl.tBodies[k].rows[i].cells[1], 'adm-detail-content-cell-r');
2979					}
2980				}
2981			}
2982
2983			this.aTabs[tab].EDIT_TABLE = tbl;
2984			this.aTabs[tab].CONTENT_BLOCK = tbl.parentNode;
2985			var modifyFormElements = BX.adminFormTools.modifyFormElements(tbl);
2986		}
2987	}
2988
2989	if(!bSkipInit)
2990	{
2991		BX.ready(BX.defer(this.Init, this));
2992	}
2993};
2994
2995BX.adminTabControl.prototype.Init = function()
2996{
2997	if (this.aTabs && this.aTabs.length > 0)
2998	{
2999		var tabs_block = this.TABS_BLOCK = BX(this.name + '_tabs');
3000		if (!!tabs_block)
3001		{
3002			var settings_btn = BX(this.name + '_settings_btn');
3003
3004			tabs_block.appendChild(BX.create('DIV', {
3005				props: {
3006					className: 'adm-detail-pin-btn-tabs',
3007					title: BX.message('JSADM_PIN_OFF')
3008				},
3009				attrs: {onclick: this.name + '.ToggleFix(\'top\')'}
3010			}));
3011
3012			BX.addCustomEvent(tabs_block, 'onFixedNodeChangeState', function(state)
3013			{
3014				if (state)
3015				{
3016					BX.addClass(tabs_block, 'adm-detail-tabs-block-fixed');
3017				}
3018				else
3019				{
3020					BX.removeClass(tabs_block, 'adm-detail-tabs-block-fixed');
3021				}
3022
3023				if (!!settings_btn && BX.hasClass(settings_btn, 'bx-settings-btn-active'))
3024				{
3025					BX.onCustomEvent(settings_btn, 'onChangeNodePosition');
3026				}
3027			});
3028
3029			if (this.bFixed['top'])
3030			{
3031				BX.Fix(tabs_block, {type: 'top', limit_node: tabs_block.parentNode});
3032			}
3033			else
3034			{
3035				BX.addClass(tabs_block, 'adm-detail-tabs-block-pin');
3036				tabs_block.lastChild.title = BX.message('JSADM_PIN_ON');
3037			}
3038		}
3039	}
3040
3041	var footer = BX(this.name + '_buttons_div');
3042	if (!!footer)
3043	{
3044		if (footer.firstChild)
3045		{
3046			if (BX.util.trim(footer.firstChild.innerHTML).length <= 0)
3047			{
3048				if (!BX.hasClass(footer.firstChild, 'adm-detail-content-btns-empty'))
3049					BX.addClass(footer.firstChild, 'adm-detail-content-btns-empty');
3050			}
3051			else
3052			{
3053				if (true) // todo !this.isPublicFrame
3054				{
3055					footer.firstChild.insertBefore(BX.create('DIV', {
3056						props: {
3057							className: 'adm-detail-pin-btn',
3058							title: BX.message('JSADM_PIN_OFF')
3059						},
3060						attrs: {onclick: this.name + '.ToggleFix(\'bottom\')'}
3061					}), footer.firstChild.firstChild);
3062				}
3063
3064				BX.addCustomEvent(footer, 'onFixedNodeChangeState', function(state)
3065					{
3066						if (state)
3067							BX.addClass(footer, 'adm-detail-content-btns-fixed');
3068						else
3069							BX.removeClass(footer, 'adm-detail-content-btns-fixed');
3070					});
3071
3072				if (this.bFixed['bottom'])
3073				{
3074					BX.Fix(footer, {type: 'bottom', limit_node: footer.parentNode});
3075				}
3076				else
3077				{
3078					BX.addClass(footer, 'adm-detail-content-btns-pin');
3079					footer.firstChild.firstChild.title = BX.message('JSADM_PIN_ON')
3080				}
3081			}
3082
3083			if (this.isSidePanel)
3084			{
3085				this.setFormDataForSidePanel();
3086				BX.bindDelegate(footer, 'click', {property:{type: /button/}}, this.onClickSidePanelButtons.bind(this));
3087			}
3088			else
3089			{
3090				BX.bindDelegate(footer, 'click', {property:{type: /button|submit/}}, BX.adminPanel.showWait);
3091			}
3092		}
3093
3094		this.form = BX.findParent(footer, {tag : "form"});
3095		if (this.isSidePanel && this.form)
3096		{
3097			BX.bind(this.form, "change", function() {
3098				if (!this.isActiveConfirm)
3099				{
3100					this.isActiveConfirm = true;
3101					BX.addCustomEvent("SidePanel.Slider:onCloseByEsc", function(event) {
3102						var reg = /bitrix\/admin\//;
3103						var str = event.getSlider().getUrl();
3104						if (reg.test(str) && !confirm(BX.message("JSADM_SP_ON_CLOSE_BY_ESC")))
3105						{
3106							event.denyAction();
3107						}
3108					});
3109				}
3110			});
3111		}
3112	}
3113
3114	this.bInited = true;
3115};
3116
3117BX.adminTabControl.prototype.setFormDataForSidePanel = function()
3118{
3119	var sidePanel = top.BX.SidePanel ? top.BX.SidePanel : BX.SidePanel,
3120		slider,
3121		dictionary;
3122	if (typeof sidePanel === 'undefined')
3123	{
3124		return;
3125	}
3126	if (!sidePanel.Instance)
3127	{
3128		return;
3129	}
3130
3131	slider = sidePanel.Instance.getSliderByWindow(window);
3132	if (slider)
3133	{
3134		dictionary = slider.getData();
3135		dictionary.set("adminTabControlInstance", this);
3136	}
3137	sidePanel = null;
3138};
3139
3140BX.adminTabControl.prototype.onClickSidePanelButtons = function(event)
3141{
3142	var button = event.target,
3143		buttonType = button.name;
3144
3145	this.form = BX.findParent(button, {tag : "form"});
3146	if (!this.form)
3147	{
3148		throw new Error('BX.adminTabControl: form not found.');
3149	}
3150
3151	switch (buttonType)
3152	{
3153		case 'save':
3154		case 'apply':
3155		case 'save_and_add':
3156		case 'save_and_conduct':
3157		case 'save_document':
3158		case 'cancellation':
3159			this.submitAjax(buttonType, button);
3160			break;
3161		case 'cancel':
3162		case 'dontsave':
3163			top.BX.onCustomEvent('SidePanel:postMessage', [window, buttonType, {}]);
3164			break;
3165	}
3166};
3167
3168BX.adminTabControl.prototype.submitAjax = function(buttonType, button)
3169{
3170	if (!buttonType)
3171	{
3172		throw new Error('BX.adminTabControl: buttonType not found.');
3173	}
3174
3175	if (button)
3176	{
3177		BX.adminPanel.showWait(button);
3178	}
3179
3180	this.createEventTypeInput(buttonType);
3181
3182	var params = {}, url = this.form.getAttribute("action");
3183
3184	if (this.publicSidePanel)
3185	{
3186		url = BX.adminSidePanel.setDefaultQueryParams(url);
3187	}
3188
3189	BX.ajax.submitAjax(this.form, {
3190		method : 'POST',
3191		url: url,
3192		onsuccess: BX.delegate(function(result) {
3193			result = BX.parseJSON(result, {});
3194			if (result && result.status)
3195			{
3196				if (result.status === 'success')
3197				{
3198					if (result.hasOwnProperty('listActions'))
3199						params['listActions'] = BX.type.isArray(result['listActions']) ? result['listActions'] : [];
3200					if (this.backUrl)
3201						params['backUrl'] = this.backUrl;
3202					if (button && button.dataset.url)
3203						params['addUrl'] = button.dataset.url;
3204
3205					var listApplyTypes = ["apply", "save_document", "save_and_conduct"];
3206					if (BX.util.in_array(buttonType, listApplyTypes))
3207					{
3208						if (result.hasOwnProperty('formParams'))
3209						{
3210							params['formParams'] = result['formParams'];
3211							this.createFormParamsInput(result['formParams']);
3212						}
3213					}
3214
3215					top.BX.onCustomEvent('SidePanel:postMessage', [window, buttonType, params]);
3216				}
3217				else if (result.status === 'error')
3218				{
3219					alert(result.message.replace(/<br>/gi, ''));
3220				}
3221			}
3222			else
3223			{
3224				alert('Wrong response format');
3225			}
3226
3227			if (button)
3228			{
3229				BX.adminPanel.closeWait(button);
3230			}
3231		}, this)
3232	});
3233};
3234
3235BX.adminTabControl.prototype.createEventTypeInput = function(eventType)
3236{
3237	if (!this.form)
3238	{
3239		throw new Error('BX.adminTabControl: form not found.');
3240	}
3241
3242	if (BX(this.name + '_eventType'))
3243	{
3244		BX(this.name + '_eventType').innerHTML = '';
3245		BX(this.name + '_eventType').appendChild(BX.create('input', {
3246			attrs: {
3247				'type': 'hidden',
3248				'name': eventType,
3249				'value': 'Y'
3250			}
3251		}));
3252	}
3253	else
3254	{
3255		this.form.appendChild(BX.create('div', {
3256			props: {
3257				'id': this.name + '_eventType'
3258			},
3259			children: [
3260				BX.create('input', {
3261					attrs: {
3262						'type': 'hidden',
3263						'name': eventType,
3264						'value': 'Y'
3265					}
3266				})
3267			]
3268		}));
3269	}
3270};
3271
3272BX.adminTabControl.prototype.createFormParamsInput = function(formParams)
3273{
3274	if (!this.form)
3275	{
3276		throw new Error('BX.adminTabControl: form not found.');
3277	}
3278
3279	var k;
3280	formParams = BX.type.isPlainObject(formParams) ? formParams : {};
3281
3282	if (BX(this.name + '_formParams'))
3283	{
3284		BX(this.name + '_formParams').innerHTML = '';
3285		for (k in formParams)
3286		{
3287			BX(this.name + '_formParams').appendChild(BX.create('input', {
3288				attrs: {
3289					'type': 'hidden',
3290					'name': BX.util.htmlspecialchars(k),
3291					'value': BX.util.htmlspecialchars(formParams[k])
3292				}
3293			}));
3294		}
3295
3296	}
3297	else
3298	{
3299		var formParamsDom = BX.create('div', {
3300			props: {
3301				'id': this.name + '_formParams'
3302			}
3303		});
3304		for (k in formParams)
3305		{
3306			formParamsDom.appendChild(BX.create("input", {
3307				props: {
3308					type: "hidden",
3309					name: BX.util.htmlspecialchars(k),
3310					value: BX.util.htmlspecialchars(formParams[k])
3311				}
3312			}));
3313		}
3314		this.form.appendChild(formParamsDom);
3315	}
3316};
3317
3318BX.adminTabControl.prototype.setPublicMode = function(v)
3319{
3320	this.bPublicMode = !!v;
3321	if (this.bPublicMode)
3322	{
3323		var currentWindow = BX.WindowManager.Get();
3324		if (currentWindow)
3325		{
3326			var name = this.name;
3327			BX.addCustomEvent(currentWindow, 'onWindowClose', function(){
3328				window[name] = null;
3329			});
3330		}
3331	}
3332};
3333
3334BX.adminTabControl.prototype.ToggleFix = function(type, value)
3335{
3336	if (!this.bInited)
3337	{
3338		this.bFixed[type] = typeof value == 'undefined' ? !this.bFixed[type] : !!value;
3339		return;
3340	}
3341
3342	if (typeof value != 'undefined')
3343	{
3344		this.bFixed[type] = !value;
3345	}
3346
3347	switch (type)
3348	{
3349		case 'bottom':
3350			var footer = BX(this.name + '_buttons_div');
3351			if (!!footer)
3352			{
3353				if (this.bFixed[type])
3354				{
3355					BX.addClass(footer, 'adm-detail-content-btns-pin');
3356					footer.firstChild.firstChild.title = BX.message('JSADM_PIN_ON');
3357					BX.UnFix(footer);
3358				}
3359				else
3360				{
3361					BX.removeClass(footer, 'adm-detail-content-btns-pin');
3362					footer.firstChild.firstChild.title = BX.message('JSADM_PIN_OFF');
3363					BX.Fix(footer, {type: 'bottom', limit_node: footer.parentNode});
3364				}
3365
3366			}
3367		break;
3368		case 'top':
3369			if (!!this.TABS_BLOCK)
3370			{
3371				if (this.bFixed[type])
3372				{
3373					BX.addClass(this.TABS_BLOCK, 'adm-detail-tabs-block-pin');
3374					this.TABS_BLOCK.lastChild.title = BX.message('JSADM_PIN_ON');
3375					BX.UnFix(this.TABS_BLOCK);
3376				}
3377				else
3378				{
3379					BX.removeClass(this.TABS_BLOCK, 'adm-detail-tabs-block-pin');
3380					this.TABS_BLOCK.lastChild.title = BX.message('JSADM_PIN_OFF');
3381					BX.Fix(this.TABS_BLOCK, {type: 'top', limit_node: this.TABS_BLOCK.parentNode});
3382				}
3383			}
3384		break;
3385	}
3386
3387	this.bFixed[type] = !this.bFixed[type];
3388	BX.userOptions.save('edit', 'admin_tabs', 'fix_'+type, (this.bFixed[type] ? 'on': 'off'));
3389};
3390
3391BX.adminTabControl.prototype.SelectTab = function(tab_id)
3392{
3393	if (!this.bInited)
3394	{
3395		setTimeout("window."+this.name+".SelectTab('"+BX.util.jsencode(tab_id)+"')", 50);
3396	}
3397	else if (!this.aTabsDisabled[tab_id])
3398	{
3399		var div = BX(tab_id);
3400		if (div.style.display != 'none')
3401		{
3402			//already visible or expanded tab
3403			if(this.bExpandTabs)
3404			{
3405				//let's scroll to the expanded tab
3406				var pos = BX.pos(div), wndScroll = BX.GetWindowScrollPos();
3407				if (!!this.TABS_BLOCK && this.bFixed['top'])
3408				{
3409					pos.top -= this.TABS_BLOCK.offsetHeight;
3410				}
3411				window.scrollTo(wndScroll.scrollLeft, pos.top);
3412			}
3413		}
3414		else
3415		{
3416			//invisible tab - need to show it
3417			var oldHeight = 0;
3418			var newHeight = 0;
3419			var contentBlockPaddings = 40;
3420			for (var i = 0, cnt = this.aTabs.length; i < cnt; i++)
3421			{
3422				var tab = BX(this.aTabs[i]["DIV"]);
3423				if(tab.style.display != 'none')
3424				{
3425					oldHeight = this.aTabs[i].CONTENT_BLOCK.offsetHeight - contentBlockPaddings;
3426					this.ShowTab(this.aTabs[i]["DIV"], false);
3427					tab.style.display = 'none';
3428					break;
3429				}
3430			}
3431
3432			this.ShowTab(tab_id, true);
3433			div.style.display = 'block';
3434
3435			BX(this.name+'_active_tab').value = tab_id;
3436
3437			var currentTab = null;
3438			for (i = 0, cnt = this.aTabs.length; i < cnt; i++)
3439			{
3440				if(this.aTabs[i]["DIV"] == tab_id)
3441				{
3442					this.aTabs[i]["_ACTIVE"] = true;
3443
3444					if(this.aTabs[i]["ONSELECT"])
3445					{
3446						BX.evalGlobal(this.aTabs[i]["ONSELECT"]);
3447					}
3448
3449					if (!this.bPublicMode)
3450					{
3451						currentTab = this.aTabs[i];
3452						var currentContentBlock = this.aTabs[i].CONTENT_BLOCK;
3453						newHeight = currentContentBlock.offsetHeight - contentBlockPaddings;
3454						if (oldHeight > 0)
3455						{
3456							currentContentBlock.style.height = oldHeight + "px";
3457							currentContentBlock.style.overflowY = "hidden";
3458							this.aTabs[i].EDIT_TABLE.style.opacity = 0;
3459						}
3460					}
3461
3462					break;
3463				}
3464			}
3465
3466			if (!!this.TABS_BLOCK)
3467			{
3468				if (BX.hasClass(this.TABS_BLOCK, 'adm-detail-tabs-block-fixed'))
3469				{
3470					pos = BX.pos(div);
3471					wndScroll = BX.GetWindowScrollPos();
3472					window.scrollTo(wndScroll.scrollLeft, pos.top - this.TABS_BLOCK.offsetHeight - parseInt(this.TABS_BLOCK.style.top));
3473				}
3474			}
3475
3476			if (!this.bPublicMode && oldHeight > 0 && newHeight > 0 && currentTab)
3477			{
3478				var easing = new BX.easing({
3479					duration : 500,
3480					start : { height: oldHeight, opacity : 0 },
3481					finish : { height: newHeight, opacity : 100 },
3482					transition : BX.easing.makeEaseOut(BX.easing.transitions.quart),
3483
3484					step : BX.proxy(function(state){
3485						this.CONTENT_BLOCK.style.height = state.height + 'px';
3486						this.EDIT_TABLE.style.opacity = state.opacity / 100;
3487						BX.onCustomEvent('onAdminTabsChange');
3488					}, currentTab),
3489
3490					complete : BX.proxy(function(){
3491						this.CONTENT_BLOCK.style.height = "auto";
3492						this.CONTENT_BLOCK.style.overflowY = "visible";
3493						BX.onCustomEvent('onAdminTabsChange');
3494
3495					}, currentTab)
3496
3497				});
3498				easing.animate();
3499			}
3500			else
3501			{
3502				BX.onCustomEvent('onAdminTabsChange');
3503			}
3504		}
3505	}
3506};
3507
3508BX.adminTabControl.prototype.ShowTab = function(tab_id, bShow)
3509{
3510	if (bShow)
3511		BX.addClass(BX('tab_cont_' + tab_id), 'adm-detail-tab-active');
3512	else
3513		BX.removeClass(BX('tab_cont_' + tab_id), 'adm-detail-tab-active');
3514};
3515
3516BX.adminTabControl.prototype.ShowDisabledTab = function(tab_id, disabled)
3517{
3518	var tab = BX('tab_cont_'+tab_id);
3519	if(disabled)
3520	{
3521		BX.addClass(tab, 'adm-detail-tab-disable');
3522	}
3523	else
3524	{
3525		BX.removeClass(tab, 'adm-detail-tab-disable');
3526	}
3527};
3528
3529// TODO: rewrite
3530BX.adminTabControl.prototype.NextTab = function()
3531{
3532	var CurrentTab=BX(this.name+'_active_tab').value;
3533	var NextTab="";
3534
3535	for(var i=0; i<this.aTabs.length; i++)
3536		{
3537			if(CurrentTab==this.aTabs[i]["DIV"])
3538			{
3539				if(i>=(this.aTabs.length-1))
3540					NextTab=this.aTabs[0];
3541				else
3542					NextTab=this.aTabs[i+1];
3543			}
3544		}
3545
3546	if(NextTab["DIV"])
3547		this.SelectTab(NextTab["DIV"]);
3548};
3549
3550BX.adminTabControl.prototype.ToggleTabs = function()
3551{
3552	this.bExpandTabs = !this.bExpandTabs;
3553
3554	var a = BX(this.name+'_expand_link');
3555	a.title = (this.bExpandTabs? BX.message('JSADM_TABS_COLLAPSE') : BX.message('JSADM_TABS_EXPAND'));
3556	if (this.bExpandTabs)
3557	{
3558		BX.addClass(a, 'adm-detail-title-setting-active');
3559	}
3560	else
3561	{
3562		BX.removeClass(a, 'adm-detail-title-setting-active');
3563	}
3564
3565	for(var i=0; i < this.aTabs.length; i++)
3566	{
3567		var tab_id = this.aTabs[i]["DIV"];
3568		var div = BX(tab_id);
3569		this.ShowTab(tab_id, false);
3570		div.style.display = (this.bExpandTabs && !this.aTabsDisabled[tab_id]? 'block':'none');
3571	}
3572
3573	if(!this.bExpandTabs)
3574	{
3575		this.ShowTab(this.aTabs[0]["DIV"], true);
3576		div = document.getElementById(this.aTabs[0]["DIV"]);
3577		div.style.display = 'block';
3578	}
3579
3580	BX.userOptions.save('edit', this.unique_name, 'expand', (this.bExpandTabs? 'on': 'off'));
3581
3582	BX.onCustomEvent('OnToggleTabs');
3583	BX.onCustomEvent('onAdminTabsChange');
3584};
3585
3586
3587BX.adminTabControl.prototype.DisableTab = function(tab_id)
3588{
3589	this.aTabsDisabled[tab_id] = true;
3590	this.ShowDisabledTab(tab_id, true);
3591	if(this.bExpandTabs)
3592	{
3593		var div = BX(tab_id);
3594		if (div && div.style)
3595		{
3596			div.style.display = 'none';
3597		}
3598	}
3599};
3600
3601BX.adminTabControl.prototype.EnableTab = function(tab_id)
3602{
3603	this.aTabsDisabled[tab_id] = false;
3604	this.ShowDisabledTab(tab_id, this.bExpandTabs);
3605	if(this.bExpandTabs)
3606	{
3607		var div = BX(tab_id);
3608		if (div && div.style)
3609		{
3610			div.style.display = 'block';
3611		}
3612	}
3613};
3614
3615BX.adminTabControl.prototype.ShowWarnings = function(form_name, warnings)
3616{
3617	var form = document.forms[form_name];
3618	if(!form)
3619		return;
3620
3621	for(var i in warnings)
3622	{
3623		var e = form.elements[warnings[i]['name']];
3624
3625		if(!e)
3626			continue;
3627
3628		var type = (e.type? e.type.toLowerCase():'');
3629		var bBefore = false;
3630		if(e.length > 1 && type != 'select-one' && type != 'select-multiple')
3631		{
3632			e = e[0];
3633			bBefore = true;
3634		}
3635		if(type == 'textarea' || type == 'select-multiple')
3636			bBefore = true;
3637
3638		var td = e.parentNode;
3639		var img;
3640		if(bBefore)
3641		{
3642			img = td.insertBefore(new Image(), e);
3643			td.insertBefore(document.createElement("BR"), e);
3644		}
3645		else
3646		{
3647			img = td.insertBefore(new Image(), e.nextSibling);
3648			img.hspace = 2;
3649			img.vspace = 2;
3650			img.style.verticalAlign = 'middle';
3651		}
3652		img.src = '/bitrix/panel/main/images_old/icon_warn.gif';
3653		img.title = warnings[i]['title'];
3654	}
3655};
3656
3657BX.adminTabControl.prototype.ShowSettings = function(url)
3658{
3659	(new BX.CDialog({
3660			content_url: url,
3661			resizable: true,
3662			height: 605,
3663			width: 560
3664	})).Show();
3665};
3666
3667BX.adminTabControl.prototype.CloseSettings =  function()
3668{
3669	BX.WindowManager.Get().Close();
3670};
3671
3672BX.adminTabControl.prototype.SaveSettings =  function(el)
3673{
3674	var sTabs='', s='';
3675
3676	var oFieldsSelect;
3677	var oSelect = BX('selected_tabs');
3678	if(oSelect)
3679	{
3680		var k = oSelect.length;
3681		for(var i=0; i<k; i++)
3682		{
3683			s = oSelect[i].value + '--#--' + oSelect[i].text;
3684			oFieldsSelect = BX('selected_fields[' + oSelect[i].value + ']');
3685			if(oFieldsSelect)
3686			{
3687				var n = oFieldsSelect.length;
3688				for(var j=0; j<n; j++)
3689				{
3690					s += '--,--' + oFieldsSelect[j].value + '--#--' + jsUtils.trim(oFieldsSelect[j].text);
3691				}
3692			}
3693			sTabs += s + '--;--';
3694		}
3695	}
3696
3697	var bCommon = (document.form_settings.set_default && document.form_settings.set_default.checked);
3698
3699	var sParam = '';
3700	sParam += '&p[0][c]=form';
3701	sParam += '&p[0][n]='+BX.util.urlencode(this.name);
3702	if(bCommon)
3703		sParam += '&p[0][d]=Y';
3704	sParam += '&p[0][v][tabs]=' + BX.util.urlencode(sTabs);
3705
3706	var options_url = '/bitrix/admin/user_options.php?lang='+BX.message('LANGUAGE_ID')+'&sessid=' + BX.bitrix_sessid();
3707	options_url += '&action=delete&c=form&n='+this.name+'_disabled';
3708
3709	BX.WindowManager.Get().showWait(el);
3710	BX.ajax.post(options_url, sParam, BX.proxy(function() {
3711		BX.WindowManager.Get().closeWait(el);
3712		BX.WindowManager.Get().Close();
3713		location.reload();
3714	}, this));
3715};
3716
3717BX.adminTabControl.prototype.DeleteSettings = function(bCommon)
3718{
3719	BX.showWait();
3720	BX.userOptions.del('form', this.name, bCommon, function () {location.reload();});
3721};
3722
3723BX.adminTabControl.prototype.DisableSettings = function()
3724{
3725	var request = new JCHttpRequest;
3726	request.Action = function () {location.reload();};
3727	var sParam = '';
3728	sParam += '&p[0][c]=form';
3729	sParam += '&p[0][n]='+encodeURIComponent(this.name+'_disabled');
3730	sParam += '&p[0][v][disabled]=Y';
3731	request.Send('/bitrix/admin/user_options.php?lang=' + phpVars.LANGUAGE_ID + sParam + '&sessid='+phpVars.bitrix_sessid);
3732};
3733
3734BX.adminTabControl.prototype.EnableSettings = function()
3735{
3736	var request = new JCHttpRequest;
3737	request.Action = function () {location.reload();};
3738	var sParam = '';
3739	sParam += '&c=form';
3740	sParam += '&n='+encodeURIComponent(this.name)+'_disabled';
3741	sParam += '&action=delete';
3742	request.Send('/bitrix/admin/user_options.php?lang=' + phpVars.LANGUAGE_ID + sParam + '&sessid='+phpVars.bitrix_sessid);
3743};
3744
3745BX.adminViewTabControl = function(aTabs)
3746{
3747	this.aTabs = aTabs;
3748	this.bPublicMode = false;
3749	BX.ready(BX.delegate(this.Init, this));
3750};
3751
3752BX.adminViewTabControl.prototype.setPublicMode = function(v)
3753{
3754	this.bPublicMode = !!v;
3755};
3756
3757BX.adminViewTabControl.prototype.SelectTab = function(tab_id)
3758{
3759	var div = BX(tab_id);
3760	if(div.style.display != 'none')
3761		return;
3762
3763	var oldHeight = 0;
3764	var contentBlockPaddings = 41;
3765	for(var i in this.aTabs)
3766	{
3767		var tab_div = BX(this.aTabs[i]["DIV"]);
3768		if(tab_div.style.display != 'none')
3769		{
3770			var tab = BX('view_tab_'+this.aTabs[i]["DIV"]);
3771			BX.removeClass(tab, 'adm-detail-subtab-active');
3772
3773			var oldContentBlock = BX.findChild(tab_div, { className : "adm-detail-content-item-block-view-tab"});
3774			if (oldContentBlock)
3775				oldHeight = oldContentBlock.offsetHeight - contentBlockPaddings;
3776
3777			tab_div.style.display = 'none';
3778			break;
3779		}
3780	}
3781
3782	var active_tab = BX('view_tab_'+tab_id);
3783	BX.addClass(active_tab, 'adm-detail-subtab-active');
3784	div.style.display = 'block';
3785
3786	var newHeight = 0;
3787	var newContentBlock = BX.findChild(div, { className : "adm-detail-content-item-block-view-tab" });
3788	var newContentTable = null;
3789	if (newContentBlock)
3790	{
3791		newHeight = newContentBlock.offsetHeight - contentBlockPaddings;
3792		if (oldHeight > 0)
3793		{
3794			newContentBlock.style.height = oldHeight + "px";
3795			newContentBlock.style.overflowY = "hidden";
3796			newContentTable = BX.findChild(newContentBlock, { tagName : "table" });
3797			if (newContentTable)
3798				newContentTable.style.opacity = 0;
3799		}
3800	}
3801
3802	for(i in this.aTabs)
3803	{
3804		if(this.aTabs[i]["DIV"] == tab_id)
3805		{
3806			if(this.aTabs[i]["ONSELECT"])
3807			{
3808				BX.evalGlobal(this.aTabs[i]["ONSELECT"]);
3809			}
3810			break;
3811		}
3812	}
3813
3814	if (oldHeight > 0 && newHeight > 0 && newContentBlock)
3815	{
3816		var easing = new BX.easing({
3817			duration : 500,
3818			start : { height: oldHeight, opacity : 0 },
3819			finish : { height: newHeight, opacity : 100 },
3820			transition : BX.easing.makeEaseOut(BX.easing.transitions.quart),
3821
3822			step : BX.proxy(function(state){
3823				this.style.height = state.height + 'px';
3824				if (newContentTable)
3825					newContentTable.style.opacity = state.opacity / 100;
3826				BX.onCustomEvent('onAdminTabsChange');
3827			}, newContentBlock),
3828
3829			complete : BX.proxy(function(){
3830				this.style.height = "auto";
3831				this.style.overflowY = "visible";
3832				BX.onCustomEvent('onAdminTabsChange');
3833
3834			}, newContentBlock)
3835
3836		});
3837		easing.animate();
3838	}
3839	else
3840		BX.onCustomEvent('onAdminTabsChange');
3841};
3842
3843BX.adminViewTabControl.prototype.DisableTab = function(tab_id)
3844{
3845	if (this.aTabs.length <= 0)
3846	{
3847		return;
3848	}
3849
3850	var j = null;
3851	var bFound = false;
3852
3853	for(var i in this.aTabs)
3854	{
3855		if(this.aTabs[i]["DIV"] == tab_id)
3856		{
3857			if (i > 0)
3858			{
3859				j = parseInt(i) - 1;
3860				while (j >= 0)
3861				{
3862					if (BX('view_tab_' + this.aTabs[j]["DIV"]).style.display != 'none')
3863					{
3864						this.SelectTab(this.aTabs[j]["DIV"]);
3865						bFound = true;
3866						break;
3867					}
3868					j--;
3869				}
3870			}
3871
3872			if (!bFound)
3873			{
3874				j = parseInt(i) + 1;
3875				while (j < (this.aTabs.length - 1))
3876				{
3877					if (BX('view_tab_' + this.aTabs[j]["DIV"]).style.display != 'none')
3878					{
3879						this.SelectTab(this.aTabs[j]["DIV"]);
3880						bFound = true;
3881						break;
3882					}
3883					j++;
3884				}
3885			}
3886
3887			if (!bFound)
3888			{
3889				BX(tab_id).style.display = 'none';
3890			}
3891
3892			BX('view_tab_' + this.aTabs[i]["DIV"]).style.display = 'none';
3893			break;
3894		}
3895	}
3896};
3897
3898BX.adminViewTabControl.prototype.EnableTab = function(tab_id)
3899{
3900	for(var i in this.aTabs)
3901	{
3902		if(this.aTabs[i]["DIV"] == tab_id)
3903		{
3904			BX('view_tab_' + this.aTabs[i]["DIV"]).style.display = 'inline-block';
3905			this.SelectTab(this.aTabs[i]["DIV"]);
3906			break;
3907		}
3908	}
3909};
3910
3911BX.adminViewTabControl.prototype.ReplaceAnchor = function(tab)
3912{
3913};
3914
3915BX.adminViewTabControl.prototype.RebuildTabs = function()
3916{
3917
3918};
3919
3920BX.adminViewTabControl.prototype.Init = function()
3921{
3922	if(this.aTabs.length == 0)
3923		return;
3924};
3925
3926/***************************** simple history listener **********************/
3927
3928BX.adminHistory = function()
3929{
3930	BX.bind(window, 'popstate', BX.proxy(this._get, this));
3931
3932	this.bStart = true;
3933
3934	this.pushSupported = true;
3935	this.state = {};
3936	this.startState = null;
3937
3938	this.disabled = false;
3939};
3940
3941BX.adminHistory.pushSupported = false;
3942
3943BX.adminHistory.disable = BX.adminHistory.prototype.disable = function() {BX.adminHistory.disabled = true};
3944BX.adminHistory.enable = BX.adminHistory.prototype.enable = function() {BX.adminHistory.disabled = false};
3945
3946/* callback is useless here but should be here for compatibility reasons */
3947BX.adminHistory.put = function(url, callback, arIgnoreParams)
3948{
3949	if (BX.adminHistory.disabled)
3950		return;
3951
3952	var link = BX('navchain-link');
3953	if(link)
3954	{
3955		if (url.indexOf('&amp;') > 0)
3956			url = BX.util.htmlspecialcharsback(url);
3957		if (BX.type.isArray(arIgnoreParams))
3958			url = BX.util.remove_url_param(url, arIgnoreParams);
3959
3960		link.href = url;
3961		if (url != window.location.href)
3962			BX.addClass(link, 'navchain-link-visible');
3963		else
3964			BX.removeClass(link, 'navchain-link-visible');
3965	}
3966};
3967
3968BX.adminHistory.prototype.put = function(url, callback, arIgnoreParams)
3969{
3970	if (BX.adminHistory.disabled)
3971		return;
3972
3973	if (url.indexOf('&amp;') > 0)
3974		url = BX.util.htmlspecialcharsback(url);
3975	if (BX.type.isArray(arIgnoreParams))
3976		url = BX.util.remove_url_param(url, arIgnoreParams);
3977
3978	url = BX.util.remove_url_param(url, 'admin_history');
3979
3980	var state = {url: url, callback: callback};
3981
3982	var k = Math.random();
3983	this.state[k] = state;
3984
3985	if (this.bStart)
3986	{
3987		this.startState = k;
3988		this.bStart = false;
3989	}
3990	else
3991	{
3992		history.pushState(k, '', url);
3993	}
3994};
3995
3996BX.adminHistory.prototype._get = function(e)
3997{
3998	e = e || window.event || {state: null};
3999
4000	var state = e.state;
4001
4002	if(state === null)
4003	{
4004		state = this.startState;
4005	}
4006
4007	if (state && this.state[state])
4008	{
4009		if (this.state[state].callback)
4010		{
4011			this.state[state].callback(this.state[state].url + (this.state[state].url.indexOf('?')>0?'&':'?') + 'admin_history=Y')
4012		}
4013		else
4014		{
4015			window.location.href = this.state[state].url;
4016		}
4017	}
4018};
4019
4020/*************************** fixed elements *********************************/
4021
4022BX.FixOffsets = {
4023	top: 0,
4024	bottom: 0,
4025	right: 0
4026};
4027
4028BX.Fix = function(el, params)
4029{
4030	if (!el.BXFIXER)
4031	{
4032		if (el.tagName.toUpperCase() == 'THEAD')
4033			el.BXFIXER = new BX.CFixerTHead(el, params);
4034		else
4035			el.BXFIXER = new BX.CFixer(el, params);
4036	}
4037
4038	el.BXFIXER.Start()
4039};
4040
4041BX.UnFix = function(el)
4042{
4043	if (!!el && !!el.BXFIXER)
4044		el.BXFIXER.Stop()
4045};
4046
4047BX.CFixer = function(node, params)
4048{
4049	this.node = node;
4050	this.params = params || {type: 'top'};
4051
4052	this.pos = {};
4053	this.limit = -1;
4054
4055	this.position_top = null;
4056	this.position_bottom = null;
4057	this.position_right = null;
4058
4059	this.bStarted = false;
4060	this.bFixed = false;
4061
4062	this.gutter = null;
4063
4064	this.clingTop = null;
4065	this.clingBottom = null;
4066	this.clingRight = null;
4067};
4068
4069BX.CFixer.prototype.Start = function()
4070{
4071	if (this.bStarted)
4072		return;
4073
4074	this.pos = BX.pos(this.node);
4075
4076	BX.bind(window, 'scroll', BX.proxy(this._scroll_listener, this));
4077	BX.bind(window, 'resize', BX.proxy(this._scroll_listener, this));
4078	BX.bind(window, 'resize', BX.proxy(this._recalc_pos, this));
4079
4080	BX.addCustomEvent('onAdminFilterToggleRow', BX.proxy(this._recalc_pos, this));
4081	BX.addCustomEvent('onAdminFilterToggleRow', BX.proxy(this._scroll_listener, this));
4082	BX.addCustomEvent('onAdminPanelFix', BX.defer(this._scroll_listener, this));
4083	BX.addCustomEvent('onAdminPanelChange', BX.defer(this._scroll_listener, this));
4084	BX.addCustomEvent('onAdminTabsChange', BX.defer(this._recalc_pos, this));
4085	BX.addCustomEvent(BX.adminMenu, 'onAdminMenuResize', BX.proxy(this._recalc_pos, this));
4086	//BX.addCustomEvent(BX.adminMenu, 'onAdminMenuResize', BX.proxy(this._ReFix, this));
4087
4088	this._scroll_listener();
4089
4090	this.bStarted = true;
4091};
4092
4093BX.CFixer.prototype.Stop = function()
4094{
4095	if (!this.bStarted)
4096		return;
4097
4098	this._UnFix();
4099
4100	BX.unbind(window, 'scroll', BX.proxy(this._scroll_listener, this));
4101	BX.unbind(window, 'resize', BX.proxy(this._scroll_listener, this));
4102	BX.unbind(window, 'resize', BX.proxy(this._recalc_pos, this));
4103
4104	BX.removeCustomEvent('onAdminFilterToggleRow', BX.proxy(this._recalc_pos, this));
4105	BX.removeCustomEvent('onAdminFilterToggleRow', BX.proxy(this._scroll_listener, this));
4106	BX.removeCustomEvent('onAdminPanelFix', BX.defer(this._scroll_listener, this));
4107	BX.removeCustomEvent('onAdminTabsChange', BX.defer(this._recalc_pos, this));
4108	BX.removeCustomEvent('onAdminPanelChange', BX.defer(this._scroll_listener, this));
4109	//BX.removeCustomEvent(BX.adminMenu, 'onAdminMenuResize', BX.proxy(this._scroll_listener, this));
4110	BX.removeCustomEvent(BX.adminMenu, 'onAdminMenuResize', BX.proxy(this._recalc_pos, this));
4111
4112	this.bStarted = false;
4113};
4114
4115BX.CFixer.prototype._recalc_pos = function()
4116{
4117	this.pos = BX.pos(this.gutter || this.node);
4118	var node_pos = BX.pos(this.node);
4119
4120	if (this.bFixed)
4121	{
4122		if (this.params.type == 'top' || this.params.type == 'bottom')
4123		{
4124			this.node.style.width = this.pos.width + 'px';
4125			this.gutter.style.height = node_pos.height + 'px';
4126		}
4127	}
4128
4129	this._scroll_listener();
4130};
4131
4132BX.CFixer.prototype._Fix = function()
4133{
4134	if (!this.bFixed)
4135	{
4136		this.pos = BX.pos(this.gutter || this.node);
4137
4138		if (!this.gutter)
4139			this.gutter = this.node.parentNode.insertBefore(BX.create(
4140				this.node.tagName, {
4141					//style: {height: this.pos.height + 'px', width: this.pos.width + 'px'},
4142					style: {display: 'block', height: this.pos.height + 'px'},
4143					props: {className: this.node.className}
4144				}), this.node);
4145
4146		this._w = this.node.style.width;
4147		this.node.style.width = this.pos.width + 'px';
4148
4149		BX.addClass(this.node, 'bx-fixed-' + this.params.type);
4150
4151		if (this['position_' + this.params.type] !== null)
4152			this.node.style[this.params.type] = this['position_' + this.params.type] + 'px';
4153
4154		this.bFixed = true;
4155
4156		if(this.params.type == 'top')
4157		{
4158			this.clingTop = BX.FixOffsets.top;
4159			BX.FixOffsets.top += this.pos.height;
4160		}
4161
4162		BX.addCustomEvent('onAdminFixerUnfix', BX.proxy(this._cling_offset_correction, this));
4163	}
4164};
4165
4166BX.CFixer.prototype._UnFix = function(bRefix)
4167{
4168	if (this.bFixed)
4169	{
4170		this.node.style.width = this._w;
4171		BX.removeClass(this.node, 'bx-fixed-' + this.params.type);
4172
4173		this.node.style[this.params.type] = null;
4174
4175		this.bFixed = false;
4176
4177		if (!bRefix)
4178		{
4179			if (this.gutter && this.gutter.parentNode)
4180				this.gutter.parentNode.removeChild(this.gutter);
4181
4182			this.gutter = null;
4183
4184			this._check_scroll(this.pos.left, this.pos.top);
4185		}
4186
4187		var clingPoint, offsetSize;
4188
4189		if(this.params.type == 'top')
4190		{
4191			clingPoint = this.clingTop;
4192			offsetSize = this.pos.height;
4193			this.clingTop = null;
4194			BX.FixOffsets.top -= this.pos.height;
4195		}
4196
4197		BX.removeCustomEvent('onAdminFixerUnfix', BX.proxy(this._cling_offset_correction, this));
4198		BX.onCustomEvent('onAdminFixerUnfix', [{type: this.params.type, clingPoint: clingPoint, offsetSize: offsetSize}]);
4199	}
4200};
4201
4202BX.CFixer.prototype._ReFix = function()
4203{
4204	if (this.bFixed)
4205	{
4206		this._UnFix(true); BX.defer(this._Fix, this)();
4207	}
4208};
4209
4210BX.CFixer.prototype._cling_offset_correction = function(params)
4211{
4212	if(this.params.type == params.type)
4213	{
4214		if(this.params.type == 'top' && params.clingPoint < this.clingTop )
4215			this.clingTop -= params.offsetSize;
4216
4217		this._scroll_listener();
4218	}
4219};
4220
4221BX.CFixer.prototype._scroll_listener = function()
4222{
4223	var wndScroll = BX.GetWindowScrollPos(), bFixed = this.bFixed, wndSize;
4224
4225	if (!BX.isNodeInDom(this.node))
4226		return this.Stop();
4227
4228	var pos = bFixed ? this.pos : BX.pos(this.node);
4229
4230	if (this.params.limit_node)
4231	{
4232		var pos1 = BX.pos(this.params.limit_node);
4233
4234		switch(this.params.type)
4235		{
4236			case 'top':
4237				this.limit = pos1.bottom - this.pos.height;
4238			break;
4239			case 'bottom':
4240				this.limit = pos1.top + this.pos.height;
4241			break;
4242			case 'right':
4243				this.limit = pos1.right + this.node.offsetWidth;
4244			break;
4245		}
4246	}
4247
4248	if (!BX.isNodeHidden(this.node))
4249	{
4250		switch(this.params.type)
4251		{
4252			case 'top':
4253				var additive = this.clingTop !== null ? this.clingTop : BX.FixOffsets.top;
4254				this.position_top = BX.adminPanel.isFixed() ? BX.adminPanel.panel.offsetHeight + additive : additive;
4255
4256				if (this.limit > additive && wndScroll.scrollTop + this.position_top > this.limit)
4257					this._UnFix();
4258				else if (!this.bFixed && wndScroll.scrollTop + this.position_top >= pos.top)
4259					this._Fix();
4260				else if (this.bFixed && wndScroll.scrollTop + this.position_top < pos.top)
4261					this._UnFix();
4262
4263			break;
4264			case 'bottom':
4265				wndSize = BX.GetWindowInnerSize();
4266				wndScroll.scrollBottom = wndScroll.scrollTop + wndSize.innerHeight;
4267
4268				if (this.limit > 0 && wndScroll.scrollBottom < this.limit)
4269					this._UnFix();
4270				else if (!this.bFixed && wndScroll.scrollBottom < pos.bottom)
4271					this._Fix();
4272				else if (this.bFixed && wndScroll.scrollBottom >= pos.bottom)
4273					this._UnFix();
4274			break;
4275			case 'right':
4276				wndSize = BX.GetWindowInnerSize();
4277
4278				// 15 is a browser scrollbar fix
4279				wndScroll.scrollRight = wndScroll.scrollLeft + wndSize.innerWidth - 15;
4280
4281				if (this.limit > 0 && wndScroll.scrollRight < this.limit)
4282					this._UnFix();
4283				else if (!this.bFixed && wndScroll.scrollRight < pos.right)
4284					this._Fix();
4285				else if (this.bFixed && wndScroll.scrollRight >= pos.right)
4286					this._UnFix();
4287
4288			break;
4289		}
4290	}
4291	else if (this.bFixed)
4292	{
4293		this._UnFix();
4294	}
4295
4296	if (this.bFixed)
4297	{
4298		this._check_scroll(wndScroll.scrollLeft, wndScroll.scrollTop);
4299	}
4300	else
4301	{
4302		this._check_scroll(this.pos.left, this.pos.top);
4303	}
4304
4305	if (bFixed != this.bFixed)
4306	{
4307		BX.onCustomEvent(this.node, 'onFixedNodeChangeState', [this.bFixed]);
4308	}
4309};
4310
4311BX.CFixer.prototype._check_scroll = function(scrollLeft, scrollTop)
4312{
4313	if (this.params.type == 'top' || this.params.type == 'bottom')
4314		this.node.style.left = (this.pos.left - scrollLeft) + 'px';
4315	else
4316		this.node.style.top = (this.pos.top - scrollTop) + 'px';
4317
4318	if (this.bFixed && this['position_' + this.params.type] !== null)
4319	{
4320		this.node.style[this.params.type] = this['position_' + this.params.type] + 'px';
4321	}
4322};
4323
4324BX.CFixerTHead = function()
4325{
4326	BX.CFixerTHead.superclass.constructor.apply(this, arguments);
4327
4328	this.mirror = null;
4329	this.mirror_thead = null;
4330};
4331BX.extend(BX.CFixerTHead, BX.CFixer);
4332
4333BX.CFixerTHead.prototype._Fix = function()
4334{
4335	if (!this.bFixed)
4336	{
4337		if (!this.mirror)
4338		{
4339			this.pos = BX.pos(this.node);
4340
4341			var wndScroll = BX.GetWindowScrollPos();
4342
4343			this.mirror_thead = BX.clone(this.node);
4344
4345			this.mirror = document.body.appendChild(
4346				BX.create('DIV', {
4347					style: {
4348						left: (this.pos.left-wndScroll.scrollLeft) + 'px'
4349					},
4350					props: {className: 'bx-fixed-' + this.params.type + ' adm-list-table-fixed'},
4351					children:[
4352						BX.create('TABLE', {
4353							props: {className: this.node.parentNode.className},
4354							style: {width: this.node.parentNode.offsetWidth + 'px'},
4355							children: [this.mirror_thead]
4356						})
4357					]
4358				})
4359			);
4360
4361			for (var i = 0; i < this.node.rows[0].cells.length; i++)
4362			{
4363				this.mirror_thead.rows[0].cells[i].appendChild(
4364					BX.create('SPAN', {
4365						style: {
4366							cssFloat: 'left',
4367							height: '1px'
4368						},
4369						html: '<img src="/bitrix/images/1.gif" style="height: 0; width: ' + (this.node.rows[0].cells[i].offsetWidth-4) + 'px;">'
4370					}));
4371
4372				this.mirror_thead.rows[0].cells[i].style.width = this.node.rows[0].cells[i].offsetWidth + 'px';
4373			}
4374		}
4375
4376		this.mirror.style.display = 'block';
4377		this.mirror.style.top = (this.position_top !== null ? this.position_top : 0) + 'px';
4378		this.bFixed = true;
4379	}
4380};
4381
4382BX.CFixerTHead.prototype._UnFix = function()
4383{
4384	if (this.bFixed)
4385	{
4386		if (!!this.mirror)
4387		{
4388			this._clear_mirror();
4389		}
4390
4391		this.bFixed = false;
4392	}
4393};
4394
4395BX.CFixerTHead.prototype._recalc_pos = function()
4396{
4397	this.pos = BX.pos(this.node);
4398
4399	if (this.bFixed && (this.params.type == 'top' || this.params.type == 'bottom'))
4400	{
4401		this.mirror.firstChild.style.width = this.pos.width + 'px';
4402	}
4403
4404	this._scroll_listener();
4405};
4406
4407
4408BX.CFixerTHead.prototype._clear_mirror = function()
4409{
4410	if (!!this.mirror)
4411		this.mirror.parentNode.removeChild(this.mirror);
4412
4413	this.mirror = null;
4414	this.mirror_thead = null;
4415};
4416
4417BX.CFixerTHead.prototype._check_scroll = function(scrollLeft)
4418{
4419	if (!!this.mirror)
4420	{
4421		this.mirror.style.left = (this.pos.left - scrollLeft) + 'px';
4422		if (this.bFixed && this['position_' + this.params.type] !== null)
4423			this.mirror.style[this.params.type] = this['position_' + this.params.type] + 'px'
4424	}
4425};
4426
4427/******************************** admin menu unification ********************/
4428
4429BX.adminShowMenu = function(el, menu, params)
4430{
4431	if (el.OPENER)
4432		return true;
4433
4434	var bindElement = el,
4435		pseudo_el = null;
4436
4437	if (typeof el == 'object' && !BX.type.isElementNode(el) && typeof el.x != 'undefined')
4438	{
4439		pseudo_el = document.body.appendChild(BX.create('DIV', {
4440			style: {
4441				position: 'absolute',
4442				left: el.x + 'px',
4443				top: el.y + 'px',
4444				height: 0,
4445				width: 0
4446			}
4447		}));
4448
4449		bindElement = pseudo_el;
4450	}
4451
4452	params = params || {};
4453
4454	bindElement.OPENER = new BX.COpener({
4455		DIV: bindElement,
4456		MENU: menu,
4457		TYPE: 'click',
4458		ACTIVE_CLASS: (typeof params.active_class != 'undefined') ? params.active_class : 'adm-btn-active',
4459		PUBLIC_FRAME: (typeof params.public_frame != 'undefined') ? parseInt(params.public_frame) : 0,
4460		CLOSE_ON_CLICK: (typeof params.close_on_click != 'undefined') ? !!params.close_on_click : true
4461	});
4462
4463	var f = function()
4464	{
4465		BX.onCustomEvent(el, 'onAdminMenuClose');
4466
4467		if (!!pseudo_el)
4468		{
4469			pseudo_el.parentNode.removeChild(pseudo_el);
4470			pseudo_el = null;
4471		}
4472
4473		bindElement = null;
4474	};
4475
4476	BX.addCustomEvent(bindElement.OPENER, 'onOpenerMenuClose', f);
4477	BX.addCustomEvent(bindElement.OPENER, 'onOpenerMenuOpen', function() {
4478		BX.onCustomEvent(el, 'onAdminMenuShow');
4479	});
4480
4481	bindElement.OPENER.Toggle();
4482};
4483
4484/****************Admin Filter********************************/
4485
4486BX.AdminFilter = function(filter_id, aRows)
4487{
4488	var _this = this;
4489	this.filter_id = filter_id;
4490	this.aRows = aRows;
4491	this.oVisRows = {};
4492	this.oOptions = {};
4493	this.curID = "0";
4494	this.form = jsUtils.FindParentObject(BX(this.filter_id), "form");
4495	this.popupItems = {};
4496	this.missingRows = 0;
4497	this.tableWrap = null;
4498	this.table = null;
4499	this.easing = null;
4500	this.startContentHeight = 0;
4501	this.table_id = false;
4502	this.url = false;
4503	this.currentLoadedTab = null;
4504	this.presetsDeleted = [];
4505
4506	this.state = {
4507		init: false,
4508		requesting: false,
4509		clearing: false,
4510		folded: false,
4511		saving: false
4512	};
4513
4514	//saving in session or cookie
4515	this.params = {
4516		filteredId: false,
4517		activeTabId: false
4518	};
4519
4520	this.SetFoldedView = function()
4521	{
4522		BX.toggleClass(BX('adm-filter-tab-wrap-'+this.filter_id), 'adm-filter-folded');
4523		this.state.folded = !this.state.folded;
4524		BX.userOptions.save('filter', this.filter_id, 'styleFolded', this.state.folded ? "Y" : "N");
4525		this.SetSwitcherTitle();
4526	};
4527
4528	this.SetSwitcherTitle = function()
4529	{
4530		var switcher = BX("adm-filter-switcher-tab");
4531		var wrap = BX("adm-filter-tab-wrap-"+this.filter_id);
4532
4533		switcher.title = BX.hasClass(wrap,"adm-filter-folded") ? BX.message('JSADM_FLT_UNFOLD') : BX.message('JSADM_FLT_FOLD');
4534	};
4535
4536	this.InitFilter = function(oVisRows)
4537	{
4538		var vREmpty = this.isObjectEmpty(oVisRows);
4539
4540		this.SetSwitcherTitle();
4541
4542		this.oVisRows = oVisRows;
4543
4544		var tbl = BX(this.filter_id);
4545
4546		if(!tbl)
4547			return;
4548
4549		this.table = tbl;
4550
4551		var n=tbl.rows.length;
4552		this.missingRows = tbl.rows.length - this.aRows.length;
4553		var diff = this.missingRows;
4554
4555		for(var i=n-1; i>=0; i--)
4556		{
4557			var row = tbl.rows[i];
4558			var td = row.insertCell(-1);
4559			var tail = "";
4560			BX.admFltWrap.Row(row);
4561
4562			if( i-diff >=0 )
4563			{
4564				tail = this.aRows[i-diff];
4565			}
4566			else
4567			{
4568				tail = "miss-"+i;
4569				this.aRows.unshift(tail);
4570
4571				if(vREmpty)
4572					this.oVisRows[tail] = true;
4573			}
4574
4575			row.id = this.filter_id+'_row_'+tail;
4576
4577			if(this.oVisRows[tail] != true)
4578				row.style.display = 'none';
4579
4580			td.innerHTML = '<span class="adm-filter-item-delete" onclick="this.blur(); '+this.filter_id+'.DeleteFilterRow(\''+row.id+'\');" hidefocus="true" title="'+phpVars.messFilterLess+'" style="display: none;"></span>';
4581		}
4582
4583		for(i=0; i<n; i++)
4584		{
4585			var tr = tbl.insertRow(i*2+1);
4586
4587			if(this.oVisRows[this.aRows[i]] != true)
4588				tr.style.display = 'none';
4589			tr.id = this.filter_id+'_row_'+this.aRows[i]+'_delim';
4590
4591			td = tr.insertCell(-1);
4592			td.colSpan = 3;
4593			td.className = 'delimiter';
4594			td.innerHTML = '<div class="empty"></div>';
4595		}
4596
4597		try{
4598			tbl.style.display = 'table';}
4599		catch(e){
4600			tbl.style.display = 'block';}
4601
4602		this.tableWrap = tbl.parentNode;
4603
4604		this.DisplayNonEmptyRows();
4605		this.ChangeViewDependVisible();
4606
4607		BX.addCustomEvent(window, "onAdminListLoaded", BX.proxy(this.onAdminListLoaded, this));
4608		BX.onCustomEvent(window, "onAdminFilterInited", [{filterId: this.filter_id}]);
4609	};
4610
4611	this.InitFirst = function()
4612	{
4613		this.oOptions["0"] = {
4614			FIELDS: {},
4615			EDITABLE: false
4616		};
4617
4618		for(var i in this.oOptions)
4619			this.oOptions[i]["tab"] = new BX.admFltTab(i,this);
4620	};
4621
4622	this.InitFilteredTab = function(tabId)
4623	{
4624		var flterId = false;
4625
4626		if(this.oOptions[tabId])
4627			flterId = tabId;
4628		else
4629			flterId = this.GetByPresetId(tabId);
4630
4631		if(flterId === false)
4632			return false;
4633
4634		if(!this.ApplyFilter(flterId))
4635			return false;
4636
4637		if(this.state.folded)
4638		{
4639			this.oOptions["0"]["tab"].UnSetActive();
4640			this.oOptions[flterId]["tab"].SetActive();
4641		}
4642
4643		this.oOptions[flterId]["tab"].SetFiltered(true);
4644		return true;
4645	};
4646
4647	this.InitOpenedTab = function(tabIdUri, tabIdSes)
4648	{
4649
4650		var tabIds = [tabIdUri, tabIdSes];
4651
4652		var openedTabObj, openedTabId;
4653
4654		for(var i in tabIds)
4655		{
4656			var tabId = tabIds[i];
4657
4658			if(tabId=="")
4659				continue;
4660
4661			openedTabId = false;
4662
4663			if(this.oOptions[tabId])
4664				openedTabId = tabId;
4665			else
4666				openedTabId = this.GetByPresetId(tabId);
4667
4668			if(openedTabId === false)
4669				continue;
4670
4671			openedTabObj = BX("adm-filter-tab-"+this.filter_id+'-'+openedTabId);
4672
4673			if(openedTabObj)
4674				break;
4675		}
4676
4677		if(!openedTabObj)
4678				return false;
4679
4680		//openedTabObj.onclick();
4681		this.SetActiveTab(openedTabObj);
4682		this.ApplyFilter(openedTabId);
4683
4684		if(openedTabId == tabIdUri)
4685			this.SaveFilterParams();
4686
4687		return true;
4688	};
4689
4690	this.GetByPresetId = function(presetId)
4691	{
4692		for(var i in  this.oOptions )
4693			if(this.oOptions[i] && this.oOptions[i]["PRESET_ID"] && this.oOptions[i]["PRESET_ID"] == presetId)
4694				return i;
4695
4696		return false;
4697	};
4698
4699	this.isObjectEmpty = function( obj )
4700	{
4701		for ( var key in obj )
4702			return false;
4703
4704		return true;
4705	};
4706
4707	this.ChangeViewDependVisible = function()
4708	{
4709		var countVR = this.CountVisibleRows();
4710
4711		if(countVR < 1)
4712			this.ToggleFilterRow(this.filter_id+'_row_'+this.aRows[0], true);
4713
4714		if(countVR <= 1)
4715			this.ToggleButtonsHideAll();
4716
4717		if(countVR >= 2)
4718			this.ToggleButtonsShowAll();
4719
4720		this.SetBottomStyle();
4721	};
4722
4723	this.UrlAddParams = function(url, sParams)
4724	{
4725		var retUrl = url;
4726		var lastUrlSymb = url.substr(url.length-1);
4727
4728		if(retUrl.indexOf('?') >= 0)
4729		{
4730			if(lastUrlSymb!='&')
4731				retUrl += '&';
4732		}
4733		else
4734		{
4735			retUrl += '?';
4736		}
4737
4738		retUrl+=sParams;
4739
4740		return retUrl;
4741	};
4742
4743	this.OnSet = function(table_id, url, oButt)
4744	{
4745		if(!window[table_id])
4746		{
4747			return true;
4748		}
4749
4750		if(this.state.requesting)
4751		{
4752			return false;
4753		}
4754
4755		if(!this.table_id)
4756		{
4757			this.table_id = table_id;
4758		}
4759
4760		if(!this.url)
4761		{
4762			this.url = url;
4763		}
4764
4765		BX.onCustomEvent(window, 'onBeforeAdminFilterSet');
4766
4767		if(this.curID != "0" && !this.state.init)
4768		{
4769			this.Save();
4770		}
4771
4772		var filterUrl = this.UrlAddParams(url,'set_filter=Y&adm_filter_applied='+encodeURIComponent(this.curID));
4773
4774		if(this.oOptions[this.curID]["PRESET_ID"])
4775		{
4776			filterUrl+=this.UrlAddParams(filterUrl,"adm_filter_preset="+encodeURIComponent(this.oOptions[this.curID]["PRESET_ID"]));
4777		}
4778
4779		var params = this.GetParameters();
4780
4781		this.state.requesting = true;
4782
4783		BX.defer(function()
4784		{
4785			if(_this.state.folded)
4786			{
4787				_this.currentLoadedTab = _this.oOptions[_this.curID]["tab"].GetObj();
4788				_this.oOptions[_this.curID]["tab"].ShowWheel();
4789
4790			}
4791			else
4792			{
4793				BX.adminPanel.showWait(oButt);
4794			}
4795
4796			//wait until filter ajax-saving
4797			var waiter =
4798			{
4799				func: function()
4800				{
4801					if (!_this.state.saving)
4802					{
4803						window[table_id].GetAdminList(filterUrl+params);
4804						_this.oOptions[_this.curID]["tab"].SetFiltered(_this.state.init);
4805						clearInterval(intervalID);
4806					}
4807				}
4808			};
4809
4810			var intervalID = window.setInterval(function(){ waiter.func.call(waiter) }, 200);
4811
4812		})();
4813
4814		return false;
4815	};
4816
4817	this.OnClear = function(table_id, url, oButt)
4818	{
4819		if(!window[table_id])
4820		{
4821			return true;
4822		}
4823
4824		if(this.state.requesting)
4825		{
4826			return false;
4827		}
4828
4829		this.state.clearing = true;
4830		BX.onCustomEvent(window, 'onBeforeAdminFilterClear');
4831		var filterUrl = this.UrlAddParams(url,"del_filter=Y"+this.GetParameters());
4832
4833		this.state.requesting = true;
4834
4835		BX.defer(function()
4836		{
4837			if(_this.state.folded)
4838			{
4839				_this.currentLoadedTab = _this.oOptions[_this.curID]["tab"].GetObj();
4840				_this.oOptions[_this.curID]["tab"].ShowWheel();
4841			}
4842			else
4843			{
4844				BX.adminPanel.showWait(oButt);
4845			}
4846
4847			if(_this.params.filteredId && _this.oOptions[_this.params.filteredId] && !_this.state.folded)
4848			{
4849				_this.oOptions[_this.params.filteredId]["tab"].UnSetFiltered();
4850			}
4851
4852			window[table_id].GetAdminList(filterUrl);
4853		})();
4854
4855		return false;
4856	};
4857
4858	//when window[table_id].GetAdminList(...) executed
4859	this.onAdminListLoaded = function()
4860	{
4861		if (this.currentLoadedTab === false)
4862			return;
4863
4864		BX.removeClass(this.currentLoadedTab, "adm-filter-tab-loading");
4865
4866		if(this.state.clearing && this.params.filteredId !== false && this.oOptions[this.params.filteredId])
4867			this.oOptions[this.params.filteredId]["tab"].UnSetFiltered();
4868
4869		this.currentLoadedTab = null;
4870		this.state.clearing = false;
4871		this.state.requesting = false;
4872	};
4873
4874	this.GetFormButton = function(name)
4875	{
4876		if(!name)
4877			return false;
4878
4879		var button = BX(this.filter_id+name);
4880
4881		if(button)
4882			return button;
4883
4884		return this.form[name];
4885	};
4886
4887	this.ApplyFilter = function(id)
4888	{
4889		if(this.state.requesting && !this.state.init)
4890			return false;
4891
4892		if(!this.oOptions[id])
4893			return false;
4894
4895		if(this.curID == "0")
4896			this.oOptions["0"]["FIELDS"] = this.GetFilterFields(true);
4897
4898		this.curID = id;
4899
4900		this.StartAnimation();
4901
4902		this.SetFilterFields(this.oOptions[id]["FIELDS"]);
4903
4904		if(!this.state.init)
4905		{
4906			//this.SaveOpenTab(id);
4907			this.SaveFilterParams();
4908		}
4909
4910		this.EndAnimation();
4911
4912		if(this.state.folded && !this.state.init)
4913		{
4914			this.currentLoadedTab = this.oOptions[id]["tab"].GetObj();
4915			this.oOptions[id]["tab"].ShowWheel();
4916
4917			//click on pressed button
4918			if(this.params.filteredId === id)
4919			{
4920				var clearButton = this.GetFormButton('del_filter');
4921
4922				if(this.filter_id  && this.url)
4923				{
4924					this.OnClear(this.table_id, this.url, clearButton);
4925				}
4926				else
4927				{
4928					if(clearButton)
4929						clearButton.onclick();
4930				}
4931			}
4932			else // click on unpressed button
4933			{
4934				var setFilterButton = this.GetFormButton('set_filter');
4935
4936				if(this.filter_id  && this.url)
4937				{
4938					this.OnSet(this.table_id, this.url, setFilterButton);
4939				}
4940				else
4941				{
4942					if(setFilterButton)
4943						setFilterButton.onclick();
4944					else
4945						this.form.submit();
4946				}
4947			}
4948		}
4949
4950		return true;
4951	};
4952
4953	this.Save = function(saveAs)
4954	{
4955		var fields = this.GetFilterFields(true);
4956
4957		if((!this.oOptions[this.curID]["EDITABLE"] && !saveAs))
4958		{
4959			this.SaveInsteadPreset();
4960			return;
4961		}
4962
4963		if(saveAs || this.curID == "0")
4964			this.ShowSaveOptsWnd(fields, false);
4965		else
4966		{
4967			var common = (this.oOptions[this.curID]["COMMON"] == 'Y');
4968			this.SaveToBase(this.oOptions[this.curID]["NAME"], common, fields, false, false);
4969		}
4970	};
4971
4972	this.SaveAs = function()
4973	{
4974		this.Save(true);
4975	};
4976
4977	this.Delete = function()
4978	{
4979		if(!this.oOptions[this.curID].EDITABLE)
4980			this.MarkPresetAsDeleted(this.curID);
4981		else
4982			this.DeleteFromBase(this.curID);
4983	};
4984
4985	this.GetClearFields = function()
4986	{
4987		var fields = this.GetFilterFields();
4988
4989		for(var key in fields)
4990			fields[key]["value"] = "";
4991
4992		return fields;
4993	};
4994
4995	this.ReplaceFilterTab = function(oldId, newId)
4996	{
4997		if(!oldId || !newId)
4998			return false;
4999
5000		var tab = BX("adm-filter-tab-"+this.filter_id+"-"+oldId);
5001
5002		if(!tab)
5003			return false;
5004
5005		tab.id = "adm-filter-tab-"+this.filter_id+"-"+newId;
5006
5007		if(this.url && BX.adminMenu && BX.adminMenu.registerItem)
5008		{
5009			var registerUrl = BX.util.remove_url_param(this.url,["adm_filter_applied","adm_filter_preset"]);
5010			registerUrl += "&adm_filter_applied" + '=' + BX.util.urlencode(newId);
5011			BX.adminMenu.registerItem(tab.id, {URL: registerUrl});
5012		}
5013
5014		tab.onclick = function(){ _this.SetActiveTab(this); _this.ApplyFilter(newId); };
5015
5016		this.MarkPresetAsDeleted(oldId,newId);
5017
5018		return true;
5019	};
5020
5021	this.SetFilteredBG = function(id)
5022	{
5023		if(!this.params.filteredId && id !== false)
5024			return;
5025
5026		if(id == this.params.filteredId && id !== false)
5027			BX.addClass(BX("adm-filter-tab-wrap-"+this.filter_id),"adm-current-filter");
5028		else
5029		{
5030			BX.removeClass(BX("adm-filter-tab-wrap-"+this.filter_id),"adm-current-filter");
5031		}
5032	};
5033
5034	this.SetActiveTab = function(tabObj)
5035	{
5036		if(this.state.requesting && !this.state.init)
5037			return false;
5038
5039		var tabIdBegin = "adm-filter-tab-"+this.filter_id+"-";
5040		var tabId = tabObj.id.substr(tabIdBegin.length,tabObj.id.length);
5041
5042		if(this.params.filteredId!== false && this.params.filteredId === tabId && this.state.folded)
5043			return true;
5044
5045		var arPrevSelTabs = BX.findChildren(tabObj.parentNode, {tag: "span"} ,false);
5046
5047		for (var i=arPrevSelTabs.length-1; i>=0; i--)
5048			BX.removeClass(arPrevSelTabs[i] ,"adm-filter-tab-active");
5049
5050		this.SetFilteredBG(tabId);
5051		this.oOptions[tabId]["tab"].SetActive();
5052		this.params.activeTabId = tabId;
5053
5054		return true;
5055	};
5056
5057	this.ShowSaveOptsWnd = function(fields, empty)
5058	{
5059		var bCreated = false;
5060		if(!window['filterSaveOptsDialog'+this.filter_id])
5061		{
5062			window['filterSaveOptsDialog'+this.filter_id] = new BX.CDialog({
5063				'content':'<form name="flt_save_opts_'+this.filter_id+'" onkeypress=" return '+this.filter_id+'.SaveOptsWndKeyPress(event);"></form>',
5064				'title': BX.message('JSADM_FLT_SAVE_TITLE'),
5065				'width': 450,
5066				'height': 100,
5067				'resizable': false
5068			});
5069			bCreated = true;
5070		}
5071
5072		var formOpts = document['flt_save_opts_'+this.filter_id];
5073
5074		formOpts.onKeyPress = this.onKeyPress;
5075		var fsTable= BX('filter_save_opts_'+this.filter_id).children[0];
5076
5077		window['filterSaveOptsDialog'+this.filter_id].ClearButtons();
5078
5079		window['filterSaveOptsDialog'+this.filter_id].SetButtons([
5080			{
5081				'id': this.filter_id+"_btn_save",
5082				'className':'adm-btn-save',
5083				'title': BX.message('JSADM_FLT_SAVE'),
5084				'action': function(){
5085
5086					var common;
5087					if(formOpts.common)
5088						common = formOpts.common.checked;
5089					else
5090						common = false;
5091
5092					_this.SaveToBase(formOpts.save_filter_name.value, common, fields, true, empty);
5093
5094					if(_this.state.folded)
5095						_this.SetFoldedView();
5096
5097					this.parentWindow.Close();
5098				}
5099			},
5100			BX.CDialog.prototype.btnCancel
5101		]);
5102
5103		window['filterSaveOptsDialog'+this.filter_id].adjustSizeEx();
5104		window['filterSaveOptsDialog'+this.filter_id].Show();
5105
5106		if(bCreated)
5107			formOpts.appendChild(fsTable);
5108
5109		if(this.curID != "0" && !empty)
5110		{
5111			formOpts.save_filter_name.value = (this.oOptions[this.curID]["NAME"] ? this.oOptions[this.curID]["NAME"] : '');
5112
5113			if(formOpts.common)
5114				formOpts.common.checked = (this.oOptions[this.curID]["COMMON"] == 'Y');
5115		}
5116		else
5117		{
5118			formOpts.save_filter_name.value = BX.message('JSADM_FLT_NEW_NAME');
5119
5120			if(formOpts.common)
5121				formOpts.common.checked = false;
5122		}
5123
5124		formOpts.save_filter_name.focus();
5125	};
5126
5127	this.SaveOptsWndKeyPress = function(event)
5128	{
5129		if(!event)
5130			event = window.event;
5131
5132		if(!event)
5133			return true;
5134
5135		if(event.keyCode == 13)
5136		{
5137			BX(this.filter_id+"_btn_save").click();
5138			return false;
5139		}
5140
5141		if(event.keyCode == 27)
5142		{
5143			window['filterSaveOptsDialog'+this.filter_id].Close();
5144			return false;
5145		}
5146
5147		return true;
5148	};
5149
5150	this.MarkPresetAsDeleted = function(oldId, newId)
5151	{
5152		if(!newId && !confirm(BX.message('JSADM_FLT_DEL_CONFIRM')))
5153			return;
5154
5155		this.presetsDeleted[this.presetsDeleted.length] = oldId;
5156
5157		var strOpt = '';
5158
5159		for(var key in this.presetsDeleted)
5160				strOpt += (strOpt != ''? ',':'')+this.presetsDeleted[key];
5161
5162		var bCurrentFiltered = false;
5163
5164		if(this.params.filteredId == this.curID)
5165			bCurrentFiltered = true;
5166
5167		var tabId = "0";
5168
5169		if(newId)
5170		{
5171			this.oOptions[this.curID]["tab"].id = this.curID = tabId = newId;
5172		}
5173		else
5174		{
5175			this.oOptions[oldId]["tab"].DeleteHtml();
5176			delete this.oOptions[oldId];
5177		}
5178
5179		var newActiveTab = this.oOptions[tabId]["tab"].GetObj();
5180
5181		if(newActiveTab)
5182			newActiveTab.click();
5183
5184		BX.userOptions.save('filter', this.filter_id, 'presetsDeleted', strOpt);
5185
5186		if(bCurrentFiltered && this.table_id && !newId)
5187			this.OnClear(this.table_id,this.url);
5188	};
5189
5190	this.DeleteFromBase = function(id)
5191	{
5192		this.state.saving = true;
5193		if(!confirm(BX.message('JSADM_FLT_DEL_CONFIRM')))
5194			return;
5195
5196		var data = {
5197			'id': id,
5198			'action': 'del_filter',
5199			'sessid': phpVars.bitrix_sessid,
5200			'lang': BX.message("LANGUAGE_ID")
5201		};
5202
5203		var callback = function(result)
5204		{
5205			if(result)
5206			{
5207				_this.oOptions[id]["tab"].DeleteHtml();
5208				delete _this.oOptions[id];
5209
5210				var bCurrentFiltered = false;
5211
5212				if(_this.params.filteredId == _this.curID)
5213					bCurrentFiltered = true;
5214
5215				var defaultTab = _this.oOptions["0"]["tab"].GetObj();
5216
5217				if(defaultTab)
5218					defaultTab.click();
5219
5220				_this.state.saving = false;
5221
5222				if(_this.table_id && bCurrentFiltered)
5223					_this.OnClear(_this.table_id,_this.url);
5224			}
5225			else
5226				alert(BX.message('JSADM_FLT_DEL_ERROR'));
5227		};
5228
5229		BX.ajax.post('/bitrix/admin/filter_act.php', data, callback);
5230
5231	};
5232
5233	this.SaveInsteadPreset = function()
5234	{
5235		this.state.saving = true;
5236		var data = {
5237			'filter_id': this.filter_id,
5238			'preset_id': this.curID,
5239			'action': 'save_filter',
5240			'sessid': phpVars.bitrix_sessid,
5241			'name': this.oOptions[this.curID]["NAME"],
5242			'common': 'N',
5243			'fields': _this.GetFilterFields(),
5244			'lang': BX.message("LANGUAGE_ID")
5245		};
5246
5247		if(this.oOptions[this.curID]["SORT_FIELD"])
5248			data['sort_field'] = this.oOptions[this.curID]["SORT_FIELD"];
5249
5250		if(this.oOptions[this.curID]["SORT"])
5251			data['sort'] = this.oOptions[this.curID]["SORT"];
5252
5253		var callback = function(resultId)
5254		{
5255			if(resultId)
5256			{
5257				_this.oOptions[resultId] =
5258				{
5259					NAME: _this.oOptions[_this.curID]["NAME"],
5260					FIELDS: _this.GetFilterFields(),
5261					EDITABLE: true,
5262					PRESET_ID: _this.curID,
5263					COMMON: false
5264				};
5265
5266				_this.oOptions[resultId]["tab"] = new BX.admFltTab(resultId,_this);
5267
5268				if(data['sort_field'])
5269					_this.oOptions[resultId]["SORT_FIELD"] = data['sort_field'];
5270
5271				if(data['sort'])
5272					_this.oOptions[resultId]["SORT"] = data['sort'];
5273
5274				_this.ReplaceFilterTab(_this.curID, resultId);
5275				_this.state.saving = false;
5276			}
5277			else
5278				alert(BX.message('JSADM_FLT_SAVE_ERROR'));
5279		};
5280
5281		BX.ajax.post('/bitrix/admin/filter_act.php', data, callback);
5282	};
5283
5284
5285	this.SaveToBase = function(name, common, fields, saveAs, empty)
5286	{
5287		this.state.saving = true;
5288		if(name=="")
5289			name = BX.message('JSADM_FLT_NO_NAME');
5290
5291		var data = {
5292			'filter_id': this.filter_id,
5293			'action': 'save_filter',
5294			'sessid': phpVars.bitrix_sessid,
5295			'name': name,
5296			'common': common ? 'Y' : 'N',
5297			'fields': fields,
5298			'lang': BX.message("LANGUAGE_ID")
5299		};
5300
5301		if(!saveAs && this.curID != "0")
5302			data['id']=this.curID;
5303
5304		if(!saveAs && this.oOptions[this.curID]["PRESET_ID"])
5305			data['preset_id']=this.oOptions[this.curID]["PRESET_ID"];
5306
5307		if(this.oOptions[this.curID]["SORT_FIELD"])
5308			data['sort_field'] = this.oOptions[this.curID]["SORT_FIELD"];
5309
5310		if(this.oOptions[this.curID]["SORT"])
5311			data['sort'] = this.oOptions[this.curID]["SORT"];
5312
5313		var callback = function(resultId)
5314		{
5315			if(resultId)
5316			{
5317				_this.oOptions[resultId] =
5318				{
5319					NAME: name,
5320					COMMON: common ? "Y" : "N",
5321					FIELDS: fields,
5322					EDITABLE: true
5323				};
5324
5325				if(data['sort_field'])
5326					_this.oOptions[resultId]["SORT_FIELD"] = data['sort_field'];
5327
5328				if(data['sort'])
5329					_this.oOptions[resultId]["SORT"] = data['sort'];
5330
5331				_this.oOptions[resultId]["tab"] = new BX.admFltTab(resultId,_this);
5332
5333				if(saveAs || data['id'] == undefined)
5334					_this.oOptions[resultId]["tab"].AddHtml(_this.url, name);
5335
5336				if(empty)
5337					_this.ClearParameters();
5338
5339				_this.state.saving = false;
5340			}
5341			else
5342				alert(BX.message('JSADM_FLT_SAVE_ERROR'));
5343		};
5344
5345		BX.ajax.post('/bitrix/admin/filter_act.php', data, callback);
5346
5347		return data;
5348	};
5349
5350	this.ClearParameters = function()
5351	{
5352		if(!this.form)
5353			return;
5354
5355		var i;
5356		var n = this.form.elements.length;
5357		for(i=0; i<n; i++)
5358		{
5359			var el = this.form.elements[i];
5360
5361			BX.removeClass(el,"adm-calendar-inp-setted");
5362
5363			switch(el.type.toLowerCase())
5364			{
5365				case 'text':
5366				case 'textarea':
5367					el.value = '';
5368					break;
5369
5370				case 'select-one':
5371					el.selectedIndex = 0;
5372					if(el.onchange)
5373						el.onchange();
5374					break;
5375
5376				case 'select-multiple':
5377					var j;
5378					var l = el.options.length;
5379					for(j=0; j<l; j++)
5380						el.options[j].selected = false;
5381					break;
5382
5383				default:
5384					break;
5385			}
5386		}
5387	};
5388
5389	this.GetRowByElement = function(element)
5390	{
5391		return jsUtils.FindParentObject(element, "tr");
5392	};
5393
5394	this.SetFilterFields = function(fields)
5395	{
5396		this.ClearParameters();
5397		var checkboxesIdx = [];
5398		var elName;
5399
5400		for(var i=0, n = this.form.elements.length; i<n; i++)
5401		{
5402			var el = this.form.elements[i];
5403
5404			if(BX.hasClass(el,"adm-calendar-inp-setted"))
5405				continue;
5406
5407			if(el.type == 'select-multiple')
5408			{
5409				elName = el.name.substr(0, el.name.length - 2);
5410			}
5411			else if(el.type == 'checkbox' && el.name.search(/[\[\]]/))
5412			{
5413				elName = el.name.substr(0, el.name.length - 2);
5414
5415				if(checkboxesIdx[elName] == undefined)
5416					checkboxesIdx[elName] = 0;
5417				else
5418					checkboxesIdx[elName]++;
5419
5420				elName +="_cbxIdx_"+checkboxesIdx[elName];
5421
5422				el.checked = false;
5423			}
5424			else
5425			{
5426				elName = el.name;
5427			}
5428
5429			if(!fields[elName])
5430			{
5431				var row = this.GetRowByElement(el);
5432
5433				if(!row)
5434					continue;
5435
5436				if(this.IsAllRowElementsHidden(row.id, fields))
5437					this.ToggleFilterRow(row.id, false, false, true);
5438
5439				continue;
5440			}
5441
5442			switch(el.type.toLowerCase())
5443			{
5444				case 'select-one':
5445					el.value = fields[elName]["value"];
5446
5447					if(el.value == "")
5448						el.selectedIndex = 0;
5449
5450					break;
5451
5452				case 'text':
5453				case 'textarea':
5454					el.value = fields[elName]["value"];
5455					break;
5456
5457				case 'radio':
5458				case 'checkbox':
5459					el.checked = (el.value == fields[elName]["value"]);
5460					break;
5461
5462				case 'select-multiple':
5463					var bWasSelected = false;
5464					el.value = null;
5465					if (el.options.length > 0)
5466					{
5467						el.options[0].selected = false;
5468						for(var j=0, l=el.options.length; j<l; j++)
5469						{
5470							for(var option in fields[elName]['value'])
5471							{
5472								if(el.options[j].value == fields[elName]['value'][option])
5473								{
5474									el.options[j].selected = true;
5475									bWasSelected = true;
5476								}
5477							}
5478						}
5479
5480						if(!bWasSelected && el.options[0].value == '')
5481							el.options[0].selected = true;
5482					}
5483					break;
5484
5485				default:
5486					break;
5487			}
5488
5489			BX.fireEvent(el, 'change');
5490
5491			if(fields[elName]['hidden'] ==  'true' && this.IsAllRowElementsHidden(this.GetRowByElement(el).id, fields))
5492				this.ToggleFilterRow(this.GetRowByElement(el).id, false, false, true);
5493			else
5494				this.ToggleFilterRow(this.GetRowByElement(el).id, true, false);
5495		}
5496
5497		if(this.CountVisibleRows() < 1)
5498			this.ToggleFilterRow(this.filter_id+'_row_'+this.aRows[0], true, false);
5499
5500		//this.SaveRowsOption();
5501	};
5502
5503	this.IsFormElementHidden = function (el)
5504	{
5505
5506		if(BX.browser.IsOpera())
5507			return !el.offsetWidth && !el.offsetHeight && !el.clientHeight && !el.clientWidth;
5508
5509		return !el.offsetWidth && !el.offsetHeight;
5510	};
5511
5512	this.IsAllRowElementsHidden = function (rowId, fields)
5513	{
5514		var bAllHidden = true;
5515
5516		for(var i=0, n = this.form.elements.length; i<n; i++)
5517		{
5518			var el = this.form.elements[i];
5519
5520			if(!fields[el.name])
5521				continue;
5522
5523			if(jsUtils.FindParentObject(el, "tr").id != rowId)
5524				continue;
5525
5526			if(fields[el.name]['hidden'] == 'false')
5527			{
5528					bAllHidden = false;
5529					break;
5530			}
5531		}
5532
5533		return bAllHidden;
5534	};
5535
5536	this.GetFilterFields = function(bSetVisibilityByRow)
5537	{
5538		var fields = {};
5539		var checkboxesIdx = [];
5540		var elName;
5541
5542		for(var i=0, n = this.form.elements.length; i<n; i++)
5543		{
5544			var el = this.form.elements[i];
5545
5546			if(!el.name)
5547				continue;
5548
5549			if(el.type == 'select-multiple')
5550			{
5551				elName = el.name.substr(0, el.name.length - 2);
5552			}
5553			else if(el.type == 'checkbox' && el.name.search(/[\[\]]/))
5554			{
5555				elName = el.name.substr(0, el.name.length - 2);
5556
5557				if(checkboxesIdx[elName] == undefined)
5558					checkboxesIdx[elName] = 0;
5559				else
5560					checkboxesIdx[elName]++;
5561
5562				elName += "_cbxIdx_"+checkboxesIdx[elName];
5563			}
5564			else
5565			{
5566				elName = el.name;
5567			}
5568
5569			switch(el.type.toLowerCase())
5570			{
5571				case 'select-one':
5572				case 'text':
5573				case 'textarea':
5574					fields[elName] = { value: el.value };
5575					break;
5576
5577				case 'radio':
5578					if(el.checked)
5579						fields[elName] = { value: el.value };
5580					break;
5581
5582				case 'checkbox':
5583					if(el.checked)
5584						fields[elName] = { value: el.value };
5585					else
5586						fields[elName] = { value: false };
5587					break;
5588
5589				case 'select-multiple':
5590					fields[elName] = {value:[]};
5591
5592					for(var j=0, l = el.options.length; j<l; j++)
5593						if(el.options[j].selected && el.options[j].value)
5594							fields[elName]['value']['sel_'+el.options[j].value] = el.options[j].value;
5595
5596					//fields[elName]['hidden'] = this.IsFormElementHidden(el);
5597
5598					break;
5599				default:
5600					break;
5601			}
5602
5603			if(!fields[elName])
5604				continue;
5605
5606			if(bSetVisibilityByRow)
5607				fields[elName]['hidden'] = (this.GetRowByElement(el).style.display == 'none' ? 'true' : 'false');
5608			else
5609				fields[elName]['hidden'] = this.IsFormElementHidden(el) ? 'true' : 'false';
5610
5611		}
5612
5613		return fields;
5614	};
5615
5616	this.IsFilterFill = function()
5617	{
5618		if(!this.form)
5619			return;
5620
5621		var i;
5622		var n = this.form.elements.length;
5623		for(i=0; i<n; i++)
5624		{
5625			var el = this.form.elements[i];
5626			if(el.disabled)
5627				continue;
5628			var tr = this.GetRowByElement(el);
5629			if(tr && tr.style && tr.style.display == 'none')
5630				continue;
5631
5632			switch(el.type.toLowerCase())
5633			{
5634				case 'select-one':
5635					if(el.options.length > 0)
5636						if(el.options[0].value.length != 0 && (el.options[0].value.toUpperCase() != 'NOT_REF' || el.value.toUpperCase() == 'NOT_REF'))
5637							break;
5638				case 'text':
5639				case 'textarea':
5640					if(el.value.length > 0)
5641						return true;
5642					break;
5643				case 'checkbox':
5644					if(el.checked)
5645						return true;
5646					break;
5647				case 'select-multiple':
5648					var j;
5649					var l = el.options.length;
5650					for(j=0; j<l; j++)
5651						if(el.options[j].selected && el.options[j].value != '')
5652							return true;
5653					break;
5654				default:
5655					break;
5656			}
5657		}
5658		return false;
5659	};
5660
5661	this.GetParameters = function()
5662	{
5663		if(!this.form)
5664			return;
5665
5666		var i, s = "";
5667		var n = this.form.elements.length;
5668		for(i=0; i<n; i++)
5669		{
5670			var el = this.form.elements[i];
5671
5672			if(el.disabled)
5673				continue;
5674
5675			var tr = this.GetRowByElement(el);
5676
5677			if(tr && tr.style && tr.style.display == 'none')
5678				continue;
5679
5680			if(el.className == "adm-select adm-calendar-period" && el.value != '')
5681			{
5682				var selPParent = el.parentNode.parentNode;
5683				var inputFrom = BX.findChild(selPParent, {'className':'adm-input adm-calendar-from'},true);
5684				var inputTo = BX.findChild(selPParent, {'className':'adm-input adm-calendar-to'},true);
5685
5686				var dateFrom = false;
5687				var dateTo = false;
5688				var today = new Date();
5689				var year = today.getFullYear();
5690				var month = today.getMonth();
5691				var day = today.getDate();
5692				var dayW = today.getDay();
5693
5694				if (dayW == 0)
5695					dayW = 7;
5696
5697				switch(el.value)
5698				{
5699					case 'exact':
5700						dateFrom = BX.parseDate(inputFrom.value, false, phpVars.FORMAT_DATE, phpVars.FORMAT_DATETIME);
5701						dateTo = dateFrom;
5702						break;
5703
5704					case 'after':
5705						inputTo.value = "";
5706						break;
5707
5708					case 'before':
5709						inputFrom.value = "";
5710						break;
5711
5712					default:
5713						break;
5714				}
5715
5716				var format = window[inputFrom.name+"_bTime"] ? BX.message('FORMAT_DATETIME') : BX.message('FORMAT_DATE');
5717
5718				if(dateFrom)
5719					inputFrom.value = BX.formatDate(dateFrom, format);
5720
5721				if(dateTo)
5722					inputTo.value = BX.formatDate(dateTo, format);
5723			}
5724
5725			var val = "";
5726			switch(el.type.toLowerCase())
5727			{
5728				case 'select-one':
5729				case 'text':
5730				case 'textarea':
5731				case 'hidden':
5732					val = el.value;
5733					break;
5734				case 'radio':
5735				case 'checkbox':
5736					if(el.checked)
5737						val = el.value;
5738					break;
5739				case 'select-multiple':
5740					var j;
5741					var l = el.options.length;
5742					for(j=0; j<l; j++)
5743						if(el.options[j].selected)
5744							s += '&' + el.name + '=' + encodeURIComponent(el.options[j].value);
5745					break;
5746				default:
5747					break;
5748			}
5749			if(val != "")
5750				s += '&' + el.name + '=' + encodeURIComponent(val);
5751
5752		}
5753
5754		if(this.oOptions[this.curID]["SORT_FIELD"] && typeof this.oOptions[this.curID]["SORT_FIELD"] == 'object')
5755		{
5756			for(var idx in this.oOptions[this.curID]["SORT_FIELD"])
5757			{
5758				s += '&by=' +encodeURIComponent(idx)+'&order='+this.oOptions[this.curID]["SORT_FIELD"][idx];
5759				break;
5760			}
5761		}
5762		return s;
5763	};
5764
5765	this.CheckActive = function()
5766	{
5767		var i;
5768		var n = this.form.elements.length;
5769		for(i=0; i<n; i++)
5770		{
5771			var el = form.elements[i];
5772			if(el.disabled)
5773				continue;
5774			var tr = this.GetRowByElement(el);
5775			if(tr && tr.style && tr.style.display == 'none')
5776				continue;
5777
5778			switch(el.type.toLowerCase())
5779			{
5780				case 'select-one':
5781					if(el.options[0].value.length != 0 && (el.options[0].value.toUpperCase() != 'NOT_REF' || el.value.toUpperCase() == 'NOT_REF'))
5782						break;
5783				case 'text':
5784				case 'textarea':
5785					if(el.value.length > 0)
5786						return true;
5787					break;
5788				case 'checkbox':
5789					if(el.checked)
5790						return true;
5791					break;
5792				case 'select-multiple':
5793					var j;
5794					var l = el.options.length;
5795					for(j=0; j<l; j++)
5796						if(el.options[j].selected && el.options[j].value != '')
5797							return true;
5798					break;
5799				default:
5800					break;
5801			}
5802		}
5803		return false;
5804	};
5805
5806	this.DisplayNonEmptyRows = function()
5807	{
5808		if(!this.form)
5809			return;
5810
5811		var i;
5812		var n = this.form.elements.length;
5813		for(i=0; i<n; i++)
5814		{
5815			var el = this.form.elements[i];
5816			if(el.disabled)
5817				continue;
5818
5819			var bVisible = false;
5820			switch(el.type.toLowerCase())
5821			{
5822				case 'select-one':
5823					if(el.value.length>0 && (el.options[0].value.length == 0 || (el.options[0].value != el.value)))
5824						bVisible = true;
5825					break;
5826
5827				case 'text':
5828				case 'textarea':
5829					if(el.value.length>0)
5830						bVisible = true;
5831					break;
5832
5833				case 'checkbox':
5834					if(el.checked)
5835						bVisible = true;
5836					break;
5837
5838				case 'select-multiple':
5839					var j;
5840					var l = el.options.length;
5841					for(j=0; j<l; j++)
5842						if(el.options[j].selected && el.options[j].value != '')
5843						{
5844							bVisible = true;
5845							break;
5846						}
5847					break;
5848
5849				default:
5850					break;
5851			}
5852			if(bVisible)
5853			{
5854				var tr = jsUtils.FindParentObject(el, 'tr');
5855				if(tr.id)
5856					this.ToggleFilterRow(tr.id, true, false);
5857			}
5858		}
5859	};
5860
5861	this.CountVisibleRows = function()
5862	{
5863		var counter = 0;
5864		for (var i=this.aRows.length-1; i>=0; i--)
5865			if(this.oVisRows[this.aRows[i]])
5866				counter++;
5867
5868		return counter;
5869	};
5870
5871	this.SetBottomStyle = function()
5872	{
5873		var bottomSeparator = BX(this.filter_id+"_bottom_separator");
5874		var contentDiv = BX(this.filter_id+"_content");
5875
5876		if(this.CountVisibleRows() > 1)
5877		{
5878			contentDiv.className = "adm-filter-content";
5879			bottomSeparator.style.display = "block";
5880		}
5881		else
5882		{
5883			contentDiv.className = "adm-filter-content adm-filter-content-first";
5884			bottomSeparator.style.display = "none";
5885		}
5886	};
5887
5888	this.ToggleButtonShow = function(rowId)
5889	{
5890		var row = BX(rowId);
5891
5892		if(!row)
5893			return;
5894
5895		row.cells[2].children[0].style.display = 'block';
5896	};
5897
5898	this.ToggleButtonHide = function(rowId)
5899	{
5900		var row = BX(rowId);
5901
5902		if(!row)
5903			return;
5904
5905		row.cells[2].children[0].style.display = 'none';
5906	};
5907
5908	this.ToggleButtonsShowAll = function()
5909	{
5910		for(var key in this.aRows)
5911			this.ToggleButtonShow(this.filter_id+'_row_'+this.aRows[key]);
5912	};
5913
5914	this.ToggleButtonsHideAll = function()
5915	{
5916		for(var key in this.aRows)
5917			this.ToggleButtonHide(this.filter_id+'_row_'+this.aRows[key]);
5918	};
5919
5920	this.ToggleFilterRow = function(rowId, on, bSave, skipControl)
5921	{
5922		var row = BX(rowId),
5923			delimiter = BX(rowId+'_delim'),
5924			ret = 0;
5925
5926
5927		if(!row || !delimiter)
5928			return ret;
5929
5930		var short_id = rowId.substr((this.filter_id+'_row_').length);
5931
5932		if(on != true && on != false)
5933			on = (row.style.display == 'none');
5934
5935		if(on == true)
5936		{
5937			try{
5938				row.style.display = 'table-row';
5939				delimiter.style.display = 'table-row';
5940			}
5941			catch(e){
5942				row.style.display = 'block';
5943				delimiter.style.display = 'block';
5944			}
5945			this.oVisRows[short_id] = true;
5946
5947			ret = row.offsetHeight + delimiter.offsetHeight;
5948		}
5949		else
5950		{
5951			if( skipControl || this.CountVisibleRows() > 1)
5952			{
5953				ret = -(row.offsetHeight + delimiter.offsetHeight);
5954
5955				row.style.display = 'none';
5956				delimiter.style.display = 'none';
5957				this.oVisRows[short_id] = false;
5958
5959			}
5960		}
5961
5962		this.SetBottomStyle();
5963
5964		var countVR = this.CountVisibleRows();
5965
5966		if(countVR == 1)
5967			this.ToggleButtonsHideAll();
5968
5969		if(countVR == 2)
5970			this.ToggleButtonsShowAll();
5971
5972
5973		if(bSave != false)
5974			this.SaveRowsOption();
5975
5976		return ret;
5977	};
5978
5979	this.DeleteFilterRow = function(rowId)
5980	{
5981		this.StartAnimation();
5982		this.ToggleFilterRow(rowId);
5983		this.EndAnimation();
5984	};
5985
5986	this.StartAnimation = function()
5987	{
5988		if(this.state.folded)
5989			return;
5990
5991		if (this.easing)
5992			this.easing.stop();
5993
5994		this.startContentHeight = this.tableWrap.offsetHeight;
5995		this.tableWrap.style.height = this.startContentHeight + "px";
5996		this.tableWrap.style.overflowY = "hidden";
5997	};
5998
5999	this.EndAnimation = function()
6000	{
6001		if(this.state.folded)
6002			return;
6003
6004		var newHeight = this.table.offsetHeight;
6005		if (newHeight == 0)
6006		{
6007			this.tableWrap.style.height = "auto";
6008			this.tableWrap.style.overflowY = "visible";
6009			return;
6010		}
6011
6012
6013		this.easing = new BX.easing({
6014			duration : 500,
6015			start : { height: this.startContentHeight, opacity : 0 },
6016			finish : { height: newHeight, opacity : 100 },
6017			transition : BX.easing.makeEaseOut(BX.easing.transitions.quart),
6018
6019			step : BX.proxy(function(state){
6020				this.tableWrap.style.height = state.height + "px";
6021
6022				BX.onCustomEvent(this, 'onAdminFilterToggleRow');
6023			}, this),
6024
6025			complete : BX.proxy(function(){
6026				this.tableWrap.style.height = "auto";
6027				this.tableWrap.style.overflowY = "visible";
6028				this.easing = null;
6029
6030				BX.onCustomEvent(this, 'onAdminFilterToggleRow');
6031			}, this)
6032
6033		});
6034		this.easing.animate();
6035
6036	};
6037
6038	this.SaveFilterParams = function()
6039	{
6040		var sParams = "filter_id:"+this.filter_id+",";
6041
6042		for(var name in this.params)
6043			sParams += name+":"+this.params[name]+",";
6044
6045		// Remove the last comma from the final string
6046		sParams = sParams.substr(0,sParams.length-1);
6047
6048		document.cookie = BX.message('COOKIE_PREFIX')+"_ADM_FLT_PARAMS=" + sParams;
6049	};
6050
6051	this.SaveRowsOption = function()
6052	{
6053		if(this.curID != "0")
6054		{
6055			this.Save(false);
6056			return true;
6057		}
6058
6059
6060		var sRows = '';
6061
6062		for(var key in this.oVisRows)
6063			if(this.oVisRows[key] == true)
6064				sRows += (sRows != ''? ',':'')+key;
6065
6066		jsUserOptions.SaveOption('filter', this.filter_id, 'rows', sRows);
6067	};
6068
6069	this.SaveOpenTab = function(id)
6070	{
6071		var data = {
6072			'id': id,
6073			'filter_id': this.filter_id,
6074			'action': 'open_tab_save',
6075			'sessid': phpVars.bitrix_sessid,
6076			'lang': BX.message("LANGUAGE_ID")
6077		};
6078
6079		BX.ajax.post('/bitrix/admin/filter_act.php', data);
6080	};
6081
6082	this.SaveFilteredId = function(id)
6083	{
6084		var data = {
6085			'id': id,
6086			'filter_id': this.filter_id,
6087			'action': 'filtered_tab_save',
6088			'sessid': phpVars.bitrix_sessid,
6089			'lang': BX.message("LANGUAGE_ID")
6090		};
6091
6092		BX.ajax.post('/bitrix/admin/filter_act.php', data);
6093	};
6094
6095	this.ToggleAllFilterRows = function(on)
6096	{
6097		var tbl = document.getElementById(this.filter_id);
6098		if(!tbl)
6099			return;
6100
6101		this.StartAnimation();
6102
6103		var n = tbl.rows.length;
6104		for(var i=n-1; i>=0; i--)
6105		{
6106			var row = tbl.rows[i];
6107			if(row.id && row.cells[0].className != 'delimiter')
6108				this.ToggleFilterRow(row.id, on, false);
6109		}
6110
6111		if(on)
6112			this.ToggleButtonsShowAll();
6113		else
6114			this.ToggleButtonsHideAll();
6115
6116		this.SaveRowsOption();
6117
6118		this.EndAnimation();
6119	};
6120
6121	this.SaveMenuShow = function(el)
6122	{
6123		var menuItems =[];
6124
6125		if(this.curID != "0")
6126			menuItems.push({TEXT: BX.message('JSADM_FLT_SAVE'), ONCLICK: filter_id+".Save();"});
6127
6128		menuItems.push({TEXT: BX.message('JSADM_FLT_SAVE_AS'), ONCLICK: 'setTimeout(function(){'+filter_id+'.SaveAs();},10);'});
6129
6130		if(this.curID != "0") //&& this.oOptions[this.curID].EDITABLE)
6131			menuItems.push({TEXT: BX.message('JSADM_FLT_DELETE'), ONCLICK: filter_id+".Delete();"});
6132
6133		if (!el.OPENER)
6134			BX.adminShowMenu(el,menuItems);
6135		else
6136			el.OPENER.SetMenu(menuItems);
6137
6138	};
6139
6140	this.SettMenuItemClick = function(rowId, objItem)
6141	{
6142
6143		var menu = BX.WindowManager.Get();
6144		if (menu && BX.type.isFunction(menu.toggleArrow))
6145			menu.toggleArrow(false);
6146
6147		this.StartAnimation();
6148
6149		var scrollOffset = this.ToggleFilterRow(rowId);
6150
6151		this.EndAnimation();
6152	};
6153
6154	this.SettMenuShow = function(el)
6155	{
6156		var tbl = BX(this.filter_id);
6157
6158		if(!tbl)
6159			return;
6160
6161		var menuItems =[];
6162		var diff = this.missingRows;
6163		var itemsIdx = this.aRows.length-1;
6164
6165		for(var i = tbl.rows.length-1; i >=0; i--)
6166		{
6167			var row = tbl.rows[i];
6168
6169			if(!row.id || row.cells[0].className == 'delimiter')
6170				continue;
6171
6172			var text ="";
6173			if(itemsIdx-diff >= 0)
6174				text = this.popupItems[this.aRows[itemsIdx]];
6175			else
6176				text = (row.cells[0].textContent || row.cells[0].innerText).replace(/:$/,"");
6177
6178			menuItems.unshift({
6179				TEXT: text,
6180				ONCLICK: filter_id+".SettMenuItemClick('"+row.id+"',this);",
6181				CLOSE_ON_CLICK: false,
6182				ADJUST_ON_CLICK: false,
6183				CHECKED: (row.style.display != 'none')
6184			});
6185
6186			itemsIdx--;
6187		}
6188
6189		menuItems.push({SEPARATOR: true});
6190		menuItems.push({
6191			TEXT: BX.message('JSADM_FLT_SHOW_ALL'),
6192			ONCLICK: filter_id+".ToggleAllFilterRows(true);"
6193		});
6194
6195		menuItems.push({
6196			TEXT: BX.message('JSADM_FLT_HIDE_ALL'),
6197			ONCLICK: filter_id+".ToggleAllFilterRows(false);"
6198		});
6199
6200		if (!el.OPENER)
6201			BX.adminShowMenu(el,menuItems);
6202		else
6203		{
6204			el.OPENER.SetMenu(menuItems);
6205			var menu = el.OPENER.GetMenu();
6206			if (menu)
6207				menu.toggleArrow(true);
6208		}
6209	}
6210};
6211
6212//********** admin filter tab object begin****************
6213BX.admFltTab = function(id, fltObj)
6214{
6215	this.id = id;
6216	this.filter = fltObj;
6217};
6218
6219BX.admFltTab.prototype = {
6220
6221	GetObjId: function()
6222	{
6223		return "adm-filter-tab-"+this.filter.filter_id+"-"+this.id;
6224	},
6225
6226	GetObj: function()
6227	{
6228		var tabObjId = this.GetObjId();
6229		return BX(tabObjId);
6230	},
6231
6232	SetActive: function()
6233	{
6234		BX.addClass(this.GetObj(),"adm-filter-tab-active");
6235	},
6236
6237	UnSetActive: function()
6238	{
6239		BX.removeClass(this.GetObj(),"adm-filter-tab-active");
6240	},
6241
6242	SetFiltered: function(init)
6243	{
6244		if(this.filter.params.filteredId !== false && this.filter.oOptions[this.filter.params.filteredId] !==undefined && !init)
6245			this.filter.oOptions[this.filter.params.filteredId]["tab"].UnSetFiltered();
6246
6247		BX.addClass(this.GetObj(),"adm-current-filter-tab");
6248
6249		if(!init)
6250		{
6251			//this.filter.SaveFilteredId(this.id);
6252			this.filter.params.filteredId = this.id;
6253			this.filter.SaveFilterParams();
6254
6255		}
6256
6257		this.filter.params.filteredId = this.id;
6258		this.filter.SetFilteredBG(this.id);
6259	},
6260
6261	UnSetFiltered: function()
6262	{
6263		this.filter.params.filteredId = false;
6264		BX.removeClass(this.GetObj(),"adm-current-filter-tab");
6265		this.filter.SetFilteredBG(false);
6266		//this.filter.SaveFilteredId(false);
6267		this.filter.SaveFilterParams();
6268	},
6269
6270	_RegisterDD: function(tabId, url, name)
6271	{
6272		if(!BX.adminMenu || !BX.adminMenu.registerItem)
6273		{
6274			return;
6275		}
6276
6277		if(!url)
6278		{
6279			return;
6280		}
6281
6282		var registerUrl = BX.util.remove_url_param(url, ["adm_filter_applied","adm_filter_preset"]);
6283		registerUrl += "&adm_filter_applied" + '=' + BX.util.urlencode(this.id
6283);
6284		BX.adminMenu.registerItem(tabId, {URL: registerUrl, TITLE: true});
6285	},
6286
6287	AddHtml: function(url, name)
6288	{
6289		var _this = this;
6290		var tabsBlock = BX("filter-tabs-"+this.filter.filter_id);
6291		var newTab = document.createElement('span');
6292		newTab.className = "adm-filter-tab";
6293		newTab.id = this.GetObjId();
6294		newTab.onclick = function(){ _this.filter.SetActiveTab(this); _this.filter.ApplyFilter(_this.id); };
6295		newTab.innerHTML = BX.util.htmlspecialchars(name);
6296		tabsBlock.insertBefore(newTab, BX("adm-filter-add-tab-"+this.filter.filter_id));
6297		this._RegisterDD(newTab.id, url, name);
6298		this.filter.SetActiveTab(newTab);
6299		this.filter.ApplyFilter(this.id);
6300	},
6301
6302	DeleteHtml: function()
6303	{
6304		var delTab = this.GetObj();
6305
6306		if(delTab)
6307			delTab.parentNode.removeChild(delTab);
6308	},
6309
6310	ShowWheel: function()
6311	{
6312		var timeout = 250;
6313
6314		setTimeout(
6315			BX.proxy(
6316				function() {
6317					if (this.GetObj())
6318						BX.addClass(this.GetObj(), "adm-filter-tab-loading");
6319				},
6320			this),
6321		timeout);
6322	}
6323};
6324
6325//********** admin filter wrap object begin****************
6326BX.admFltWrap = {
6327
6328	Inner: function(el, elClass, wrapType, wrapClass)
6329	{
6330		var wrap = document.createElement(wrapType);
6331
6332		if(wrapClass)
6333			wrap.className = wrapClass;
6334
6335		if(elClass)
6336			el.className = elClass;
6337
6338		var elChildren = BX.findChildren(el);
6339
6340		for(var i in elChildren)
6341			wrap.appendChild(elChildren[i]);
6342
6343		el.appendChild(wrap);
6344
6345		return wrap;
6346	},
6347
6348	Element: function(el, elClass, wrapType, wrapClass)
6349	{
6350		var wrap = document.createElement(wrapType);
6351
6352		if(wrapClass)
6353			wrap.className = wrapClass;
6354
6355		if(elClass)
6356			el.className = elClass;
6357
6358		el.parentNode.insertBefore(wrap, el);
6359		wrap.appendChild(el);
6360
6361		return wrap;
6362	},
6363
6364	Input:  function(el)
6365	{
6366		var wrap = false;
6367		switch (el.type)
6368		{
6369			case "select-one":
6370				if(el.size && el.size > 1)
6371					wrap = BX.admFltWrap.Element(el,"adm-select-multiple","span","adm-select-wrap-multiple");
6372				else
6373					wrap = BX.admFltWrap.Element(el,"adm-select","span","adm-select-wrap");
6374				break;
6375
6376			case "select-multiple":
6377				wrap = BX.admFltWrap.Element(el,"adm-select-multiple","span","adm-select-wrap-multiple");
6378				break;
6379
6380			case "text": // input
6381				wrap = BX.admFltWrap.Element(el,"adm-input","div","adm-input-wrap");
6382				break;
6383
6384			case "checkbox":
6385
6386				var label = BX.findChild(el.parentNode, {tagName: "label", htmlFor: el.id});
6387				if(!label)
6388				{
6389					var wraplabel = BX.admFltWrap.Element(el, "", "label", "");
6390
6391					if(label && label.childNodes[0])
6392					{
6393						wraplabel.appendChild(label.childNodes[0]);
6394						label.parentNode.removeChild(label);
6395					}
6396				}
6397
6398				BX.adminFormTools.modifyCheckbox(el);
6399				break;
6400
6401			case 'submit':
6402			case 'button':
6403			case 'reset':
6404			case "hidden":
6405			default:
6406				break;
6407		}
6408
6409		return wrap;
6410	},
6411
6412	Cell: function(cell)
6413	{
6414		var newCell = cell.cloneNode(true);
6415		var wrap;
6416		newCell.innerHTML = "";
6417
6418		while(cell.childNodes.length)
6419		{
6420			switch(cell.childNodes[0].nodeName.toLowerCase())
6421			{
6422				case 'small':
6423					BX.admFltWrap.Element(cell.childNodes[0], "", "span", "adm-filter-text-wrap");
6424					break;
6425
6426				case '#text':
6427
6428					cell.childNodes[0].nodeValue = jsUtils.trim(cell.childNodes[0].nodeValue);
6429
6430					if(cell.childNodes[0].nodeValue == '')
6431					{
6432						cell.removeChild(cell.childNodes[0]);
6433						continue;
6434					}
6435
6436					BX.admFltWrap.Element(cell.childNodes[0], "", "span", "adm-filter-text-wrap");
6437
6438					break;
6439
6440				case 'label':
6441
6442					if(cell.childNodes[0].className == "adm-designed-checkbox-label")
6443						break;
6444
6445
6446					var input = BX.findChild(cell.childNodes[0],{tag: "input"});
6447
6448					if(input)
6449						wrap = BX.admFltWrap.Input(input);
6450
6451					break;
6452
6453				case 'input':
6454
6455					var helpIcon = false;
6456
6457					var nextInput = BX.findNextSibling(cell.childNodes[0], {tagName: "INPUT"});
6458
6459					if(cell.childNodes[0].type == "text" && ( !nextInput || nextInput.type != "text"))
6460						helpIcon = BX.findChild(cell.childNodes[0].parentNode, {className: "adm-input-help-icon"});
6461
6462					wrap = BX.admFltWrap.Input(cell.childNodes[0]);
6463
6464					if(helpIcon)
6465					{
6466						BX.addClass (wrap, "adm-input-help-icon-wrap");
6467						wrap.appendChild(helpIcon);
6468					}
6469					break;
6470
6471				case 'select':
6472					BX.admFltWrap.Input(cell.childNodes[0]);
6473					break;
6474
6475				case 'iframe':
6476					cell.childNodes[0].style.display = 'none';
6477					break;
6478
6479				case 'span':
6480					if(cell.childNodes[0].style.display != 'none')
6481						cell.childNodes[0].style.display = 'inline-block';
6482					break;
6483
6484				default:
6485					break;
6486			}
6487
6488			newCell.appendChild(cell.childNodes[0]);
6489		}
6490
6491		return newCell;
6492	},
6493
6494	Row: function(row)
6495	{
6496		row.cells[0].className = "adm-filter-item-left";
6497		row.cells[1].className = "adm-filter-item-center";
6498		row.cells[2].className = 'adm-filter-item-right';
6499		row.cells[0].innerHTML = row.cells[0].innerHTML.replace(/<\/?[^>]+>/gi, ''); // strip_tags
6500
6501		var calendarInput = ( !!BX.findChild(row.cells[1], {'className': 'adm-input adm-input-calendar'}, true));
6502
6503		if(calendarInput)
6504		{
6505			var calendarBlock = BX.admFltWrap.Inner(row.cells[1], "","DIV","adm-calendar-block adm-filter-alignment");
6506			BX.admFltWrap.Inner(calendarBlock, "", "DIV", "adm-filter-box-sizing");
6507			return null;
6508		}
6509
6510		if (row.cells[1].children[0] && !BX.hasClass(row.cells[1].children[0], 'adm-filter-alignment'))
6511		{
6512			var boxSizing = BX.create('div', {props: {className: 'adm-filter-box-sizing'}});
6513			var alingment = BX.create('div', {props: {className: 'adm-filter-alignment'}});
6514
6515			row.cells[1].innerHTML = BX.admFltWrap.Cell(row.cells[1]).innerHTML;
6516
6517			while(row.cells[1].children.length>0)
6518				boxSizing.appendChild(row.cells[1].children[0]);
6519
6520			alingment.appendChild(boxSizing);
6521			row.cells[1].appendChild(alingment);
6522		}
6523		return row;
6524	}
6525};
6526//********** admin filter wrap object end****************
6527
6528BX.adminChain = {
6529	_addon: null,
6530
6531	addItems: function(divId)
6532	{
6533		BX.ready(function(){BX.adminChain._addItems(divId)});
6534	},
6535
6536	_addItems: function(divId)
6537	{
6538		var main_chain = BX("main_navchain");
6539		if(!main_chain)
6540			return;
6541
6542		if (!!this._addon)
6543		{
6544			this._addon.parentNode.removeChild(this._addon);
6545			this._addon = null;
6546		}
6547
6548		var div = BX(divId);
6549		if(!div)
6550			return;
6551
6552		this._addon = main_chain.appendChild(BX.create('span', {html: '<span class="adm-navchain-delimiter"></span>' + div.innerHTML}));
6553	}
6554};
6555
6556/************************* singletons construction **************************/
6557
6558BX.InitializeAdmin = function()
6559{
6560	BX.browser.addGlobalFeatures(["boxShadow", "borderRadius", "flexWrap", "boxDirection", "transition", "transform"]);
6561	BX.adminPanel = new BX.adminPanel();
6562	BX.adminMenu = new BX.adminMenu();
6563
6564	if (!!(history.pushState && BX.type.isFunction(history.pushState)))
6565	{
6566		BX.adminHistory = new BX.adminHistory();
6567	}
6568
6569	BX.ready(function() {
6570		var workarea = BX("adm-workarea");
6571		if (workarea)
6572			workarea.style.opacity = 1;
6573	});
6574};
6575
6576BX.adminPanel.modifyFormElements = BX.adminFormTools.modifyFormElements;
6577BX.adminPanel.modifyFormElement = BX.adminFormTools.modifyFormElement;
6578
6579})();

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.