PageSourceSearch

https://gdekomfort.ru/resource/js/core6/rsplugins/opendialog.js

js gdekomfort.ru collected 2026-10-05 02:26:00 UTC 6,070 bytes, 192 lines download raw bytes

1/**
2 * Плагин, позволяющий открывать диалоговые окна с предварительной загрузкой данных через AJAX.
3 * Переводит любую отправку формы внутри окна в режим AJAX.
4 *
5 * Зависит от RsJsCore.plugins.modal
6 */
7new class OpenDialog extends RsJsCore.classes.plugin {
8
9    constructor() {
10        super();
11        let defaults = {
12            inDialogSelector: '.rs-in-dialog',
13            disableClass: 'disabled',
14            skipFormAjaxClass: 'no-ajax'
15        };
16        this.settings = {...defaults, ...this.getExtendsSettings()};
17
18        if (RsJsCore.plugins.modal) {
19            this.modal = RsJsCore.plugins.modal;
20        } else {
21            console.error(lang.t('Плагин для модальных окон RsJsCore.plugins.modal не установлен'));
22        }
23
24        this._bindEvents();
25    }
26
27    /**
28     * Устанавливает необходимые обработчики событий
29     *
30     * @private
31     */
32    _bindEvents() {
33        document.addEventListener('click', (e) => {
34            let element = e.target.closest(this.settings.inDialogSelector);
35            if (element) {
36                let href = element.dataset.href ? element.dataset.href : element.href;
37                if (href) {
38                    if (!element.classList.contains(this.settings.disableClass)) {
39                        this.show({
40                            url: href
41                        });
42                    }
43
44                    e.preventDefault();
45                }
46            }
47        });
48    }
49
50    /**
51     * Загружает данные по URL, открывает диалоговое окно с загруженными данными
52     * @param options
53     * @param requestOptions
54     */
55    show(options, requestOptions) {
56        let defaults = {
57            url:'',
58            data: {},
59            callback: null,
60            bindSubmit: true
61        };
62        this.options = {...defaults, ...options};
63
64        let url = new URL(this.options.url, window.location.origin);
65        url.searchParams.append('dialogWrap', 1);
66        Object.keys(this.options.data).forEach(key => url.searchParams.append(key, this.options.data[key]));
67
68        this._requestContent(url, requestOptions);
69    }
70
71    /**
72     * Выполняет запрос к серверу на получение контента и открывает его в модальном окне
73     *
74     * @param url
75     * @param options
76     * @private
77     */
78    _requestContent(url, options) {
79        this.showOverlay();
80
81        return RsJsCore.utils.fetchJSON(url, options).then(response => {
82            this._prepareResponse(response);
83            if (response.html) {
84                this.modal.open(response.html, (event) => {
85                    this._prepareHtml(response, event.target);
86                });
87            }
88
89        }).finally(() => {
90            this.hideOverlay();
91        });
92    }
93
94    /**
95     * Обрабатывает специфические json ключи, которые отвечают за действия.
96     *
97     * @param response
98     * @private
99     */
100    _prepareResponse(response) {
101        if (response.closeDialog) {
102            if (this.modal && this.modal.isOpen()) {
103                this.modal.close();
104                response.html = null;
105            }
106        }
107
108        if (response.redirect) {
109            this.show({
110                url: response.redirect
111            });
112            response.html = null;
113        }
114
115        return true;
116    }
117
118    /**
119     * Выполняет обработку полученного с сервера HTML-кода.
120     * Навешивает необходимые события
121     *
122     * @param response
123     * @param element
124     * @private
125     */
126    _prepareHtml(response, element)
127    {
128        if (this.options.bindSubmit) {
129            element.querySelectorAll('form').forEach((form) => {
130                if (!form.classList.contains(this.settings.skipFormAjaxClass)) {
131                    this._ajaxForm(form);
132                }
133            });
134        }
135
136        if (this.options.callback) {
137            this.options.callback.call(this, response, element);
138        }
139    }
140
141    /**
142     * Отправляет все формы в диалоговом окне на сервер с помощью AJAX
143     *
144     * @param form
145     * @private
146     */
147    _ajaxForm(form) {
148        form.addEventListener('submit', (event) => {
149            event.preventDefault();
150
151            let data = new FormData(form);
152            let formAction = form.dataset.ajaxAction ? form.dataset.ajaxAction : form.getAttribute('action');
153            if (!formAction) formAction = '';
154            formAction += formAction.indexOf('?') === -1 ? '?dialogWrap=1' : '&dialogWrap=1';
155
156            form.querySelectorAll('button[type="submit"], input[type="submit"]').forEach((element) => {
157                element.disabled = true;
158            });
159
160            this._requestContent(formAction, {
161                method: 'POST',
162                body: data
163            })
164            .finally(() => {
165                form.querySelectorAll('button[type="submit"], input[type="submit"]').forEach((element) => {
166                    setTimeout(() => {
167                        element.disabled = false;
168                    }, 500);
169                });
170            });
171        });
172    }
173
174    /**
175     * Отображает прелоадер, в момент, когда происходит загрузка
176     * данных с сервера, до открытия окна
177     */
178    showOverlay() {
179        if (this.modal.isOpen()) {
180            this.modal.showLoader();
181        }
182    }
183
184    /**
185     * Скрывает прелоадер предшествующий отображению окна
186     */
187    hideOverlay() {
188        if (this.modal.isOpen()) {
189            this.modal.hideLoader();
190        }
191    }
192};

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.