const store = { untouched: [], snapshot: { client_name: null, client_email: null, subject: null, message: null, }, }; const SUCCESS_MESSAGE = 'Мы ценим, что у тебя нашлось время задать вопрос — каждое обращение помогает нам улучшать сервис. Ответим на указанный email в течение 2 часов.'; async function createTicket(udForm) { const url = '/usedesk/create/ticket'; let data = { api_token: '4091e2986e36f05c506f57be8efe9f815a64cdc9', client_id: 'new_client', }; const result = validateForm(udForm); if (result) { return; } const now = new Date(); if ( localStorage.getItem('usedeskLastTime') && (now.getTime() - new Date(parseInt(localStorage.getItem('usedeskLastTime'), 10)).getTime()) / 1000 < 60 * 5 ) { document.querySelector(`#ud${udForm}MsgBox`).style = 'display: block'; document.querySelector(`#ud${udForm}MsgBox`).innerHTML = `Форму можно отправлять не чаще, чем раз в 5 минут. Попробуйте, пожалуйста, позже.`; document.querySelector(`#ud${udForm}Submit`).innerHTML = 'Отправить'; return; } localStorage.setItem('usedeskLastTime', now.getTime()); document.querySelector(`#ud${udForm}Submit`).disabled = true; document.querySelector(`#ud${udForm}Submit`).innerHTML = '
'; data = Object.assign({}, data, validate.collectFormValues(document.querySelector(`#udForm${udForm}`))); try { const response = await fetch(url, { method: 'POST', cache: 'no-cache', credentials: 'same-origin', headers: { 'Content-Type': 'application/json', }, redirect: 'follow', referrerPolicy: 'no-referrer', body: JSON.stringify(data), }); // Обрабатываем ошибки со статусом 40х, 50х if (response.status >= 400) { throw new Error(`ошибка ${response.status}`); } document.querySelector(`#ud${udForm}MsgBox`).style = 'display: block'; document.querySelector(`#ud${udForm}Submit`).innerHTML = 'Отправлено'; document.querySelector(`#ud${udForm}Submit`).disabled = true; document.querySelector(`#ud${udForm}MsgBox`).innerHTML = SUCCESS_MESSAGE; } catch(error) { localStorage.removeItem('usedeskLastTime'); document.querySelector(`#ud${udForm}MsgBox`).style = 'display: block'; document.querySelector(`#ud${udForm}MsgBox`).innerHTML = `Не удалось отправить: ${error.message || 'неизвестная ошибка'}`; document.querySelector(`#ud${udForm}Submit`).innerHTML = 'Отправить'; } } const constrains = { client_name: { presence: true, length: { maximum: 255, }, }, client_email: { presence: true, length: { maximum: 255, }, email: true, }, subject: { presence: true, }, message: { presence: true, }, }; function validateForm(udForm, subjectValue) { let values = validate.collectFormValues(document.querySelector(`#udForm${udForm}`)); if (subjectValue) { store.subjectValue = subjectValue; } Object.assign(values, { subject: store.subjectValue || null }); Object.keys(values).forEach(key => { const idx = store.untouched.findIndex(el => el === `${udForm}${key}`); if (idx !== -1 && values[key] !== store.snapshot[key]) { store.untouched.splice(idx, 1); } }); const result = validate( values, constrains, { format: 'detailed' }, ); // Очищаем предыдущий результат Object.keys(constrains).forEach(el => { const formElement = document.querySelector(`#udForm${udForm} [name='${el}']`); let errField; let borderElement; if (el === 'subject') { errField = formElement.parentElement.parentElement.parentElement.querySelector('.form-input__error'); borderElement = document.querySelector(`#udForm${udForm} .choices__inner`); } else { errField = formElement.parentElement.querySelector('.form-input__error'); borderElement = formElement; } borderElement.style.borderBottom = '1px solid #FFFFFF'; errField.style = 'display: none'; errField.innerHTML = ''; }); document.querySelector(`#ud${udForm}Submit`).disabled = false; document.querySelector(`#ud${udForm}Submit`).innerHTML = 'Отправить'; document.querySelector(`#ud${udForm}MsgBox`).style = 'display: none'; // Отрисовываем текущий результат if (!result) { return null; } document.querySelector(`#ud${udForm}Submit`).disabled = true; result.forEach(el => { if (store.untouched.find(uel => uel === `${udForm}${el.attribute}`)) { return; } const formElement = document.querySelector(`#udForm${udForm} [name='${el.attribute}']`); let errField; let borderElement; if (el.attribute === 'subject') { errField = formElement.parentElement.parentElement.parentElement.querySelector('.form-input__error'); borderElement = document.querySelector(`#udForm${udForm} .choices__inner`); } else { errField = formElement.parentElement.querySelector('.form-input__error'); borderElement = formElement; } errField.style = 'display: block'; borderElement.style.borderBottom = '1px solid #FF001F'; switch(el.validator) { case 'presence': errField.innerHTML = 'Обязательное поле'; break; case 'email': errField.innerHTML = 'Неправильный e-mail'; break; default: break; } }); store.snapshot = values; return result; } document.getElementById('ud1Submit').onclick = () => createTicket(1); if (document.getElementById('ud2Submit')) { document.getElementById('ud2Submit').onclick = () => createTicket(2); } Object.keys(constrains).forEach(el => { if (el === 'subject') { return; } store.untouched = [...Object.keys(constrains).map(el => `1${el}`), ...Object.keys(constrains).map(el => `2${el}`)]; document.querySelector(`#udForm1 [name='${el}']`).oninput = () => { validateForm(1); }; if (!document.querySelector('#udForm2')) { return; } document.querySelector(`#udForm2 [name='${el}']`).oninput = () => { validateForm(2); }; }); const choicesOpts = { silent: true, searchEnabled: false, shouldSort: false, position: 'bottom', itemSelectText: '', }; const choices = new Choices(`#udForm1 [name='subject']`, choicesOpts); choices.passedElement.element.addEventListener('choice', choice => { validateForm(1, choice); }, false); if (document.querySelector('#udForm2')) { const choices2 = new Choices(`#udForm2 [name='subject']`, choicesOpts); choices2.passedElement.element.addEventListener('choice', choice => { validateForm(2, choice); }, false); }