PageSourceSearch

https://gdekomfort.ru/modules/shop/view/js/selectaddresschange.js

js gdekomfort.ru collected 2026-10-05 02:26:12 UTC 6,399 bytes, 191 lines download raw bytes

1/**
2 * Класс для работы с окном смены города.
3 * Зависит от autoComplete.js
4 */
5class SelectedAddressChange {
6
7    constructor(element, eventTarget) {
8        this.selector = {
9            ownerSelector: '.rs-region-change',
10            regionInput: '.rs-region-input',
11            markedRegion: '.rs-region-marked',
12            regionBlock: '.rs-region-block',
13            otherRegionForm: 'form',
14            loadingClass: 'in-loading'
15        };
16        this.class = {
17            open: 'rs-open',
18        };
19        this.mode = {
20            selectedAddress: 'selectedAddress',
21            dispatchEvent: 'dispatchEvent',
22        };
23        this.options = {
24            resultEventTarget: eventTarget,
25        };
26
27        this.owner = element.querySelector(this.selector.ownerSelector);
28
29        this.owner.querySelectorAll(this.selector.markedRegion).forEach((element) => {
30            element.addEventListener('click', async () => {
31                let address = await this.getAddressFieldsByRegionId(element.dataset.regionId);
32                if (address) {
33                    this.addressSelected(address);
34                }
35            });
36        });
37
38        this.owner.querySelector(this.selector.otherRegionForm).addEventListener('submit', (event) => {
39            event.preventDefault();
40            event.stopPropagation();
41            this.selectOtherAddress(event.target);
42        });
43
44        if (this.owner.querySelector('[name="country_id"]')) {
45            this.owner.querySelector('[name="country_id"]').addEventListener('change', (event) => {
46                this.loadRegionsByCountry(event.target.value);
47            });
48        }
49
50        this.initSearchAutocomplete();
51    }
52
53    /**
54     * Инициализирует autocomplete поиска региона по названию
55     */
56    initSearchAutocomplete()
57    {
58        let input = this.owner.querySelector(this.selector.regionInput);
59        let resultWrapper = input && input.closest('.rs-region-change')
60            .querySelector('.rs-autocomplete-result');
61        let cancelController;
62
63        let autoCompleteInstance = new autoComplete({
64            selector: () => input,
65            searchEngine: () => true,
66            wrapper: false,
67            data: {
68                src: async () => {
69                    if (cancelController) cancelController.abort();
70
71                    let data;
72                    cancelController = new AbortController();
73                    this.owner.classList.add(this.selector.loadingClass);
74                    data = await RsJsCore.utils.fetchJSON(input.dataset.regionAutocompleteUrl + '&' + new URLSearchParams({
75                        term: autoCompleteInstance.input.value
76                    }), {
77                        signal: cancelController.signal
78                    });
79                    this.owner.classList.remove(this.selector.loadingClass);
80
81                    return data ? data : [];
82                },
83                keys:['label']
84            },
85            resultsList: {
86                maxResults:20,
87                class: '',
88                position:'beforeend',
89                destination:() => resultWrapper,
90            },
91            resultItem: {
92                element: (element, data) => {
93                    let tpl;
94                    tpl = `<a class="dropdown-item">
95                                <div class="col">${data.value.label}</div>
96                            </a>`;
97                    element.innerHTML = tpl;
98                },
99                selected: 'selected'
100            },
101            events: {
102                input: {
103                    selection: (event) => {
104                        this.addressSelected(event.detail.selection.value.address_data);
105                    },
106                    open: (event) => {
107                        resultWrapper.classList.add('open');
108                    },
109                    close: (event) => {
110                        resultWrapper.classList.remove('open');
111                    }
112                }
113            }
114        });
115    }
116
117    /**
118     * Загружает регионы, исходя из выбранной страны
119     */
120    loadRegionsByCountry(countryId) {
121        let data = new FormData();
122        data.append('Act', 'getRegionsByParent');
123        data.append('parent_id', countryId);
124
125        RsJsCore.utils.fetchJSON(this.owner.dataset.url, {
126            method: 'post',
127            body: data
128        }).then((response) => {
129            if (response.success) {
130                this.owner.querySelector(this.selector.regionBlock).innerHTML = response.regionBlock;
131            }
132        });
133    }
134
135    /**
136     * "Выбирает" набранный вручную адрес
137     */
138    selectOtherAddress(form) {
139        let address = {
140            country_id: 0,
141            region_id: 0,
142            city_id: 0,
143            country: '',
144            region: '',
145            city: '',
146        };
147        form.querySelectorAll('[name]').forEach((element) => {
148            address[element.name] = element.value;
149        });
150        this.addressSelected(address);
151    }
152
153    /**
154     * Получает данные адреса на основе Id региона
155     */
156    async getAddressFieldsByRegionId(regionId) {
157        let data = new FormData();
158        data.append('Act', 'getAddressByRegion');
159        data.append('region_id', regionId);
160
161        return RsJsCore.utils.fetchJSON(this.owner.dataset.url, {
162            method: 'post',
163            body: data,
164        }).then((response) => {
165            if (response.success) {
166                return response.address;
167            }
168        });
169    }
170
171    /**
172     * "Выбирает" переданный адрес, выполняемые действия зависят от режима работы
173     *
174     * @param address - массив с данными адреса
175     */
176    addressSelected(address) {
177        let target = this.options.resultEventTarget;
178        if (typeof(target) == 'function') {
179            target(address);
180        } else {
181            target.dispatchEvent(new CustomEvent('addressSelected', {
182                detail: {
183                    address: address
184                }
185            }));
186        }
187
188        //Закрываем окно
189        RsJsCore.plugins.modal.close();
190    }
191};

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.