PageSourceSearch

https://gdekomfort.ru/templates/komfort/resource/js/rscomponent/comments.js

js gdekomfort.ru collected 2026-10-05 02:26:24 UTC 5,400 bytes, 171 lines download raw bytes

1/**
2 * Инициализирует работу отзывов
3 */
4new class Comments extends RsJsCore.classes.component {
5
6    constructor(settings) {
7        super();
8
9        let defaults = {
10            context: '.rs-comments',
11            comment: '.rs-comment',
12            stars: '.rs-stars li',
13            rate: '.rs-rate',
14            inputRate: '.inp_rate',
15            rateDescr: '.rs-rate-descr',
16            ratingFilter: '.rs-comment-filter',
17            activeClass: 'active',
18            loadingClass: 'rs-in-loading',
19            voteAction: '.rs-comment-vote-plus,.rs-comment-vote-minus',
20            rateText: [
21                lang.t('нет оценки'),
22                lang.t('ужасно'),
23                lang.t('плохо'),
24                lang.t('нормально'),
25                lang.t('хорошо'),
26                lang.t('отлично')
27            ],
28            formSelector: '.rs-comments-form',
29        };
30
31        this.settings = { ...defaults, ...this.getExtendsSettings(), ...settings };
32    }
33
34    /**
35     * Инициаизирует выбор оценки для отзыва
36     *
37     * @param event
38     */
39    initStarsSelect(event) {
40        this.context = event.target.querySelector(this.settings.context);
41
42        if (this.context) {
43            this.context.querySelectorAll(this.settings.stars).forEach((element) => {
44                element.addEventListener('mouseover', event => this.overStar(event));
45                element.addEventListener('mouseout', event => this.restoreStars(event));
46                element.addEventListener('click', event => this.setMark(event));
47            });
48
49            this.restoreStars();
50        }
51    }
52
53    /**
54     * Возвращает порядковый номер элемента среди братьев в DOM
55     *
56     * @param element
57     * @returns {number}
58     */
59    getNodeIndex(element) {
60        return [...element.parentNode.children].indexOf(element);
61    }
62
63    /**
64     * Обработчик наведения мыши на звезду
65     *
66     * @param event
67     */
68    overStar(event) {
69        this.selectStars(this.getNodeIndex(event.target) + 1);
70    }
71
72    /**
73     * Подсвечивает нужную оценку на звездах
74     *
75     * @param index
76     */
77    selectStars(index) {
78        let allStars = this.context.querySelectorAll(this.settings.stars);
79        allStars.forEach(element => {
80            element.classList.remove(this.settings.activeClass);
81        });
82
83        for (let i = 0; i <= index - 1; i++) {
84            allStars[i].classList.add(this.settings.activeClass);
85        }
86
87        let description = this.context.querySelector(this.settings.rateDescr);
88        description && (description.innerText = this.settings.rateText[index]);
89    }
90
91    /**
92     * Восстанавливает визуальное отображение оценки к предыдущему закрепленному значению
93     */
94    restoreStars() {
95        let inputRate = this.context.querySelector(this.settings.inputRate);
96        if (inputRate) {
97            this.selectStars(inputRate.value);
98        }
99    }
100
101    /**
102     * Фиксирует новую оценку
103     *
104     * @param event
105     */
106    setMark(event) {
107        this.context.querySelector(this.settings.inputRate).value = this.getNodeIndex(event.target) + 1;
108    }
109
110    initFormSubmit(event) {
111        const form = event.target.querySelector(this.settings.formSelector);
112
113        if (form) {
114            form.addEventListener('submit', (event) => {
115                event.preventDefault();
116                this.handleFormSubmit(form);
117            });
118        }
119    }
120
121    handleFormSubmit(form) {
122        const formData = new FormData(form);
123        const url = form.action;
124        const method = form.method;
125
126        fetch(url, {
127            method: method,
128            body: formData,
129        })
130            .then(response => response.text())
131            .then(() => {
132                location.reload();
133            })
134            .catch(error => {
135                console.error('Error:', error);
136            });
137    }
138
139    initVote(event) {
140        const allVoiteActions = event.target.querySelectorAll(this.settings.voteAction);
141
142        if (allVoiteActions) {
143            allVoiteActions.forEach(voiteAction => {
144                voiteAction.addEventListener('click', () => {
145                    this.utils.fetchJSON(voiteAction.dataset.href, {
146                        method:'POST',
147                    }).then((response) => {
148                        if (response.success == true) {
149                            const comment = voiteAction.closest(this.settings.comment);
150
151                            comment.querySelector('.rs-comment-vote-minus span').innerText = response.vote_no;
152                            comment.querySelector('.rs-comment-vote-plus span').innerText = response.vote_yes;
153                        }
154                    });
155                });
156            });
157        }
158    }
159
160    /**
161     * Обработчик события нового контента на странице
162     *
163     * @param event
164     */
165    onContentReady(event) {
166        this.initStarsSelect(event);
167        this.plugins.ajaxPaginator.init('.rs-ajax-paginator');
168        this.initFormSubmit(event);
169        this.initVote(event);
170    }
171};

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.