Your IP : 18.118.252.85


Current Path : /var/www/www-root/data/www/www.monolith-realty.ru/bitrix/js/landing/ui/field/
Upload File :
Current File : /var/www/www-root/data/www/www.monolith-realty.ru/bitrix/js/landing/ui/field/range_field.js

;(function()
{
	"use strict";

	BX.namespace("BX.Landing.UI.Field");


	/**
	 * Implements interface for works with range field
	 *
	 * @extends {BX.Landing.UI.Field.BaseField}
	 *
	 * @param {object} data
	 * @constructor
	 */
	BX.Landing.UI.Field.Range = function(data)
	{
		this.items = BX.type.isArray(data.items) ? data.items : [];
		this.values = new BX.Landing.Collection.BaseCollection();
		this.isMultiple = typeof data.type === "string" && data.type === "multiple";
		this.inputInner = this.createInputInner();
		this.container = BX.create("div", {props: {className: "landing-ui-field-range-container"}});
		this.output = this.createOutput();
		this.sliderFrom = null;
		this.sliderTo = this.createSlider();
		this.sliderValue = this.createValue();
		this.elements = [];
		this.frame = typeof data.frame === "object" ? data.frame : null;
		this.format = typeof data.format === "function" ? data.format : (function() {});
		this.postfix = typeof data.postfix === "string" ? data.postfix : "";
		this.changeHandler = typeof data.onChange === "function" ? data.onChange : (function() {});
		this.onValueChangeHandler = data.onValueChange ? data.onValueChange : (function() {});
		this.dragStartHandler = typeof data.onDragStart === "function" ? data.onDragStart : (function() {});
		this.dragEndHandler = typeof data.onDragEnd === "function" ? data.onDragEnd : (function() {});
		var rootWindow = BX.Landing.PageObject.getRootWindow();
		this.jsDD = this.frame ? rootWindow.jsDD : window.jsDD;
		this.value = null;
		this.valueFrom = null;
		this.valueTo = null;

		BX.Landing.UI.Field.BaseField.apply(this, arguments);
		this.layout.classList.add("landing-ui-field-range");
		this.stepPercent = 100 /this.values.length;

		if ((this.content === null || this.content === undefined || this.content === ""))
		{
			if (this.isMultiple)
			{
				this.content = {
					from: this.items[0].value,
					to: this.items[this.items.length-1].value
				}
			}
			else
			{
				this.content = this.items[0].value;
				this.value = this.items[0].value;
			}
		}

		var onMouseUp = function(event) {
			this.jsDD.stopDrag(event);
		}.bind(this);

		BX.Event.bind(window, 'mouseup', onMouseUp);
		BX.Event.bind(rootWindow, 'mouseup', onMouseUp);
		BX.Event.bind(window.top, 'mouseup', onMouseUp);

		this.setValue(this.content, true);
	};


	BX.Landing.UI.Field.Range.prototype = {
		constructor: BX.Landing.UI.Field.Range,
		__proto__: BX.Landing.UI.Field.BaseField.prototype,

		init: function ()
		{
			this.input.appendChild(this.inputInner);
			this.input.appendChild(this.sliderValue);
			this.layout.appendChild(this.container);
			this.container.appendChild(this.input);

			if (!this.isMultiple)
			{
				this.container.appendChild(this.output);
			}

			if (this.isMultiple)
			{
				this.sliderFrom = this.createSlider();
				this.inputInner.appendChild(this.sliderFrom);
			}

			this.inputInner.appendChild(this.sliderTo);

			this.items.forEach(function(item, index) {
				this.values.add({
					value: item.value,
					valuePercent: this.valueToPercent(index),
					left: this.valueToLeftPercent(item.value),
					name: item.name
				});
			}, this);

			if (this.isMultiple)
			{
				this.sliderFrom.onbxdragstart = this.onDragStart.bind(this);
				this.sliderFrom.onbxdrag = this.onDrag.bind(this);
				this.sliderFrom.onbxdragstop = this.onDragEnd.bind(this);
				this.jsDD.registerObject(this.sliderFrom);
			}

			this.sliderTo.onbxdragstart = this.onDragStart.bind(this);
			this.sliderTo.onbxdrag = this.onDrag.bind(this);
			this.sliderTo.onbxdragstop = this.onDragEnd.bind(this);
			this.jsDD.registerObject(this.sliderTo);

			if (this.isMultiple)
			{
				requestAnimationFrame(function () {
					this.sliderFrom.style.transform = "translateX(-" + this.values[this.values.length-1].valuePercent + "%)";
					this.sliderFrom.style.left = this.values[this.values.length-1].valuePercent + "%";
				}.bind(this));
			}

			if (this.frame)
			{
				this.onFrameLoad();
			}
		},

		createOutput: function()
		{
			this.outputInput = BX.create("div", {props: {className: "landing-ui-field-range-output-input"}, text: "0"});
			return BX.create("div", {
				props: {className: "landing-ui-field-range-output"},
				children: [
					this.outputInput,
					BX.create("div", {
						props: {className: "landing-ui-field-range-output-arrows"},
						children: [
							BX.create("div", {
								props: {className: "landing-ui-field-range-output-arrows-up"},
								events: {
									click: this.onArrowUpClick.bind(this)
								}
							}),
							BX.create("div", {
								props: {className: "landing-ui-field-range-output-arrows-down"},
								events: {
									click: this.onArrowDownClick.bind(this)
								}
							})
						]
					})
				]
			});
		},

		onArrowUpClick: function()
		{
			var index = !!this.value ? this.values.length-1 : 0;
			var result;

			this.values.forEach(function(item, i) {
				if (item.value === this.value)
				{
					index = i;
				}
			}, this);

			result = this.values[index+1] ? this.values[index+1] : this.values[index];
			this.setValue(result.value);
		},

		onArrowDownClick: function()
		{
			var index = 0;
			var result;

			this.values.forEach(function(item, i) {
				// noinspection EqualityComparisonWithCoercionJS
				if (item.value == this.value)
				{
					index = i;
				}
			}, this);

			result = this.values[index-1] ? this.values[index-1] : this.values[index];
			this.setValue(result.value);
		},

		onFrameLoad: function ()
		{
			this.elements = [].slice.call(this.frame.document.querySelectorAll(this.selector));

			if (this.elements.length)
			{
				const element = this.elements[0];

				if (this.isMultiple)
				{
					const from = this.values.find(function(item) {
						return element.classList.contains(item.value);
					});

					const to = this.values.find(function(item) {
						return element.classList.contains(item.value) && item.value !== from;
					});

					this.setValue({
						from: !!from ? from.value : null,
						to: !!to ? to.value : null
					}, true);
				}
				else
				{
					const value = this.values.find(function(item) {
						return element.classList.contains(item.value);
					});

					this.setValue(!!value ? value.value : null, true);
				}
			}
		},

		getStartXOffset: function ()
		{
			var left = parseFloat(this.jsDD.current_node.style.left) * (this.inputInner.getBoundingClientRect().width / 100);
			return this.jsDD.current_node.getBoundingClientRect().left + window.pageXOffset - (left === left ? left : 0);
		},

		onDragStart: function ()
		{
			this.offset = this.getStartXOffset();
			this.dragStartHandler();
		},

		onDrag: function (x)
		{
			x = ((x - this.offset) / this.inputInner.getBoundingClientRect().width) * 100;
			x = x < 0 ? 0 : x > 100 ? 100 : x;
			var xx = x;

			var pip;
			var sliderLeft = parseFloat(this.jsDD.current_node.style.left);
			sliderLeft = sliderLeft === sliderLeft ? sliderLeft : 0;

			if (x > this.lastPos)
			{
				xx += (this.stepPercent / 2);
				pip = this.values.filter(function (item) {
					return xx >= item.valuePercent && item.valuePercent > sliderLeft;
				}, this);

				pip = pip[pip.length - 1];
			}
			else
			{
				xx -= (this.stepPercent / 2);
				pip = this.values.filter(function (item) {
					return xx <= item.valuePercent && item.valuePercent < sliderLeft;
				}, this);

				pip = pip[0];
			}


			if (pip)
			{
				if (this.isMultiple)
				{
					if (this.jsDD.current_node === this.sliderFrom)
					{
						this.valueFrom = pip.value;
					}

					if (this.jsDD.current_node === this.sliderTo)
					{
						this.valueTo = pip.value;
					}

					this.setValue({from: this.valueFrom, to: this.valueTo});
				}
				else
				{
					this.setValue(pip.value);
				}
			}

			this.lastPos = x;
		},

		onChange: function()
		{
			this.changeHandler(this.getValue(), this.items, this.postfix, this.property);
			this.onValueChangeHandler(this);
		},

		onDragEnd: function()
		{
			this.dragEndHandler();
		},


		getValue: function()
		{
			var result;

			if (this.isMultiple)
			{
				result = {
					from: this.toPercent < this.fromPercent ? this.valueTo : this.valueFrom,
					to: this.toPercent > this.fromPercent ? this.valueTo : this.valueFrom
				};
			}
			else
			{
				result = this.value;
			}

			return result;
		},

		setValue: function(value, preventEvent)
		{
			if (value && typeof value === "object")
			{
				var from = this.values.filter(function(item) {
					// noinspection EqualityComparisonWithCoercionJS
					return item.value == value.from;
				});

				var to = this.values.filter(function(item) {
					// noinspection EqualityComparisonWithCoercionJS
					return item.value == value.to;
				});

				from = from.length ? from[0] : this.values[0];
				to = to.length ? to[0] : this.values[this.values.length-1];

				if (from)
				{
					requestAnimationFrame(function () {
						this.sliderFrom.style.transform = "translateX(-" + from.valuePercent + "%)";
						this.sliderFrom.style.left = from.valuePercent + "%";
					}.bind(this));
					this.valueFrom = from.value;
					this.fromPercent = from.valuePercent;
				}

				if (to)
				{
					requestAnimationFrame(function () {
						this.sliderTo.style.transform = "translateX(-" + to.valuePercent + "%)";
						this.sliderTo.style.left = to.valuePercent + "%";
					}.bind(this));
					this.valueTo = to.value;
					this.toPercent = to.valuePercent;
				}

				this.updateValuePosition(from.valuePercent, to.valuePercent);
			}
			else if (value)
			{
				var result = this.values.filter(function(item) {
					// noinspection EqualityComparisonWithCoercionJS
					return item.value == value;
				});

				result = result.length ? result[0] : null;

				if (result)
				{
					requestAnimationFrame(function () {
						this.sliderTo.style.transform = "translateX(-" + result.valuePercent + "%)";
						this.sliderTo.style.left = result.valuePercent + "%";
					}.bind(this));

					this.value = value;
					this.updateValuePosition(result.valuePercent);
				}
			}

			if (!preventEvent)
			{
				this.onChange();
			}
		},


		updateValuePosition: function(from, to)
		{
			if (typeof from !== "number" && typeof to !== "number")
			{
				from = 0;
				to = 100;
			}

			if (typeof from === "number" && typeof to !== "number")
			{
				to = from;
				from = 0;
			}

			requestAnimationFrame(function() {
				this.sliderValue.style.left = Math.min(from, to) + "%";
				this.sliderValue.style.right = (100 - Math.max(from, to)) + "%";
			}.bind(this));

			var result = this.values.filter(function(item) {
				// noinspection EqualityComparisonWithCoercionJS
				return item.valuePercent == to;
			});

			result = result.length ? result[0] : null;

			this.outputInput.innerText = !!result ? result.name : 0;
			BX.Dom.attr(this.outputInput, 'title', BX.Text.encode(this.outputInput.innerText));
		},


		createInputInner: function()
		{
			return BX.create("div", {props: {className: "landing-ui-field-range-input-inner"}});
		},

		createValue: function()
		{
			return BX.create("div", {props: {className: "landing-ui-field-range-value"}});
		},

		createSlider: function()
		{
			return BX.create("div", {props: {className: "landing-ui-field-range-input-slider"}});
		},

		createInput: function()
		{
			return BX.create("div", {props: {className: "landing-ui-field-input landing-ui-field-range-input"}});
		},

		/**
		 * @param value
		 * @return {number}
		 */
		valueToPercent: function(value)
		{
			return (value / (this.items.length-1)) * 100;
		},

		valueToLeftPercent: function(value)
		{
			return (value / this.inputInner.getBoundingClientRect().width) * 100;
		},

		/**
		 * Checks that value changed
		 * @return {boolean}
		 */
		isChanged: function()
		{
			if (this.isMultiple)
			{
				return JSON.stringify(this.content) !== JSON.stringify(this.getValue());
			}

			// noinspection EqualityComparisonWithCoercionJS
			return this.content != this.getValue();
		}
	};
})();