PageSourceSearch

https://www.unionmart.ru/bitrix/templates/design2025/js/script.js

js unionmart.ru collected 2026-10-01 12:36:38 UTC 17,943 bytes, 553 lines download raw bytes

1document.addEventListener('DOMContentLoaded', function () {
2    const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
3    tooltipTriggerList.forEach(function (el) {
4        new bootstrap.Tooltip(el);
5    });
6
7    $(function(){
8        $('input[type="tel"]').mask('+7 (999) 999-99-99');
9    });
10
11
12
13    const clampBlocks = document.querySelectorAll('[data-lineclump]');
14
15    function isClamped(el) {
16        return el.scrollHeight > el.clientHeight + 1;
17    }
18
19    function bindBlock(el) {
20
21        const btn =
22            el.parentElement?.querySelector('[data-lineclump-btn]') ||
23            (el.nextElementSibling?.matches('[data-lineclump-btn]') ? el.nextElementSibling : null);
24
25        if (!btn) return;
26
27        const openText = btn.dataset.open || 'Read more';
28        const hideText = btn.dataset.hide || 'Hide';
29
30        const updateButtonVisibility = () => {
31            if (el.classList.contains('is-open')) {
32                btn.hidden = false;
33                return;
34            }
35
36            btn.hidden = !isClamped(el);
37        };
38
39        requestAnimationFrame(updateButtonVisibility);
40
41        window.addEventListener('resize', updateButtonVisibility);
42
43        btn.addEventListener('click', () => {
44
45            const opened = el.classList.toggle('is-open');
46
47            btn.classList.toggle('is-open', opened);
48
49            btn.textContent = opened ? hideText : openText;
50
51            requestAnimationFrame(updateButtonVisibility);
52
53        });
54    }
55
56    clampBlocks.forEach(bindBlock);
57});
58$(document).on('click', 'button[data-product][data-bs-target]', function () {
59    var productName = $(this).data('product');
60    var modalSelector = $(this).data('bs-target');
61
62    if (!productName || !modalSelector) return;
63
64    var $modal = $(modalSelector);
65
66    if (!$modal.length) return;
67
68    $modal.find('input[name="PRODUCT"]').val(productName);
69});
70$('body').on('click', '.compare-add', function() {
71    var compareID = $(this).attr('data-id');
72    if($(this).hasClass('active')) {
73        var doAction = 'DELETE_FROM_COMPARE_LIST';
74    } else {
75        var doAction = 'ADD_TO_COMPARE_LIST';
76    }
77    addCompare(compareID, doAction);
78});
79$('body').on('click', '.favorite-add', function() {
80    var favorID = $(this).attr('data-id');
81    if($(this).hasClass('active'))
82        var doAction = 'delete';
83    else
84        var doAction = 'add';
85
86    addFavorite(favorID, doAction);
87});
88function addCompare(id, action){
89    var AddedGoodId = id;
90    var GoodAction = action;
91    $.get("/ajax/list_compare.php",
92        {action: GoodAction, id: AddedGoodId},
93        function(data) {
94            if($('.compare-add[data-id="'+id+'"]').hasClass('active')) {
95                $('.compare-add[data-id="'+id+'"]').removeClass('active');
96            } else {
97                $('.compare-add[data-id="'+id+'"]').addClass('active');
98            }
99        }
100    );
101}
102function addFavorite(id, action){
103    var param = 'id='+id+"&action="+action;
104    $.ajax({
105        url: '/ajax/favorites.php', // URL отправки запроса
106        type: "GET",
107        dataType: "html",
108        data: param,
109        success: function(response) { // Если Данные отправлены успешно
110            var result = $.parseJSON(response);
111            if(result == 1) { // Если всё чётко, то выполняем действия, которые показывают, что данные отправлены :)
112                $('.favorite-add[data-id="'+id+'"]').addClass('active');
113                var wishCount = parseInt($('#want .col').html()) + 1;
114                $('#want .col').html(wishCount); // Визуально меняем количество у иконки
115            }
116            if(result == 2){
117                $('.favorite-add[data-id="'+id+'"]').removeClass('active');
118                var wishCount = parseInt($('#want .col').html()) - 1;
119                $('#want .col').html(wishCount); // Визуально меняем количество у иконки
120            }
121        },
122        error: function(jqXHR, textStatus, errorThrown){ // Если ошибка, то выкладываем печаль в консоль
123            console.log('Error: '+ errorThrown);
124        }
125    });
126}
127function updateHeaderBasketCount() {
128    return $.getJSON('/ajax/basket/count.php')
129        .done(function (res) {
130            if (!res?.success) return;
131
132            const $root = $('#header-basket-line');
133
134            // 1) стандартный битриксовый селектор (часто встречается)
135            let $countNode = $root.find('[data-entity="basket-items-count"]').first();
136
137            // 2) запасные варианты (под разные шаблоны)
138            if (!$countNode.length) $countNode = $root.find('.basket-items-count, .js-basket-count, .basket-count').first();
139
140            if ($countNode.length) {
141                $countNode.text(res.count);
142            } else {
143                // если вообще не нашли узел — выведем в консоль, чтобы ты дала мне реальный селектор
144                console.warn('Не нашёл узел счётчика внутри #header-basket-line. Добавь data-entity="basket-items-count" на нужный <span>.');
145            }
146        });
147}
148$(document).on('click', '.buy-btn', function (e) {
149    e.preventDefault();
150
151    const modalCart = document.getElementById('modal');
152    const cart_modal = new bootstrap.Modal(modalCart);
153
154    const $btn = $(this);
155    const productId = parseInt($btn.attr('data-id'), 10);
156    if (!productId) return;
157
158    // Берём значение ближайшего input[name="b_qnt"]
159    const $qnt = $btn.closest('.product-item-actions-block')
160        .find('input[name="b_qnt"]')
161        .first();
162
163    let qty = $qnt.length ? $qnt.val() : 1;
164    qty = (String(qty).replace(',', '.'));
165    qty = parseFloat(qty);
166    if (!qty || qty <= 0) qty = 1;
167
168    $btn.prop('disabled', true).addClass('is-loading');
169
170    $.ajax({
171        url: '/ajax/basket/add.php',
172        method: 'POST',
173        dataType: 'json',
174        data: {
175            sessid: BX.bitrix_sessid(),
176            product_id: productId,
177            quantity: qty
178        }
179    })
180        .done(function (res) {
181            if (!res || !res.success) {
182                console.error(res);
183                return;
184            }
185            $('#modal .modal-header .cnt').text(res.header);
186            $('#modal .modal-body').html(res.content);
187            cart_modal.show();
188            updateHeaderBasketCount();
189        })
190        .fail(function (xhr) {
191            console.error(xhr);
192        })
193        .always(function () {
194            $btn.prop('disabled', false).removeClass('is-loading');
195        });
196});
197$(function () {
198    updateHeaderBasketCount();
199});
200$(document).ready(function() {
201    const THANKS_URL = '/spassibo/';
202
203    function redirectToThanks() {
204        sessionStorage.setItem('thanksBackUrl', window.location.href);
205        window.location.href = THANKS_URL;
206    }
207
208    function lockForm($form) {
209        $form.data('isSubmitting', true);
210        $form.find('button[type="submit"], input[type="submit"]').prop('disabled', true).addClass('is-loading');
211    }
212
213    function unlockForm($form) {
214        $form.data('isSubmitting', false);
215        $form.find('button[type="submit"], input[type="submit"]').prop('disabled', false).removeClass('is-loading');
216    }
217
218    function showSubmitPreloader() {
219        const preloader = document.getElementById('submit-preloader');
220        if (preloader) {
221            preloader.hidden = false;
222            document.body.classList.add('is-submitting-form');
223        }
224    }
225
226    function hideSubmitPreloader() {
227        const preloader = document.getElementById('submit-preloader');
228        if (preloader) {
229            preloader.hidden = true;
230            document.body.classList.remove('is-submitting-form');
231        }
232    }
233
234    function hideModal(modalId) {
235        if (!modalId) return;
236
237        const modalEl = document.getElementById(modalId);
238        if (!modalEl) return;
239
240        bootstrap.Modal.getOrCreateInstance(modalEl).hide();
241    }
242
243    function resetForm($form) {
244        $form.find('input:not([type="hidden"]):not([type="checkbox"]):not([type="radio"]), textarea').val('');
245        $form.find('input[type="checkbox"], input[type="radio"]').prop('checked', false);
246        $form.trigger('reset');
247    }
248
249    function hideError($form) {
250        $form.find('.alert.alert-danger').addClass('hidden');
251    }
252
253    function showError($form, $str = "") {
254        var $alert = $form.find('.alert.alert-danger');
255        if ($alert.length === 0) {
256            $alert = $('<div class="mb-3 alert alert-danger hidden"></div>');
257            $form.find('#captcha-container').after($alert);
258        }
259        clearTimeout($alert.data('timer'));
260        $alert.removeClass('hidden').text($str);
261        var timer = setTimeout(function() {
262            $alert.addClass('hidden').text("");
263        }, 3000);
264        $alert.data('timer', timer);
265    }
266
267    function submitAjaxForm(options) {
268        const $form = $(options.formSelector);
269
270        if (!$form.length) return;
271
272        $form.off('submit.ajaxForm').on('submit.ajaxForm', function(e) {
273            e.preventDefault();
274
275            const curForm = $(this);
276
277            if (curForm.data('isSubmitting')) {
278                console.warn('[FORM BLOCKED] already submitting');
279                return;
280            }
281
282            hideError(curForm);
283            lockForm(curForm);
284            showSubmitPreloader();
285
286            const runRequest = function() {
287                $.ajax({
288                    type: options.method || 'POST',
289                    url: options.url,
290                    data: options.getData ? options.getData(curForm) : curForm.serialize(),
291                    dataType: options.dataType || 'json',
292                    success: function(result) {
293                        const isSuccess = options.isSuccess
294                            ? options.isSuccess(result)
295                            : (result.status === 'success');
296
297                        if (isSuccess) {
298                            if (typeof options.goal === 'function') {
299                                options.goal(result, curForm);
300                            } else if (options.goal && typeof window.ym === 'function') {
301                                ym(677558, 'reachGoal', options.goal);
302                            }
303
304                            resetForm(curForm);
305                            hideError(curForm);
306                            hideModal(options.hideModalId);
307
308                            sessionStorage.setItem('thanksBackUrl', window.location.href);
309                            window.location.href = '/spassibo/';
310                        } else {
311                            hideSubmitPreloader();
312                            unlockForm(curForm);
313                            showError(curForm, result.errors);
314                        }
315                    },
316
317                    error: function(xhr, status, error) {
318                        console.error('[AJAX ERROR]', {
319                            status: status,
320                            error: error,
321                            httpStatus: xhr.status,
322                            responseText: xhr.responseText
323                        });
324
325                        hideSubmitPreloader();
326                        unlockForm(curForm);
327                        showError(curForm);
328                    }
329                });
330            };
331            runRequest();
332        });
333    }
334
335    submitAjaxForm({
336        formSelector: '#call_form',
337        url: '/ajax/call.modal.handler.php',
338        hideModalId: 'call-modal',
339        goal: 'zakazzvonka'
340    });
341
342    submitAjaxForm({
343        formSelector: '#callback-inline',
344        url: '/ajax/call.modal.handler.php',
345        goal: 'zakazzvonka'
346    });
347
348    submitAjaxForm({
349        formSelector: '#get-discount-form',
350        url: '/ajax/discount.form.handler.php',
351        debug: true
352    });
353
354    submitAjaxForm({
355        formSelector: '#service-modal-form',
356        url: '/ajax/form_ukladka_handler.php',
357        hideModalId: 'service-modal',
358        debug: true
359    });
360
361    submitAjaxForm({
362        formSelector: '#ask-form',
363        url: '/ajax/ask.modal.handler.php',
364        hideModalId: 'ask-modal',
365        goal: 'zadatvopros'
366    });
367
368    submitAjaxForm({
369        formSelector: '#ask-question-new',
370        url: '/ajax/kp.handler.php',
371        goal: 'zadatvopros'
372    });
373
374    submitAjaxForm({
375        formSelector: '#cheaper-form',
376        url: '/ajax/cheaper.php',
377        hideModalId: 'cheaper-modal'
378    });
379    /*
380    submitAjaxForm({
381        formSelector: '#vip-form',
382        url: '/ajax/vip-form.php',
383        hideModalId: 'vip-modal',
384        debug: true,
385        isSuccess: function(result) {
386            return result.status === 'success' || result.text !== 'Captcha';
387        }
388    });
389
390    submitAjaxForm({
391        formSelector: '#example-form',
392        url: '/ajax/example-form.php',
393        hideModalId: 'example-modal',
394        isSuccess: function(result) {
395            return result.status === 'success' || result.text !== 'Captcha';
396        }
397    });*/
398
399    submitAjaxForm({
400        formSelector: '#ask-price',
401        url: '/ajax/ask.pricelist.handler.php',
402        debug: true
403    });
404
405    submitAjaxForm({
406        formSelector: '#contact-form',
407        url: '/ajax/contact-form.handler.php',
408        hideModalId: 'contact-us-modal'
409    });
410
411    submitAjaxForm({
412        formSelector: '#subscribe',
413        url: '/ajax/subscribe.handler.php',
414        isSuccess: function(result) {
415            return result.status === 'success';
416        },
417        debug: true
418    });
419
420    submitAjaxForm({
421        formSelector: '#oneclick-form',
422        url: '/ajax/one-click-new.php',
423        hideModalId: 'one-click-modal',
424        debug: true,
425        isSuccess: function(result) {
426            return result.status === 'ok';
427        },
428        errorAsSuccess: function(xhr) {
429            try {
430                const result = xhr.responseJSON;
431                return result && result.status === 'ok';
432            } catch (e) {
433                return false;
434            }
435        }
436    });
437
438    submitAjaxForm({
439        formSelector: '#review-form',
440        url: '/ajax/reviews.handler.php',
441        hideModalId: 'review-modal',
442        method: 'POST',
443        dataType: 'json',
444        contentType: false,
445        processData: false,
446        getData: function() {
447            const form = document.getElementById('review-form');
448            const formData = new FormData(form);
449
450            const fileInput = $('#review-form input[name="userfile"]')[0];
451            if (fileInput && fileInput.files && fileInput.files[0]) {
452                formData.set('file_attach', fileInput.files[0]);
453            }
454
455            formData.set('comment', $('#review-form textarea').val());
456
457            return formData;
458        },
459        isSuccess: function() {
460            return true;
461        }
462    });
463
464    $('#vip-form').on('submit', function(e) {
465        e.preventDefault();
466
467        const curForm = $(this);
468
469        if (curForm.data('isSubmitting')) {
470            return;
471        }
472
473        hideError(curForm);
474        lockForm(curForm);
475        showSubmitPreloader();
476
477        $.ajax({
478            type: 'POST',
479            url: '/ajax/vip-form.php',
480            data: curForm.serialize(),
481            dataType: 'json',
482            headers: {
483                'X-Requested-With': 'XMLHttpRequest'
484            },
485            success: function(result) {
486                console.log('vip-form result:', result);
487
488                if (result.status === 'success') {
489                    resetForm(curForm);
490                    hideError(curForm);
491                    hideModal('vip-modal');
492                    sessionStorage.setItem('thanksBackUrl', window.location.href);
493                    window.location.href = '/spassibo/';
494                } else {
495                    hideSubmitPreloader();
496                    unlockForm(curForm);
497                    showError(curForm, result.errors);
498                }
499            },
500            error: function(xhr) {
501                console.log('vip-form xhr error:', xhr);
502                hideSubmitPreloader();
503                unlockForm(curForm);
504                showError(curForm);
505            }
506        });
507    });
508
509    $('#example-form').on('submit', function(e) {
510        e.preventDefault();
511
512        const curForm = $(this);
513
514        if (curForm.data('isSubmitting')) {
515            return;
516        }
517
518        hideError(curForm);
519        lockForm(curForm);
520        showSubmitPreloader();
521
522        $.ajax({
523            type: 'POST',
524            url: '/ajax/example-form.php',
525            data: curForm.serialize(),
526            dataType: 'json',
527            headers: {
528                'X-Requested-With': 'XMLHttpRequest'
529            },
530            success: function(result) {
531                console.log('example-form result:', result);
532
533                if (result.status === 'success') {
534                    resetForm(curForm);
535                    hideError(curForm);
536                    hideModal('example-modal');
537                    sessionStorage.setItem('thanksBackUrl', window.location.href);
538                    window.location.href = '/spassibo/';
539                } else {
540                    hideSubmitPreloader();
541                    unlockForm(curForm);
542                    showError(curForm, result.errors);
543                }
544            },
545            error: function(xhr) {
546                console.log('example-form xhr error:', xhr);
547                hideSubmitPreloader();
548                unlockForm(curForm);
549                showError(curForm);
550            }
551        });
552    });
553});

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.