PageSourceSearch

https://fabrika38.ru/local/components/wms/wms.forms/js/components/contacts-form.js?177519546512010

js fabrika38.ru collected 2026-10-07 20:05:32 UTC 12,010 bytes, 321 lines download raw bytes

1(function () {
2    if (typeof BX.wms === 'undefined') {
3        BX.wms = {};
4    }
5    if (typeof BX.wms.forms === 'undefined') {
6        BX.wms.forms = {};
7    }
8
9    BX.wms.forms.contactsForm = {
10        name: 'contactsForm',
11        components: {
12            CitySuggestInput: BX.wms.forms.CitySuggestInput
13        },
14        props: {
15            dadataKey: {type: String, default: ''},
16            userId: {type: [String, Number], default: ''},
17            yandexSiteKey: {type: String, default: ''},
18            captchaResetKey: {
19                type: [String, Number],
20                default: () => Date.now()
21            },
22            errors: {
23                type: Object,
24                default: () => ({})
25            }
26        },
27        data() {
28            return {
29                name: '',
30                email: '',
31                phone: '',
32                city: '',
33                message: '',
34                subject: '',
35                agreement: false,
36                successSent: false,
37                errorSent: false,
38                serverError: false,
39                useYandexCaptcha: true,
40                smartToken: null,
41                phoneMaskInstance: null,
42            };
43        },
44        watch: {
45            errors: {
46                handler(newErrors) {
47                    if (!this.$el) return;
48
49                    this.clearAllErrors();
50                    const captchaContainer = this.$el.querySelector('.form-captcha-container');
51                    if (captchaContainer) {
52                        captchaContainer.classList.remove('error');
53                    }
54
55                    if (!newErrors || typeof newErrors !== 'object') return;
56
57                    Object.keys(newErrors).forEach(fieldName => {
58                        if (fieldName === 'smartToken') {
59                            if (captchaContainer) {
60                                captchaContainer.classList.add('error');
61                            }
62                        } else {
63                            const input = this.$el.querySelector(`[name="${fieldName}"]`);
64                            if (input) {
65                                input.classList.add('error');
66                            }
67                        }
68                    });
69                },
70                deep: true,
71                immediate: true
72            }
73        },
74        mounted() {
75            if (BX.wms.forms.FormPersistence) {
76                BX.wms.forms.FormPersistence.initFormPersistence.call(this);
77            }
78            const phoneInput = this.$el.querySelector('.phone');
79            if (phoneInput && window.Inputmask) {
80                const mask = new window.Inputmask('+7 (999) 999-99-99', {
81                    showMaskOnHover: false,
82                    showMaskOnFocus: true,
83                    clearIncomplete: true,
84                    autoUnmask: false
85                });
86                mask.mask(phoneInput);
87                this.phoneMaskInstance = mask;
88            }
89
90            if (this.$el) this.$el.querySelectorAll('.input').forEach(input => {
91                input.addEventListener('input', () => input.classList.remove('error'));
92            });
93
94            // Инициализация поля города
95            if (window.BX && window.BX.Suggest) {
96                new window.BX.Suggest('cities-list', function (value) {
97                    this.value = value;
98                    this.dispatchEvent(new Event('input'));
99                }.bind(this.$el.querySelector('#city-field')));
100            }
101        },
102        beforeUnmount() {
103            if (this.phoneMaskInstance) {
104                this.phoneMaskInstance.remove();
105            }
106        },
107        methods: {
108            validateForm() {
109                this.clearAllErrors();
110                let isValid = true;
111
112                if (!this.name.trim()) {
113                    this.setError('name');
114                    isValid = false;
115                }
116
117                if (!this.email || !/^\S+@\S+\.\S+$/.test(this.email)) {
118                    this.setError('email');
119                    isValid = false;
120                }
121
122                const phoneDigits = this.phone.replace(/\D/g, '');
123                if (!this.phone || !/^(7|8)\d{10}$/.test(phoneDigits)) {
124                    this.setError('phone');
125                    isValid = false;
126                }
127
128                if (!this.agreement) {
129                    this.setError('agreement');
130                    isValid = false;
131                }
132
133                return isValid;
134            },
135            setError(fieldName) {
136                const fieldMap = {
137                    name: '#name-field',
138                    phone: '#phone-field',
139                    email: '#email-field',
140                    agreement: '#contact-consent'
141                };
142                const selector = fieldMap[fieldName];
143                if (!selector) return;
144
145                const el = this.$el.querySelector(selector);
146                if (!el) return;
147
148                el.classList.add('error');
149
150            },
151            clearAllErrors() {
152                if (!this.$el) return;
153                this.$el.querySelectorAll('.input.error, textarea.error').forEach(el => {
154                    el.classList.remove('error');
155                });
156                this.$el.querySelectorAll('.checkboxEl.error').forEach(el => {
157                    el.classList.remove('error');
158                });
159            },
160            async submitForm() {
161                if (!this.validateForm()) {
162                    this.errorSent = true;
163                    return;
164                }
165
166                let data = {
167                    name: this.name,
168                    email: this.email,
169                    phone: this.phone,
170                    city: this.city,
171                    smartToken: this.smartToken
172                };
173                try {
174                    await this.$emit('submit', data);
175                    // this.successSent = true;
176                    //this.resetForm();
177                } catch (e) {
178                    this.errorSent = true;
179                    this.serverError = true;
180                }
181            },
182            handleTokenUpdate(token) {
183                this.smartToken = token;
184                this.errorSent = false;
185            },
186            resetForm() {
187                this.name = '';
188                this.email = '';
189                this.phone = '';
190                this.city = '';
191                this.message = '';
192                this.subject = '';
193                this.agreement = false;
194                this.smartToken = null;
195            },
196            resetAll() {
197                this.resetForm(); // Сбрасываем поля
198                this.successSent = false; // Скрываем окно успеха
199            },
200        },
201        computed: {
202            isLoggedIn() {
203                return this.userId && Number(this.userId) > 0;
204            }
205        },
206        template: `
207    <div>
208        <h2>Мы на связи</h2>
209        <p>Оставьте заявку, и мы свяжемся с вами</p>
210            <form id="contactForm" class="turqForm contactForm  saveState " @submit.prevent="submitForm">
211
212                <div class="input-wrap" :class="{ error: !!errors.name }">
213                    <input 
214                        placeholder="Ваше имя" 
215                        type="text" 
216                        class="input" 
217                        name="name" 
218                        id="name-field"
219                        v-model="name"
220                        @input="$event.target.classList.remove('error')"
221                    >
222                </div>
223
224                <div class="input-wrap" :class="{ error: !!errors.phone }">
225                    <input 
226                        placeholder="+7 (___)-___-__-__" 
227                        type="text" 
228                        name="phone" 
229                        class="input phone" 
230                        id="phone-field"
231                        v-model="phone"
232                        @input="$event.target.classList.remove('error')"
233                    >
234                </div>
235
236                <div class="input-wrap" :class="{ error: !!errors.email }">
237                    <input 
238                        placeholder="E-mail" 
239                        type="text" 
240                        name="email" 
241                        class="input" 
242                        id="email-field"
243                        v-model="email"
244                        @input="$event.target.classList.remove('error')"
245                    >
246                </div>
247
248                <div class="input-wrap">
249                        <city-suggest-input
250                            v-model="city"
251                            placeholder="Город"
252                            :dadata-key="dadataKey"
253                            @select="onCitySelect"
254                        />
255                    </div>
256
257                      <div class="wrapBox">
258                    <div class="checkboxEl vue-consent input-wrap">
259                        <input id="contact-consent" type="checkbox" v-model="agreement" name="agreement" required>
260                        <label for="contact-consent">
261                            <span class="agreement-box box" style="pointer-events: none"></span>
262                            Я согласен на <a href="/politika-konfidentsialnosti/">обработку своих персональных данных.</a>
263                        </label>
264                    </div>
265                </div>
266                <div class="wrapBox">
267                    <div v-if="useYandexCaptcha" 
268                         class="form-captcha-container"
269                         @click="removeCaptchaError"
270                         id="yandex-captcha-container"
271                    >
272                        <yandex-captcha
273                            :key="captchaResetKey"
274                            :site-key="yandexSiteKey"
275                            size="compact"
276                            theme="light"
277                            @update:model-value="handleTokenUpdate"
278                        />
279                    </div>
280                </div>
281          
282                    
283                <div class="wrapBox wrapBtn">
284                    <input 
285                        type="button"
286                        @click="submitForm"
287                        name="web_form_submit" 
288                        class="btn green" 
289                        :value="successSent ? 'Отправлено!' : 'Отправить заявку'"
290                        :disabled="successSent"
291                    >
292
293
294                     <p class="tipText sucess_res" v-show="successSent">
295                           <span class="text-box">
296                                Ваша заявка успешно отправлена!
297                           </span>
298                          <input 
299                        type="button"
300                        @click="resetAll"
301                        class="btn green" 
302                         :value="'Отлично'"
303                    >
304                    </p>
305                    <p class="tipText error_res " v-show="errorSent && !serverError">
306                    <span class="errorFormRedBg">
307                       <i class="error-ic ic"></i> Проверьте правильность ввода данных
308                     </span>
309                     
310                    </p>
311                    <p class="tipText error_res" v-show="errorSent && serverError">
312                         <span class="errorFormRedBg">
313                       <i class="error-ic ic"></i> Ошибка на сервере. Повторите попытку позже.
314                     </span>
315                    </p>
316                </div>
317            </form>
318    </div>        
319`
320    };
321})();

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.