feat: add toolbar buttons, share, reset and contact modal to questionnaire2

This commit is contained in:
Anton
2026-05-12 22:03:41 +03:00
parent e25e18af45
commit faac35302b
2 changed files with 130 additions and 0 deletions
+55
View File
@@ -143,6 +143,11 @@
<span class="toolbar-title">Saarijärven koirapuisto — Уточняющий опросник</span>
<span class="save-status" id="saveStatus"></span>
</div>
<div class="toolbar-right">
<button class="toolbar-btn" id="btnReset" title="Очистить форму"><span class="btn-icon"></span><span class="btn-text"> Заново</span></button>
<button class="toolbar-btn" id="btnSave" title="Сохранить"><span class="btn-icon">💾</span><span class="btn-text"> Сохранить</span></button>
<button class="toolbar-btn primary" id="btnShare" title="Поделиться ссылкой"><span class="btn-icon">🔗</span><span class="btn-text"> Поделиться</span></button>
</div>
</div>
<div class="flash" id="flash"></div>
@@ -503,6 +508,56 @@
</div>
</div>
<!-- Кнопка внизу страницы -->
<div class="bottom-contact">
<button class="bottom-contact-btn" onclick="openModal()">✉ Форма по другому вопросу</button>
</div>
<!-- Модальное окно -->
<div class="modal-overlay" id="modalOverlay" onclick="closeModalOutside(event)">
<div class="modal">
<div class="modal-header">
<h3>Обращение по другому вопросу</h3>
<button class="modal-close" onclick="closeModal()">×</button>
</div>
<div class="modal-body">
<p class="modal-subtitle">Заполните форму — мы свяжемся с вами в ближайшее время.</p>
<form id="generalForm" action="https://formspree.io/f/xrejjoav" method="POST">
<input type="hidden" name="form_type" value="general_inquiry">
<input type="hidden" name="_replyto" id="general_replyto">
<div class="modal-field">
<label for="g_subject">Тема обращения <span class="required">*</span></label>
<input type="text" id="g_subject" name="subject" required placeholder="Например: вопрос о сотрудничестве">
</div>
<div class="modal-field">
<label for="g_message">Сообщение <span class="required">*</span></label>
<textarea id="g_message" name="message" required placeholder="Опишите ваш вопрос или предложение..."></textarea>
</div>
<div class="modal-field">
<label for="g_name">Ваше имя <span class="required">*</span></label>
<input type="text" id="g_name" name="name" required placeholder="Имя и фамилия">
</div>
<div class="modal-field">
<label for="g_email">Электронная почта <span class="required">*</span></label>
<input type="email" id="g_email" name="email" required placeholder="ваш@email.com">
</div>
<div class="modal-field">
<label for="g_phone">Телефон <span class="optional">(необязательно)</span></label>
<input type="tel" id="g_phone" name="phone" placeholder="+358 XX XXX XXXX">
</div>
<button type="submit" class="modal-submit" id="generalSubmitBtn">Отправить обращение</button>
<p class="modal-note">Нажимая кнопку, вы соглашаетесь на обработку персональных данных</p>
</form>
<div class="modal-success" id="modalSuccess" style="display:none;">
<div class="modal-success-icon"></div>
<h4>Обращение отправлено!</h4>
<p>Мы получили ваше сообщение и свяжемся с вами в ближайшее время.</p>
<button class="modal-submit" onclick="closeModal()">Закрыть</button>
</div>
</div>
</div>
</div>
<script src="script2.js"></script>
</body>
</html>
+75
View File
@@ -18,6 +18,50 @@ document.addEventListener('DOMContentLoaded', function () {
});
document.getElementById('_replyto').value = document.getElementById('client_email').value;
document.getElementById('btnReset').addEventListener('click', function () {
if (!confirm('Очистить всю форму? Это действие нельзя отменить.')) return;
document.getElementById('questionnaireForm').querySelectorAll('input[type="radio"], input[type="checkbox"]').forEach(el => el.checked = false);
document.getElementById('questionnaireForm').querySelectorAll('textarea, input[type="text"], input[type="tel"], input[type="email"]').forEach(el => { if (!['client_name','client_email'].includes(el.id)) el.value = ''; });
document.querySelectorAll('.other-input').forEach(el => el.classList.remove('visible'));
updateProgress(); updatePreview();
showFlash('Форма очищена');
});
document.getElementById('btnSave').addEventListener('click', function () {
updateURL(); showFlash('Сохранено!');
document.getElementById('saveStatus').textContent = 'Сохранено ' + formatTime();
});
document.getElementById('btnShare').addEventListener('click', function () {
updateURL();
const url = window.location.href;
if (navigator.clipboard) {
navigator.clipboard.writeText(url).then(() => showFlash('Ссылка скопирована!'));
} else {
const ta = document.createElement('textarea');
ta.value = url; ta.style.position = 'fixed'; ta.style.opacity = '0';
document.body.appendChild(ta); ta.select(); document.execCommand('copy');
document.body.removeChild(ta); showFlash('Ссылка скопирована!');
}
});
// Модальное окно
const generalForm = document.getElementById('generalForm');
if (generalForm) {
generalForm.addEventListener('submit', async function (e) {
e.preventDefault();
const btn = document.getElementById('generalSubmitBtn');
btn.disabled = true; btn.textContent = 'Отправляем...';
document.getElementById('general_replyto').value = document.getElementById('g_email').value;
try {
const res = await fetch(generalForm.action, { method: 'POST', body: new FormData(generalForm), headers: { 'Accept': 'application/json' } });
if (res.ok) { generalForm.style.display = 'none'; document.getElementById('modalSuccess').style.display = 'block'; }
else throw new Error();
} catch { btn.disabled = false; btn.textContent = 'Отправить обращение'; showFlash('Ошибка. Попробуйте ещё раз.'); }
});
}
document.addEventListener('keydown', e => { if (e.key === 'Escape') closeModal(); });
document.getElementById('questionnaireForm').addEventListener('change', function () {
updateProgress();
updatePreview();
@@ -169,6 +213,37 @@ function escapeHtml(str) {
return str.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
}
function updateURL() {
const data = {};
document.querySelectorAll('input[type="radio"]:checked, input[type="checkbox"]:checked').forEach(el => {
if (!data[el.name]) data[el.name] = [];
data[el.name].push(el.value);
});
const b64 = btoa(unescape(encodeURIComponent(JSON.stringify(data))));
const url = new URL(window.location.href);
url.searchParams.set('d', b64);
window.history.replaceState(null, '', url.toString());
}
function formatTime() {
const d = new Date();
return d.getHours().toString().padStart(2,'0') + ':' + d.getMinutes().toString().padStart(2,'0');
}
function openModal() {
document.getElementById('modalOverlay').classList.add('open');
document.body.style.overflow = 'hidden';
}
function closeModal() {
document.getElementById('modalOverlay').classList.remove('open');
document.body.style.overflow = '';
}
function closeModalOutside(e) {
if (e.target === document.getElementById('modalOverlay')) closeModal();
}
function showFlash(msg) {
const el = document.getElementById('flash');
el.textContent = msg;