PageSourceSearch

https://kupitesplit.ru/templates/seozhdanov/resource/js/rs.cart.js

js kupitesplit.ru collected 2026-10-04 03:36:13 UTC 25,421 bytes, 575 lines download raw bytes

1/**
2 * Инициализирует функцию добавления товаров в корзину, отображение общего числа товаров в корзине
3 * Инициализируется, если на экране присутствует блок "Корзина". (элемент #cart)
4 */
5$.cart = function( method ) {
6    var defaults = {
7            cartActiveClass: 'active',
8            fixedLine: '.rs-cart-line',
9            fixedLineActiveClass: 'open',
10            amountTextField: '.rs-num',
11            closeDlg: '.rs-close-dlg',
12            popupCartId:'rs-popup-cart',
13            checkoutButton: '#checkout',
14            checkoutButtonActiveClass: 'active',
15            cartTotalPrice: '.cost .value',
16            cartTotalItems: '.rs-cart-items-count',
17            cartPriceBlock: false,
18            productWrapper: '.rs-product-item',
19            update: '.rs-recalc',
20            inLoadingClass: 'inloading',
21            saveScroll: '.rs-save-scroll',
22            popupCartContainer: '.rs-popup-cart',
23
24            addToCart: '.rs-to-cart',
25            noShowCart: false,
26            noShowCartClass: 'rs-no-show-cart',
27            applyCoupon: '.rs-apply-coupon',
28            cartBlock: '#rs-cart-items',
29            cartForm: '#rs-cart-form',
30            cartItem: '.rs-cart-item',
31            amountWraper: '.rs-amount', //Оборачивающий контейнер
32            amountField: '.rs-field-amount',
33
34            showCart: '.rs-show-cart',
35            checkout: '.rs-submit',
36            clearCart: '.rs-clear-cart',
37            offerField: '.rs-offer',
38            cartItemInc: '.rs-inc',
39            cartItemDec: '.rs-dec',
40            cartItemRemove: '.rs-remove',
41            removeCoupon: '.rs-lines-container .rs-remove',
42            context: '[data-id]',
43            offerFormName: 'offer',
44            multiOffersName: 'multioffers[items]',    //атрибут name для многомерных компл.
45            multiofferFormName: '[multioffers][',     //атрибут name многомерной комплектации
46            multiofferHidden: '[name^="hidden_offers"]',      //атрибут name у спрятанных полей со сведения о компл.
47            amountFormName: 'amount',
48            alreadyInCartClass: 'added',
49            alreadyInCartClassTimeout:5,
50            alreadyInCartBlock: false,
51            alreadyInCartBlockTimeout:5,
52            concomitantCheckboxName: 'concomitant[',
53            concomitantField: '.rs-field-concomitant',
54            concomitantAmountClass: 'rs-concomitant', //Класс на вводе количества сопутствующих товаров
55            noMobileDetected: false,
56
57            toggleOneClickCart: '.rs-toggle-one-click-cart', //Класс кнопки для оформления заказа по телефону
58            continueButton: '.rs-continue'
59        },
60        $this = $('#rs-cart'),
61        hasCart = true;
62
63    if (!$this.length) {
64        $this = $('body');
65        hasCart = false;
66    }
67
68    var data = $this.data('cart');
69    if (!data) { //Инициализация
70        data = { options: defaults };
71        $this.data('cart', data);
72    }
73
74    //public
75    var methods = {
76        init: function(initoptions) {
77            data.options = $.extend(data.options, initoptions);
78
79            $('body').on('click.cart', data.options.addToCart, addToCart);
80            $(data.options.showCart).click(function() {
81                var href = $(this).data('href') ? $(this).data('href') : $(this).attr('href');
82                return methods.add(href);
83            });
84            $(data.options.checkoutButton).click(function() {
85                if (!$(this).hasClass(data.options.checkoutButtonActiveClass)) return false;
86            });
87            initCart(); //Вызываем на случай, если находимся на странице с корзиной
88        },
89
90        /**
91         * Добавляет товар в корзину
92         *
93         * @param url - ссылка на добавление товара в корзин
93у
94         * @param offer - номер комплектации 0,1,2...
95         * @param multioffers - массив многомерных комплектаций
96         * @param concomitants - массив сопутствующих товаров
97         * @param amount - количество товаров, которое необходимо добавить
98         * @param noShowCartDialog - не показывать корзину пользователя
99         */
100        add: function(url, offer, multioffers, concomitants, amount, noShowCartDialog) {
101
102            //if ($.detectMedia && ($.detectMedia('mobile') || $.detectMedia('portrait')) ) return true; //Не открываем окна в мобильной версии
103
104            var params = {};
105            if (offer) params.offer = offer;
106            if (amount) params.amount = amount;
107            if (multioffers) params = $.extend(params, multioffers); // Многомерных комплектаций
108            if (concomitants) params = $.extend(params, concomitants);  // Сопутствующие товары
109
110            let target = $(this);
111            target.trigger('product.addBefore', {
112                url:url,
113                offer:offer,
114                multioffers:multioffers,
115                amount:amount,
116                noShowCartDialog:noShowCartDialog
117            });
118
119            if (!noShowCartDialog) {
120                methods.showCart(url, params);
121            } else {
122                $.post(url, params, function(response) {
123                    try {
124                        //Обновляем сведения в основном окне, если действие происходит во всплывающем
125                        window.opener.jQuery.cart('updateCartBlock', response);
126                    } catch (e) {
127                        $.cart('updateCartBlock', response);
128                    } finally {
129                        target.trigger('product.add', {
130                            url:url,
131                            offer:offer,
132                            multioffers:multioffers,
133                            amount:amount,
134                            noShowCartDialog:noShowCartDialog
135                        });
136                    }
137                }, 'json');
138            }
139
140            return false;
141        },
142
143        updateCartBlock: function(serverData) {
144            if (serverData) {
145                $(data.options.cartTotalItems, $this).text(serverData.cart.items_count);
146                $(data.options.cartTotalPrice, $this).text(serverData.cart.total_price);
147                $(data.options.cartPriceBlock).toggle(parseInt(serverData.cart.total_price)>0);
148                $(data.options.checkoutButton).toggleClass(data.options.checkoutButtonActiveClass, serverData.cart.can_checkout && parseInt(serverData.cart.items_count)>0 );
149                $this.toggleClass(data.options.cartActiveClass, parseInt(serverData.cart.items_count)>0);
150            }
151        },
152
153        /**
154         * Обновляет корзину
155         */
156        refresh: function(url, callback) {
157            var params = $(data.options.cartForm).serializeArray();
158            if (!url) url = $(data.options.cartForm).attr('action');
159            showLoading();//Показ загрузки
160            $("input, select", data.cartBlock).prop('disabled', true); //Закроем на время ввод, пока грузится информация
161            $.ajax({
162                url: url,
163                data: params,
164                type: 'POST',
165                dataType: 'json',
166                success: function(response) {
167                    if (response.redirect) {
168                        location.href = response.redirect;
169                    }
170
171                    var scrollElement = $(data.options.saveScroll, data.cartBlock),
172                        saveScroll = scrollElement.scrollTop();
173
174                    data.cartBlock.replaceWith(response.html);
175                    initCart(response);
176                    $(data.options.saveScroll, data.cartBlock).scrollTop(saveScroll);
177                    if (callback) callback();
178                    $('body').trigger('new-content');
179                }
180            });
181        },
182
183        showCart: function(url, params) {
184            if ($.detectMedia('mobile')) {
185                location.href=url;
186            } else {
187                params.floatCart = 1;
188                $.ajax({
189                    url: url,
190                    data: params,
191                    dataType: 'json',
192                    success: function (response) {
193                        $('#' + data.options.popupCartId).remove();
194                        $('<div id="' + data.options.popupCartId + '" />').append(response.html).appendTo(data.options.popupCartContainer);
195
196                        $(data.options.fixedLine).addClass(data.options.fixedLineActiveClass);
197                        initCart(response);
198                    }
199                });
200            }
201        }
202    };
203
204    //private
205    var addToCart = function() {
206            var _this = this;
207            $(this).addClass(data.options.alreadyInCartClass);
208            if (!$(this).data('storedText') && $(this).data('addText')) {
209                $(this).data('storedText', $(this).html());
210                $(this).html($(this).data('addText'));
211            }
212
213            var reset = function() {
214                $(_this).removeClass(data.options.alreadyInCartClass);
215                if ($(_this).data('storedText')) {
216                    $(_this).html($(_this).data('storedText'));
217                    $(_this).data('storedText', null);
218                }
219            };
220
221            if (data.options.alreadyInCartClassTimeout) {
222                setTimeout(reset, data.options.alreadyInCartClassTimeout * 1000);
223            }
224            //Отображает всплывающий блок возле корзин
224ы
225            if (data.options.alreadyInCartBlock) {
226                var $block = $(data.options.alreadyInCartBlock);
227                clearTimeout($block.data('timer'));
228                var closeBlock = function(e) {
229                    if (e && $(e.target).is(data.options.addToCart)) return;
230                    $block.fadeOut();
231                };
232
233                $block.fadeIn().click(function(e) {
234                    e.stopPropagation();
235                });
236                $('body').one('click', closeBlock);
237
238                $block.data('timer', setTimeout(closeBlock, data.options.alreadyInCartClassTimeout * 1000));
239            }
240
241            var context = $(this).closest(data.options.context);
242            if ($('[name="'+data.options.offerFormName+'"]:checked', context).length) {
243                var offer = $('[name="'+data.options.offerFormName+'"]:checked', context).val();
244            } else {
245                var offer = $('[name="'+data.options.offerFormName+'"]', context).val();
246            }
247            var amount = $('[name="'+data.options.amountFormName+'"]', context).val();
248
249            //Многомерные комплектациями
250            if ($('[name^="multioffers["]',context).length){
251                var multioffers = {};
252                $('[name^="multioffers["]',context).each(function(i){
253                    if (!$(this).is(':radio') || $(this).is(':checked')) {
254                        pid              = $(this).attr('name');
255                        multioffers[pid] = $(this).val();
256                    }
257                });
258            }
259
260            //Сопутствующие товары
261            if ($('[name^="'+data.options.concomitantCheckboxName+'"]:checked', context).length){
262                var concomitants = {};
263                $('[name^="'+data.options.concomitantCheckboxName+'"]:checked',context).each(function(i){
264                    var cname = 'concomitant[' + i + ']';
265                    concomitants[cname] = $(this).val();
266                });
267            }
268
269            var noShowCart = $(this).hasClass(data.options.noShowCartClass) || data.options.noShowCart;
270            var url = $(this).data('url') ? $(this).data('url') : $(this).attr('href');
271
272            var amountValue = amount ? amount : 1;
273            var offerValue = (offer) ? offer : 0;
274            var multioffersValues = (multioffers) ? multioffers : false;
275            var concomitantValues = (concomitants) ? concomitants : false;
276
277            //Не открываем окна в мобильной версии
278
279            if ($.detectMedia && ($.detectMedia('mobile') || $.detectMedia('portrait'))) {
280                var params = {
281                    amount:amountValue,
282                    offer:offerValue,
283                };
284
285                //Добавим многомерные комплектации к запросу
286                if (multioffersValues) {
287                    $.extend(params, multioffersValues);
288                }
289                //Добавим сопутствующие товары к запросу
290                if (concomitantValues) {
291                    $.extend(params, concomitantValues);
292                }
293
294                location.href = url + (url.indexOf('?') == -1 ? '?' : '&') + $.param(params);
295                return false;
296            }
297
298            closeDlg();
299            return methods['add'].call(this, url, offerValue, multioffersValues, concomitantValues, amount, noShowCart);
300        },
301
302        /**
303         * Инициализация страницы корзины и навешивание событий на действия в ней
304         *
305         * @param serverData - данные от сервера
306         */
307        initCart = function(serverData) {
308            data.cartBlock = $(data.options.cartBlock);
309
310            if (data.cartBlock.length) {
311                data.cartBlock
312                    .on('click', data.options.cartItemInc, incProduct)
313                    .on('click', data.options.cartItemDec, decProduct)
314                    .on('blur', data.options.amountField, function() {
315                        var val = (+$(this).val());
316                        if (val < $(this).attr('step')) $(this).val($(this).attr('step')).keyup();
317                    })
318                    .on('focus', data.options.amountField, function(e, noSelect) {
319                        if (!noSelect) {
320                            this.select();
321                        }
322                    })
323                    .on('keyup', data.options.amountField, updateAmount)
324                    .on('change', data.options.concomitantField, updateAmount)
325                    .on('change', data.options.offerField, function() {
326                        methods.refresh();
327                    })
328                    .on('change', '[name*="'+data.options.multiofferFormName+'"]', changeMultiOffers)
329                    .on('click', data.options.continueButton, function() {
330                        history.back();
331                        return false;
332                    })
333                    .on('click', data.options.toggleOneClickCart, function() {
334                        $.oneClickCart('triggerBlockTrigger'); //Откроем блок
335                        return false;
336                    })
337                    .on('click', data.options.cartItemRemove, removeProduct)
338                    .on('click', data.options.clearCart, clearCart)
339                    .on('click', data.options.applyCoupon, applyCoupon)
340                    .on('click', data.options.checkout, checkout)
341                    .on('click', data.options.closeDlg, closeDlg);
342                    //.bind('click', function(e) { e.stopPropagation(); });
343
344                $(data.options.cartForm, data.cartBlock).submit(function() {
345                    clearTimeout(data.cartBlock.data('changeTimer'));
346                    methods.refresh();
347                    return false;
348                });
349
350                $(data.options.update, data.cartBlock).hide();
351            }
352
353            methods.updateCartBlock(serverData);
354        },
355        /**
356         * Смена(Выбор) многомерных комплектаций в корзине
357         *
358         */
359        changeMultiOffers = function() {
360            var context    = $(this).closest(data.options.context);    // Оборачивающий контейнер
361            var offersList = $(data.options.multiofferHidden,context); // Список скрытых полей со значениями
362
363            if (offersList.length>0){ //Если комплектции используются
364                var offer   = $('[name*="['+data.options.offerFormName+']"]',context); // Скрытое поле - текущая комплектация
365                var offers_info = [];
366                //Соберём информацию о том, что выбрано для товара
367                var selected = $('[name*="'+data.options.multiofferFormName+'"]',context);
368
369                //Соберём информацию о комплектациях для одного товара
370                offersList.each(function(i){
371                    offers_info[i]          = {};
372                    offers_info[i]['id']    = this;
373                    offers_info[i]['info']  = $(this).data('info');
374                    offers_info[i]['num']   = $(this).data('num');
375                    offers_info[i]['value'] = $(this).val();
376                });
377                //Соберём информацию, что изменилось
378                $(selected).each(function(i){
379                    selected[i]          = {};
380                    selected[i]['title'] = $(this).data('prop-title');
381                    selected[i]['value'] = $(this).val();
382                });
383
384                var sel_offer = false;
385                //Отметим, что мы выбрали
386                for(var j=0;j<offers_info.length;j++){
387                    var info = offers_info[j]['info']; //Группа с информацией
388
389                    var found = 0;                //Флаг, что найдены все совпадения
390                    for(var m=0;m<info.length;m++){
391                        for(var i=0;i<selected.length;i++){
392                            if ((selected[i]['title']==info[m][0])&&(selected[i]['value']==info[m][1])){
393                                found++;
394                            }
395                        }
396                        if (found==selected.length){ //Если удалось найди совпадение, то выходим
397                            sel_offer = offers_info[j];
398                            break;
399                        }
400                    }
401                }
402
403                $(context).removeClass('notAvaliable');
404
405                if (sel_offer){ //Если комплектация найдена
406                    offer.val(sel_offer.value);
407                }else{ //Если не найдена комплектация, выберем нулевую
408                    offer.val(0);
409                }
410            }
411
412            methods.refresh();
413        },
414        /**
415         * Увеличение количества одного товара в корзине
416         *
417         */
418        incProduct = function() {
419            if (!data.cartBlock.hasClass(data.options.inLoadingClass)){
420                let amountField = $(this).closest(data.options.amountWraper).find(data.options.amountField);
421                let amountTextField = $(this).closest(data.options.amountWraper).find(data.options.amountTextField);
422                let breakPoint = amountField.data('breakPoint');
423
424                let delta = 1;
425                if ($(this).data('amount-step')) {
426                    delta = $(this).data('amount-step') - 0;
427                }
428                let oldValue = (+amountField.val());
429                let newValue = oldValue + delta;
430                if (oldValue < breakPoint && newValue > breakPoint) {
431                    newValue = breakPoint;
432                }
433
434                amountField.val(newValue).keyup();
435                amountTextField.text(newValue);
436            }
437
438            return false;
439        },
440
441        /**
442         * Уменьшение количества одного товара в корзине
443         *
444         */
445        decProduct = function() {
446            if (!data.cartBlock.hasClass(data.options.inLoadingClass)){
447                let amountField = $(this).closest(data.options.amountWraper).find(data.options.amountField);
448                let amountTextField = $(this).closest(data.options.amountWraper).find(data.options.amountTextField);
449                let breakPoint = amountField.data('breakPoint');
450
451                let delta = 1;
452                if ($(this).data('amount-step')) {
453                    delta = $(this).data('amount-step') - 0;
454                }
455                let oldValue = (+amountField.val());
456                let newValue = oldValue - delta;
457                if (oldValue > breakPoint && newValue < breakPoint) {
458                    newValue = breakPoint;
459                }
460
461                if (newValue > 0) {
462                    amountField.val(newValue).keyup();
463                    amountTextField.text(newValue);
464                }
465            }
466            return false;
467        },
468
469        /**
470         * Закрытие диалогового окна
471         */
472        closeDlg = function() {
473            $('#'+data.options.popupCartId).remove();
474            $(data.options.fixedLine).removeClass(data.options.fixedLineActiveClass);
475        },
476
477        /**
478         * Удаление товара из корзины
479         *
480         */
481        removeProduct = function() {
482            if (!data.cartBlock.hasClass(data.options.inLoadingClass)){
483                var cartItem = $(this).closest(data.options.cartItem);
484                cartItem.css('opacity', 0.5).addClass('removing');
485                var other = cartItem.siblings('[data-product-id="'+cartItem.data('productId')+'"]');
486                if (!other.length) {
487                    //Удаляем пометку, что товар добавлен в корзину
488                    var context = $(data.options.productWrapper+'[data-id="'+cartItem.data('productId')+'"]')
489                    $(data.options.addToCart, context).removeClass(data.options.alreadyInCartClass);
490                }
491
492                methods.refresh( $(this).attr('href') );
493            }
494            return false;
495        },
496
497        /**
498         * Показ загрузки
499         *
500         */
501        showLoading = function() {
502            data.cartBlock.addClass(data.options.inLoadingClass);
503        },
504
505        /**
506         * Скрытие загрузки
507         *
508         */
509        hideLoading = function() {
510            data.cartBlock.removeClass(data.options.inLoadingClass);
511        },
512
513        /**
514         * Обновление количества в корзине
515         * @param e
516         */
517        updateAmount = function(e) {
518            if (e.keyCode != 13) {
519                var _this = $(this);
520
521                var n = _this.closest(data.options.cartItem).index();
522                clearTimeout(data.cartBlock.data('changeTimer'));
523                data.cartBlock.data('changeTimer', setTimeout(function() {
524                    if (_this.val() != '') {
525                        methods.refresh(null, function() {
526                            //Восстанавливаем фокус
527                            $(data.options.cartItem, data.cartBlock).eq(n).find(data.options.amountField).each(function() {
528                                $(this).trigger('focus', true);
529                                var value = $(this).val();
530                                $(this).val('').val(value);
531                            })
532                        });
533                    }
534                }, 500));
535            }
536        },
537        /**
538         * Очистить корзину
539         *
540         */
541        clearCart = function() {
542            var context = $(data.options.productWrapper+'[data-id]');
543            $(data.options.addToCart, context).removeClass(data.options.alreadyInCartClass);
544
545            return refreshByHref.call(this);
546        },
547        /**
548         * Обновление по адресу
549         * @return {boolean}
550         */
551        refreshByHref = function() {
552            methods.refresh( $(this).attr('href') );
553            return false;
554        },
555        /**
556         * Применить купон
557         *
558         */
559        applyCoupon = function() {
560            methods.refresh();
561        },
562
563        checkout = function(e) {
564            var url = $(data.options.cartForm).attr('action');
565            var param = (url.indexOf('?') > -1 ? '&' : '?') + 'checkout=1';
566            methods.refresh(url + param);
567            return false
568        };
569
570    if ( methods[method] ) {
571        methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
572    } else if ( typeof method === 'object' || ! method ) {
573        return methods.init.apply( this, arguments );
574    }
575};

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.