PageSourceSearch

https://inno-implant.ru/local/templates/inno-2025/js/basket.js?177746350912316

js inno-implant.ru collected 2026-09-25 20:16:56 UTC 12,316 bytes, 331 lines download raw bytes

1function CartDataAccessor() {
2	this.LoadItems = function (loadHandler) {
3		$.get("/api/basket/get/", function (data) {
4			if (loadHandler) {
5				loadHandler(data);
6			}
7		})
8			.fail(function () {
9				loadHandler(null);
10			});
11	}
12
13	this.UpdateBasket = function (items, loadHandler) {
14		$.post("/api/basket/change/", JSON.stringify({change: items}), function (data) {
15			if (loadHandler) {
16				loadHandler(data);
17			}
18
19			let open = $('.cart-block').hasClass('active') ? 1 : 0;
20			let url = "/ajax/topbasket.php";
21
22			$.post(url, {"BASKET_OPEN": open}, function(data) {
23				$(".cart-wrapper").html(data);
24			});
25		})
26			.fail(function () {
27				loadHandler(null);
28			});
29	}
30
31	this.DeletePositions = function (positionIds, loadHandler) {
32		$.post("/api/basket/delete/", JSON.stringify({delete: positionIds}), function (data) {
33			if (loadHandler) {
34				loadHandler(data);
35			}
36		})
37			.fail(function () {
38				loadHandler(null);
39			});
40	}
41
42	this.GetRecommendedProducts = function (loadHandler) {
43		$.get("/api/basket/get-recommended/", function (data) {
44			if (loadHandler) {
45				loadHandler(data);
46			}
47		})
48			.fail(function () {
49				loadHandler(null);
50			});
51	}
52}
53
54function CartManager(totalOuterSelector, cartContainerSelector, cartProductsCountSelector, dataAccessorHelper) {
55	let _this = this;
56	this._dataAccessorHelper = dataAccessorHelper;
57	this._saveItemsTimeout = 1000;
58	this._cartContainerSelector = cartContainerSelector;
59	this._cartProductsCountSelector = cartProductsCountSelector;
60	this._dataAccessor = new CartDataAccessor();
61
62	this.Init = function () {
63		_this._container = $(_this._cartContainerSelector);
64		_this._cartProductsCount = $(_this._cartProductsCountSelector);
65		_this._dataAccessor.LoadItems(_this.UploadItems);
66	}
67
68	this._timeoutID = null;
69
70	this._cartChanged = function () {
71		_this._spinner.Display();
72		_this.LockButtons();
73		if (_this.timeoutID !== null) {
74			clearTimeout(_this.timeoutID);
75		}
76		this.timeoutID = setTimeout(
77			_this.SaveNewCartParameters,
78			_this._saveItemsTimeout);
79	}
80
81	this.SaveNewCartParameters = function () {
82		let toUpdate = [];
83		for (let id in _this._itemsInfo) {
84			toUpdate.push({
85				id: id,
86				quantity: _this._itemsInfo[id].quantity,
87				checked: _this._itemsInfo[id].checked
88			});
89		}
90		_this._dataAccessor.UpdateBasket(toUpdate, _this.UploadItems);
91	}
92
93	this.UploadItems = function (response) {
94		response = _this._dataAccessorHelper.ProcessApiResponse(response);
95			
96		if(response != null) {
97			_this._itemsInfo = {};
98			let allChecked = true;
99			let allUnchecked = true;
100			if (_this.WasLoadedAnyItems(response)) {
101				for (let i = 0; i < response.basket.items.length; i++) {
102					const item = response.basket.items[i];
103					const isChecked = item.checked === false ? false : true;
104					_this._itemsInfo[item.id] = {
105						quantity: item.quantity > item.maxquantity ? item.maxquantity : item.quantity,
106						checked: isChecked
107					}
108					if (!isChecked) {
109						allChecked = false;
110					}
111					if (isChecked) {
112						allUnchecked = false;
113					}
114				}
115			}
116			_this._allChecked = allChecked === true ? true : (allUnchecked === true ? false : null);
117			_this.RenderItems(response);
118		}
119	}
120
121	this.RenderItems = function (response) {
122		if(response != null) {
123			if (!_this.WasLoadedAnyItems(response)) {
124				_this._container.html("<div class=\"cart-empty\">В корзине нет товаров</div>");
125			} else {
126				let html = "<div class=\"order-body\">";
127
128				html += "<div class=\"order-content\">";
129				html += "<div class=\"cart-header\">";
130				html += "<div class=\"cart-header-checkbox\"><input type=\"checkbox\" class=\"select-all\" /> Выбрать</div><div class=\"cart-header-delete\"><button class=\"delete-selected\">Удалить выбранное</button></div>";
131				html += "</div>";
132				html += "<hr />";
133
134				for (let i = 0; i < response.basket.items.length; i++) {
135					let item = response.basket.items[i];
136
137					html += "<div class=\"product-item\">";
138					html += "<div class=\"product-item-image-description-column\">";
139					html += "<div class=\"product-item-checkbox-column\">";
140					html += "<input productId=\"" + item.id + "\" type=\"checkbox\" class=\"select-item\" " + (_this._itemsInfo[item.id].checked ? "checked" : "") + " />";
141					html += "</div>";
142					html += "<div class=\"product-item-image-column\">";
143					html += "<img src=\"" + item.image + "\" />";
144					html += "</div>";
145					html += "<div class=\"product-item-info-column\">";
146					if (!item.available) {
147						html += "<div class=\"product-item-not-available\">Временно нет в наличии</div>";
148					}
149					html += "<div class=\"product-item-article\">
149Артикул: " + item.article + "</div>";
150					html += "<div class=\"product-item-name\"><a href=\"" + item.pageUrl + "\" target='_blank'>" + item.name + "</a></div>";
151					html += "<div class=\"product-item-sku\">" + item.skutext + "</div>";
152					html += "</div>";
153					html += "</div>";
154
155					html += "<div class=\"product-item-count-price-column\">";
156
157					html += "<div class=\"product-item-count-column\">";
158					html += "<input productId=\"" + item.id + "\" class=\"item-count-input\" min-value=\"1\" max-value=\"" + item.maxquantity + "\" value=\"" + _this._itemsInfo[item.id].quantity + "\" />";
159					html += "</div>";
160
161					if (item.price) {
162						let actualPrice = item.price.discount ? item.price.discount : item.price.base;
163						html += "<div class=\"product-item-actual-price\">" + FormatNumberWithSeparator(actualPrice) + " " + item.price.currency + "</div>";
164						if (item.price.discount) {
165							html += "<div class=\"product-item-discount\"><span class=\"product-item-discount-amount\">" + FormatNumberWithSeparator(item.price.base) + " " + item.price.currency + "</span>";
166							if (item.price.percent) {
167								html += "<span class=\"product-item-discount-percent\">-" + item.price.percent + "%</span>";
168							}
169							html += "</div>";
170						}
171					}
172					html += "</div>";
173
174					html += "</div>";
175					html += "<hr />";
176				}
177
178				html += "</div>";
179
180				html += "<div class=\"order-total\">";
181				html += "<div class=\"total-header\">Ваш заказ</div>";
182				html += "<div class=\"total-price-count\">";
183				html += "<div class=\"total-count\">" + GetOrderWordFormByCount(response.basket.itemsCount);
184				html += "</div>";
185				html += "<div class=\"total-price\">";
186
187				let actualPrice = response.basket.total.discount ? response.basket.total.discount : response.basket.total.base;
188				if (response.basket.total.discount) {
189					html += "<span class=\"total-discount\">" + FormatNumberWithSeparator(response.basket.total.base) + " " + response.basket.total.currency + "</span>";
190				}
191				html += "<span class=\"total-actual-price\">" + FormatNumberWithSeparator(actualPrice) + " " + response.basket.total.currency + "</span>";
192
193				html += "</div>";
194				html += "</div>";
195				html += "<hr />";
196				html += "<div class=\"total-buttons\">";
197				html += "<button onclick=\"window.location = '/personal/cart/order/'\" class=\"btn btn-primary btn-primary-rectangle send-order\"></button>";
198				html += "<a class=\"btn btn-primary btn-primary-rectangle btn-primary-white continue-shopping\" href=\"/catalog/\"></a>";
199				html += "</div>";
200				html += "</div>";
201
202				html += "</div>";
203				_this._container.html(html);
204				_this._cartProductsCount.html("(" + GetOrderWordFormByCount(response.basket.totalCount) + ")");
205
206				_this.SendOrderButton = _this._container.find('.send-order');
207				_this.DeleteSelectedButton = _this._container.find('.delete-selected');
208
209				_this._container.find('.item-count-input').customNumberInput({
210					onChange: function (ev) {
211						_this._itemsInfo[ev.element.sourceElement.attr("productId")].quantity = ev.value;
212						_this._cartChanged();
213					}
214				});
215				_this._selectAllCheckbox = _this._container.find('.select-all').customCheckBox({
216					onChange: function (ev) {
217						_this.SetChecked(null, ev.value);
218					}
219				})[0];
220				_this._selectAllCheckbox.SetValue(_this._allChecked);
221				_this._selectItemsCheckboxes = _this._container.find('.select-item').customCheckBox({
222					onChange: function (ev) {
223						_this.SetChecked([ev.element.sourceElement.attr("productId")], ev.value);
224					}
225				});
226				_this._container.find('.delete-selected').click(function () {
227					let positionIds = [];
228					for (let id in _this._itemsInfo) {
229						if (_this._itemsInfo[id].checked === true) {
230							positionIds.push(id);
231						}
232					}
233					if (positionIds.length > 0) {
234						_this.LockButtons();
235						_this._dataAccessor.DeletePositions(positionIds, _this.UploadItems);
236					}
237				});
238
239
240				_this._spinner = _this._container.find(totalOuterSelector).spinner();
241				_this._spinner = _this._spinner.length === 1 ? _this._spinner[0] : null;
242			}
243		}
244	}
245
246	this.SetChecked = function (ids, value) {
247		let allChecked = true;
248		let allUnchecked = true;
249		for (let i = 0; i < _this._selectItemsCheckboxes.length; i++) {
250			const e = $(_this._selectItemsCheckboxes[i].sourceElement);
251			const productId = e.attr("productId");
252			if (ids === null || ids.indexOf(productId) >= 0) {
253				_this._itemsInfo[productId].checked = value;
254				_this._selectItemsCheckboxes[i].SetValue(value);
255			}
256			if (!_this._itemsInfo[productId].checked) {
257				allChecked = false;
258			}
259			if (_this._itemsInfo[productId].checked) {
260				allUnchecked = false;
261			}
262		}
263
264		const allValue = allChecked === true ? true : (allUnchecked === true ? false : null);
265		_this._selectAllCheckbox.SetValue(allValue);
266		_this._cartChanged();
267	}
268
269	this.WasLoadedAnyItems = function (response) {
270		return response && response.basket && response.basket.items && response.basket.items.length > 0;
271	}
272
273	this.LockButtons = function () {
274		_this.SendOrderButton.prop("disabled", true);
275		_this.DeleteSelectedButton.prop("disabled", true);
276	}
277}
278
279function RecommendedProductsManager(selector, dataAccessorHelper) {
280	let _this = this;
281	this._dataAccessor = new CartDataAccessor();
282	
283	this._dataAccessorHelper = dataAccessorHelper;
284	this._selector = selector;
285
286	this.Init = function () {
287		_this._container = $(_this._selector);
288		_this._dataAccessor.GetRecommendedProducts(_this.RenderItems);
289	}
290
291	this.RenderItems = function (response) {
292		response = _this._dataAccessorHelper.ProcessApiResponse(response);
293		if (response != null && _this.WasLoadedAnyItems(response)) {
294			let html = "<h3 class=\"header\">Рекомендуем</h3>";
295			html += "<div class=\"recommended-products-outer\">";
296			html += "<div class=\"recommended-products-inner\">";
297			for (let i = 0; i < response.length; i++) {
298				const item = response[i];
299				html += "<div class=\"recommended-product\">";
300				html += "<div class=\"recommended-product-image\">";
301				html += "<img src=\"" + item.image + "\">";
302				html += "</div>";
303				html += "<div class=\"product-item-article\">Артикул: " + item.article + "</div>";
304				html += "<div class=\"product-item-name\"><a href=\"" + item.link + "\">" + item.name + "</a></div>";
305				html += "<div class=\"product-item-sku\">" + item.skutext + "</div>";
306
307				if (item.price) {
308					let actualPrice = item.price.discount ? item.price.discount : item.price.base;
309					html += "<div class=\"product-item-actual-price\">" + FormatNumberWithSeparator(actualPrice) + " " + item.price.currency + "</div>";
310					if (item.price.discount) {
311						html += "<div class=\"product-item-discount\"><span class=\"product-item-discount-amount\">" + FormatNumberWithSeparator(item.price.base) + " " + item.price.currency + "</span>";
312						if (item.price.percent) {
313							html += "<span class=\"product-item-discount-percent\">-" + item.price.percent + "%</span>";
314						}
315						html += "</div>";
316					}
317				}
318				html += "<a href=\"" + item.link + "\" class=\"btn btn-primary btn-primary-rectangle add-to-cart\"></a>";
319
320				html += "</div>";
321			}
322			html += "</div>";
323			html += "</div>";
324			_this._container.html(html);
325		}
326	}
327
328	this.WasLoadedAnyItems = function (response) {
329		return response && response.length > 0;
330	}
331}

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.