PageSourceSearch

https://voenchast.ru/bitrix/components/bitrix/voting.uf/templates/.default/script.js

js voenchast.ru collected 2026-10-09 22:41:51 UTC 16,943 bytes, 594 lines download raw bytes

1;(function(window) {
2	var BX = window.BX;
3	if (BX["Vote"])
4		return;
5	var actionUrl = (window.BXMobileApp ? BX.message("SITE_DIR") + "mobile/?mobile_action=vote" : "/bitrix/tools/vote/uf.php");
6
7	BX.Vote = (function() {
8		var d = function(node, params) {
9			this.node = node;
10			this.form = BX.findChild(this.node, {tagName : "FORM"}, true);
11			this.id = params["id"];
12			this.voteId = params["voteId"];
13			this.params = params;
14			var n, answer, i;
15			// Error Node
16			this.errorNode = BX.findChild(this.node, {attribute : {"data-bx-vote-role" : "error"}}, true);
17			// Buttons
18			for (var ii in this.buttons)
19			{
20				if (this.buttons.hasOwnProperty(ii))
21				{
22					n = BX.findChild(this.node, {attribute : {"data-bx-vote-button" : ii}}, true);
23					if (n && BX.type.isFunction(this[ii]))
24					{
25						this[ii] = BX.delegate(this[ii], this);
26						this.buttons[ii] = n;
27						BX.bind(n, "click", this[ii]);
28					}
29				}
30			}
31			// Answers
32			n = BX.findChildren(this.node, {tagName : "TR"}, true);
33			while (n && (answer = n.pop()) && answer && answer.hasAttribute("data-bx-vote-answer"))
34			{
35				i = BX.findChild(answer, {"tagName" : "A", attribute : {"data-bx-vote-result" : "counter"}}, true);
36				if (i)
37				{
38					if (window.BXMobileApp)
39					{
40						BX.bind(answer, "click", BX.proxy(this.checkMobileUsers, this));
41					}
42					else
43					{
44
45						BX.bind(i, "click", BX.proxy(this.checkUsers, this));
46						BX.adjust(i, {attrs : {"data-bx-vote-answer" : answer.getAttribute("data-bx-vote-answer")}});
47					}
48				}
49			}
50
51			this.onPullEvent = BX.delegate(function(command, params)
52			{
53				if (command == 'voting' && !!params && params["VOTE_ID"] == this.voteId && BX(this.node))
54				{
55					this.adjustResults(params);
56				}
57			}, this);
58
59			if (window.BXMobileApp)
60			{
61				app.onCustomEvent('onPullExtendWatch', {id: 'VOTE_' + this.voteId});
62				BX.addCustomEvent('onPull-vote', this.onPullEvent);
63			}
64			else if (BX["PULL"])
65			{
66				BX.PULL.extendWatch('VOTE_' + this.voteId);
67				BX.addCustomEvent("onPullEvent-vote", this.onPullEvent);
68			}
69		};
70		d.prototype = {
71			buttons: {
72				showVoteForm: null,
73				showResults: null,
74				actVoting: null,
75				stopOrResume: null,
76				exportXls: null
77			},
78			params: {
79			},
80			url: actionUrl,
81			showVoteForm: function(e) {
82				if (this.node.getAttribute("data-bx-vote-lamp") == "green")
83				{
84					var f = BX.proxy(function(data) {
85						if (data && data.data && data.data.event)
86							this.adjustBallot(data.data.attach, data.data.event);
87						this.node.setAttribute("data-bx-vote-form", "shown");
88					}, this),
89						ff = BX.proxy(function(error) {
90						this.node.setAttribute("data-bx-vote-form", "shown");
91					}, this);
92					this.send({ action: "getBallot" }, e.target, f, ff);
93				}
94				BX.eventCancelBubble(e);
95				return BX.PreventDefault(e);
96			},
97			showResults: function(e) {
98				this.node.setAttribute("data-bx-vote-result", (this.node.getAttribute("data-bx-vote-result") == "shown" ? "hidden" : "shown"));
99				BX.eventCancelBubble(e);
100				return BX.PreventDefault(e);
101			},
102			stopOrResume: function (e) {
103				this.send({ action: this.node.getAttribute("data-bx-vote-lamp") == "red" ? "resume": "stop" }, e.target, BX.proxy(function(data) {
104					if (data["action"] == "stop")
105					{
106						this.node.setAttribute("data-bx-vote-result", "shown");
107						this.node.setAttribute("data-bx-vote-form", "hidden");
108						this.node.setAttribute("data-bx-vote-lamp", "red");
109					}
110					else
111					{
112						if (this.node.getAttribute("data-bx-vote-status") !== "voted")
113							this.node.setAttribute("data-bx-vote-form", "shown");
114
115						this.node.setAttribute("data-bx-vote-lamp", "green");
116					}
117					if (data["data"] && data["data"]["attach"])
118						this.adjustResults(data["data"]["attach"]);
119				}, this));
120				BX.eventCancelBubble(e);
121				return BX.PreventDefault(e);
122			},
123			exportXls: function (e) {
124				BX.eventCancelBubble(e);
125				top.location.href = BX.util.add_url_param(this.url, {action: "exportXls", attachId: this.id, sessid: BX.bitrix_sessid()});
126				return BX.PreventDefault(e);
127			},
128			actVoting: function(e) {
129				var data = BX.ajax.prepareForm(this.form).data;
130				data["action"] = "vote";
131				this.send(data, e.target, BX.proxy(function(data) {
132					this.node.setAttribute("data-bx-vote-form", "hidden");
133					this.node.setAttribute("data-bx-vote-result", "shown");
134					this.adjustResults(data.data.attach);
135				}, this), BX.proxy(function() {
136					this.node.setAttribute("data-bx-vote-form", "shown");
137				}, this));
138				BX.eventCancelBubble(e);
139				return BX.PreventDefault(e);
140			},
141			send: function(data, el, success, fail) {
142				BX.addClass(el, "ui-btn-clock");
143				data["sessid"] = BX.bitrix_sessid();
144				data["attachId"] = this.id;
145				BX.ajax({
146					method: 'POST',
147					url: BX.util.add_url_param(this.url, {action: data["action"], attachId: this.id}),
148					data: data,
149					dataType: 'json',
150					onsuccess: BX.proxy(function(data) {
151						BX.removeClass(el, 'ui-btn-clock');
152						if (data.status == "success")
153						{
154							this.showError(null);
155							if (BX.type.isFunction(success))
156								success.apply(this, arguments);
157						}
158						else
159						{
160							if (data.status == "error" && data["errors"])
161								this.showError(data["errors"]);
162							if (BX.type.isFunction(fail))
163								fail.apply(this, arguments);
164						}
165					}, this),
166					onfailure: BX.proxy(function(){
167						BX.removeClass(el, 'ui-btn-clock');
168						if (BX.type.isFunction(fail))
169							fail.apply(this, arguments);
170					}, this)
171				});
172			},
173			adjustBallot: function(attachment, event) {
174				var q, a, e, i, j, es, qu, an, v,
175					attach = attachment["QUESTIONS"],
176					ballot = event["ballot"],
177					extras = event["extras"];
178				for (q in attach)
179				{
180					if (attach.hasOwnProperty(q))
181					{
182						qu = attach[q];
183						e = [qu["FIELD_NAME"], qu["FIELD_NAME"] + "[]"];
184						v = (ballot[q] || {});
185						while(i = e.shift())
186						{
187							if (this.form.elements[i])
188							{
189								es = BX(this.form.elements[i]) ? [this.form.elements[i]] : this.form.elements[i];
190								for (i = 0; i < es.length;i++)
191								{
192									if (v[es[i].value])
193									{
194										es[i].checked = "checked";
195									}
196									else
197									{
198										delete es[i].checked;
199									}
200								}
201							}
202						}
203
204						for (a in attach[q]["ANSWERS"])
205						{
206							if (attach[q]["ANSWERS"].hasOwnProperty(a))
207							{
208								an = attach[q]["ANSWERS"][a];
209								if (an["FIELD_TYPE"] >= 4)
210								{
211									if (this.form.elements[an["MESSAGE_FIELD_NAME"]])
212										this.form.elements[an["MESSAGE_FIELD_NAME"]].value = (ballot[q] && ballot[q][a] && ballot[q][a]["MESSAGE"] ? ballot[q][a]["MESSAGE"] : "");
213									else
214										this.form.elements[an["FIELD_NAME"]].value = (ballot[q] && ballot[q][a] && ballot[q][a]["MESSAGE"] ? ballot[q][a]["MESSAGE"] : "");
215								}
216							}
217						}
218					}
219				}
220				for (i in extras)
221				{
222					if (extras.hasOwnProperty(i) &&
223						(q = (BX(this.form.elements[String(attachment["FIELD_NAME"]).replace("#ENTITY_ID#", i)]))))
224					{
225						if (q.value == extras[i])
226							q.checked = true;
227						else
228							delete q.checked;
229					}
230				}
231			},
232			adjustResults: function(attachment) {
233				var questions = attachment["QUESTIONS"];
234				BX.onCustomEvent(this.node, 'OnBeforeChangeData');
235				var question, answer, i, q, per, n;
236				for (q in questions)
237				{
238					if (questions.hasOwnProperty(q))
239					{
240						question = BX.findChild(this.node, {"attr": {"id": "question" + q}}, true);
241						if (question)
242						{
243							for (i in questions[q]["ANSWERS"])
244							{
245								if (questions[q]["ANSWERS"].hasOwnProperty(i))
246								{
247									answer = BX.findChild(question, {"attr": {"data-bx-vote-answer": i}}, true);
248									if (!!answer)
249									{
250										per = parseInt(questions[q]["ANSWERS"][i]["PERCENT"]);
251										per = (isNaN(per) ? 0 : per);
252										n = BX.findChild(answer, {attribute: {"data-bx-vote-result" : "counter"}}, true);
253										BX.adjust(n, {"html" : questions[q]["ANSWERS"][i]["COUNTER"] + ""});
254										delete n["VOTED_USER_OBJ"];
255										BX.adjust(BX.findChild(answer, {"tagName" : "SPAN", attribute : {"data-bx-vote-result" : "percent"}}, true),
256											{"html" : per + '%'});
257										BX.adjust(BX.findChild(answer, {"tagName" : "DIV", attribute : {"data-bx-vote-result" : "bar"}}, true),
258											{"style" : {"width" : per + '%'}});
259									}
260								}
261							}
262						}
263					}
264				}
265				n = BX.findChild(this.node, {"tagName" : "DIV", attribute : {"data-bx-vote-result" : "counter"}}, true);
266				BX.adjust(n, {"html" : attachment["COUNTER"] + ""});
267				BX.onCustomEvent(this.controller, 'OnAfterChangeData');
268			},
269			checkUsers : function(event)
270			{
271				var node = event ? BX(event.currentTarget) : null;
272				if (node.hasAttribute("data-bx-vote-answer"))
273				{
274					if (!node['VOTED_USER_OBJ'])
275					{
276						node.VOTED_USER_OBJ = new BVotedUser(
277							node.getAttribute("data-bx-vote-answer"),
278							node,
279							{
280								nameTemplate : this.params["nameTemplate"],
281								urlTemplate : this.params["urlTemplate"],
282								attachId : this.id
283							}
284						);
285					}
286					node.VOTED_USER_OBJ.click();
287				}
288			},
289			checkMobileUsers : function(e) {
290				if (this.node && this.node.getAttribute("data-bx-vote-form") !== "shown")
291				{
292					var node = BX.proxy_context,
293						i = BX.findChild(node, {"tagName" : "A", attribute : {"data-bx-vote-result" : "counter"}}, true);
294
295					if (i && parseInt(i.innerHTML) > 0)
296					{
297						BX.PreventDefault(e);
298						app.openBXTable({
299							url: BX.util.add_url_param(this.url, {action : "getMobileVoted", attachId : this.id, answerId : node.getAttribute("data-bx-vote-answer"), sessid : BX.bitrix_sessid()}),
300							TABLE_SETTINGS : {
301								markmode : false,
302								cache: false
303							}
304						});
305						return false;
306					}
307				}
308				return true;
309			},
310			showError : function(errors) {
311				var textError = "";
312				if (BX.type.isArray(errors))
313				{
314					var t = [];
315					for (var i = 0; i < errors.length; i++)
316					{
317						t.push(errors[i]["message"])
318					}
319					t = t.join("<br />");
320					textError = (t === "" ? "Unknown error" : t);
321					this.errorNode.innerHTML = textError;
322					this.node.setAttribute("data-bx-vote-error", "shown");
323				}
324				else
325				{
326					this.errorNode.innerHTML = "";
327					this.node.setAttribute("data-bx-vote-error", "hidden");
328				}
329			}
330	};
331		return d;
332	})();
333
334	var BVotedUser = (function()
335	{
336		var d = function(answerId, target, params)
337		{
338			this.id = ['vote', answerId, new Date().getTime()].join('-');
339			this.answerId = answerId;
340			this.node = target;
341			this.status = 'ready';
342			this.iNumPage = 0;
343
344			this.urlTemplate = params["urlTemplate"];
345			this.nameTemplate = params["nameTemplate"];
346			this.attachId = params["attachId"];
347			this.data = [];
348			this.queue = [];
349			this.popup = null;
350			this.popupScrollCheck = this.popupScrollCheck.bind(this);
351		};
352
353		d.prototype = {
354			url: actionUrl,
355			click: function()
356			{
357				var votersCount = parseInt(this.node.innerHTML);
358				if (votersCount > 0)
359				{
360					this.showPopup()
361						.then(() => {
362							if (this.data.length > 0)
363							{
364								this.buildVoters(this.data);
365							}
366						})
367					;
368				}
369			},
370
371			buildVoters: function(items)
372			{
373				var popupContainer = this.popup ? this.popup.getPopupContainer() : null;
374				if (popupContainer === null)
375				{
376					return;
377				}
378
379				var container = popupContainer.querySelector('.bx-ilike-popup');
380				popupContainer.querySelector('.bx-ilike-wrap-block').removeAttribute('style');
381				var changed = false;
382				items.forEach((voter) => {
383					var voterId = BX.util.htmlspecialchars(voter['ID']);
384					var voterName = BX.util.htmlspecialchars(voter['FULL_NAME']);
385					var voterPhoto = BX.type.isNotEmptyString(voter['PHOTO_SRC']) ?
386						encodeURI(BX.util.htmlspecialchars(voter['PHOTO_SRC'])) : null;
387					var voterType = BX.type.isNotEmptyString(voter['TYPE']) ?
388						BX.util.htmlspecialchars(voter['TYPE']) : null;
389
390					var answerId = ["a", this.answerId,  "u", voterId].join('');
391					if (container.querySelector('a#' + answerId) === null)
392					{
393						var html = [
394							'<span class="bx-ilike-popup-avatar-new">',
395								'<img src="', (voterPhoto ?? '/bitrix/images/main/blank.gif'),
396									'" class="bx-ilike-popup-avatar-img', (voterPhoto ? '' : ' bx-ilike-popup-avatar-img-default'),
397								'" />',
398								'<span class="bx-ilike-popup-avatar-status-icon"></span>',
399							'</span>',
400							'<span class="bx-ilike-popup-name-new">', voterName, '</span>'
401						].join('');
402
403						container.appendChild(
404							BX.create(voter['ID'] !== "HIDDEN" && this.urlTemplate ? "A" : "SPAN", {
405								attrs: {id: answerId},
406								props: {
407									href: this.urlTemplate.replace(/#(USER_ID|ID)#/i, voterId),
408									target: "_blank",
409									className: "bx-ilike-popup-img" + (voterType ? " bx-ilike-popup-img-" + voterType : "")
410								},
411								html: html,
412							})
413						);
414					}
415					changed = true;
416				});
417
418				if (changed)
419				{
420					this.popup.adjustPosition({forceBindPosition: true});
421					this.popupScrollCheck({currentTarget: container});
422				}
423			},
424
425			makeError: function(errors)
426			{
427				var contentContainer = this.popup ? this.popup.getPopupContainer() : null;
428				if (contentContainer === null)
429				{
430					return;
431				}
432
433				var text = (errors || [{message: BX.message("VOTE_ERROR_DEFAULT")}]).map((item) => {
434					return item.message;
435				}).join('');
436				contentContainer.innerHTML = '<div class="bx-vote-popup-error-block">
436' + text + '</div>';
437				this.popup.adjustPosition({forceBindPosition: true});
438			},
439
440			showPopup: function()
441			{
442				return new Promise((resolve) => {
443					var popup = this.getPopup();
444					popup.show();
445					popup.setAngle({position:'bottom'});
446					popup.adjustPosition({forceBindPosition: true});
447					resolve(popup);
448				})
449			},
450
451			getPopup: function()
452			{
453				if (this.popup)
454				{
455					return this.popup;
456				}
457
458				this.popup = new BX.PopupWindow('bx-vote-popup-cont-' + this.id, this.node, {
459					lightShadow: true,
460					offsetTop: -2,
461					offsetLeft: 3,
462					autoHide: true,
463					closeByEsc: true,
464					cacheable: false,
465					bindOptions: {position: "top"},
466					content: [
467						'<span class="bx-ilike-wrap-block" style="display: none;">' +
468							'<span class="bx-ilike-popup"><span class="bx-ilike-bottom_scroll"></span></span>' +
469						'</span>',
470						'<span class="bx-ilike-wait"></span>'
471					].join(''),
472					events: {
473						onFirstShow: () => {
474							this.send();
475							BX.bind(
476								this.popup.contentContainer.querySelector('.bx-ilike-popup'),
477								'scroll' ,
478								this.popupScrollCheck
479							)
480						},
481						onClose: () => {
482							this.popup = null;
483						}
484					}
485				});
486				return this.popup;
487			},
488
489			popupScrollCheck: function()
490			{
491				var container = this.popup ? this.popup.contentContainer : null;
492				if (container === null)
493				{
494					return;
495				}
496
497				var res = container.querySelector('.bx-ilike-popup');
498				if (
499					(res.scrollTop > (res.scrollHeight - res.offsetHeight) / 1.5)
500					||
501					container.offsetHeight > res.offsetHeight
502				)
503				{
504					this.send();
505				}
506			},
507
508			send: function()
509			{
510				if (this.status !== 'ready')
511				{
512					if (this.status === 'busy')
513					{
514						this.queue.push(this.send.bind(this));
515					}
516					else if (this.status === 'done')
517					{
518						this.finalize();
519					}
520					return;
521				}
522
523				this.status = 'busy';
524
525				BX.ajax({
526					url: BX.util.add_url_param(this.url, {action: "getVoted", attachId: this.attachId, answerId: this.answerId}),
527					method: 'POST',
528					dataType: 'json',
529					data: {
530						iNumPage: (++this.iNumPage),
531						nameTemplate: this.nameTemplate,
532						sessid: BX.bitrix_sessid()
533					},
534					onsuccess: function(data)
535					{
536						if (data && data.status === "success")
537						{
538							data = data.data;
539
540							this.buildVoters(data.items);
541							this.data = this.data.concat(data.items);
542
543							if (data["statusPage"] === "done" || data.items.length <= 0)
544							{
545								this.status = 'done';
546								this.finalize();
547							}
548							else
549							{
550								this.status = 'ready';
551								var f = this.queue.shift();
552								if (f)
553								{
554									f.call(this);
555								}
556							}
557						}
558						else
559						{
560							this.status = 'error';
561							this.makeError(data.errors);
562							this.finalize();
563						}
564					}.bind(this),
565					onfailure: function()
566					{
567						this.status = 'error';
568						this.makeError();
569						this.finalize();
570					}.bind(this)
571				});
572			},
573
574			finalize: function()
575			{
576				this.queue = [];
577				var popupContainer = this.popup ? this.popup.getPopupContainer() : null;
578				if (popupContainer === null)
579				{
580					return;
581				}
582
583				popupContainer.querySelector('.bx-ilike-wait').style.display = "none";
584
585				BX.unbind(
586					popupContainer.querySelector('.bx-ilike-popup'),
587					'scroll' ,
588					this.popupScrollCheck
589				);
590			}
591		};
592		return d;
593	})();
594})(window);

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.