EventBuzz_Backend/microsite-v2-templates/crest-novel/assets/js/contact-form.js

305 lines
8.5 KiB
JavaScript

(function () {
'use strict';
var formEl = null;
var captchaToken = '';
var captchaQuestionEl = null;
var captchaInputEl = null;
var captchaReloadBtn = null;
var submitBtn = null;
var msgEl = null;
var currentConfig = null;
var localCaptchaAnswer = null;
var captchaMode = 'server';
var fieldMap = {
name: 'Name',
email: 'Email',
subject: 'Subject',
message: 'Message'
};
function apiBase(config) {
var base = (config && config.apiBaseUrl) || '';
return String(base).replace(/\/+$/, '');
}
function parseJsonResponse(response) {
return response.text().then(function (text) {
var body = null;
try {
body = JSON.parse(text);
} catch (error) {
body = null;
}
if (!response.ok) {
var message = (body && body.error && body.error.message) || text || 'Request failed';
throw new Error(message);
}
return body;
});
}
function showMessage(message, isError) {
if (!msgEl) {
return;
}
msgEl.classList.remove('hidden', 'text-success', 'text-danger');
msgEl.classList.add(isError ? 'text-danger' : 'text-success');
msgEl.textContent = message;
}
function setSubmitting(isSubmitting) {
if (submitBtn) {
submitBtn.disabled = isSubmitting;
}
if (captchaInputEl) {
captchaInputEl.disabled = isSubmitting;
}
if (captchaReloadBtn) {
captchaReloadBtn.disabled = isSubmitting;
}
}
function loadLocalCaptcha() {
var a = Math.floor(Math.random() * 9) + 1;
var b = Math.floor(Math.random() * 9) + 1;
captchaMode = 'local';
captchaToken = '';
localCaptchaAnswer = String(a + b);
if (captchaQuestionEl) {
captchaQuestionEl.textContent = a + ' + ' + b + ' = ?';
}
if (captchaInputEl) {
captchaInputEl.value = '';
}
}
function loadCaptcha() {
var base = apiBase(currentConfig);
if (!base) {
loadLocalCaptcha();
return Promise.resolve();
}
if (captchaQuestionEl) {
captchaQuestionEl.textContent = 'Loading…';
}
return fetch(base + '/public/captcha/challenge', { cache: 'no-store' })
.then(parseJsonResponse)
.then(function (body) {
var data = body && body.data ? body.data : body;
captchaMode = 'server';
localCaptchaAnswer = null;
captchaToken = (data && data.captchaToken) || '';
if (!captchaToken) {
loadLocalCaptcha();
return;
}
if (captchaQuestionEl) {
captchaQuestionEl.textContent = (data && data.question) || 'Loading…';
}
if (captchaInputEl) {
captchaInputEl.value = '';
}
})
.catch(function () {
loadLocalCaptcha();
});
}
function applyFieldMapFromDefinition(formDefinition) {
var fields = (formDefinition && formDefinition.fields) || [];
fields.forEach(function (field) {
if (!field || !field.label) {
return;
}
var label = String(field.label).trim();
var lower = label.toLowerCase();
if (lower === 'name' || lower.indexOf('name') >= 0) {
fieldMap.name = label;
} else if (field.type === 'email' || lower === 'email') {
fieldMap.email = label;
} else if (lower === 'subject') {
fieldMap.subject = label;
} else if (field.type === 'textarea' || lower === 'message') {
fieldMap.message = label;
}
});
}
function loadFormDefinition(config, eventId) {
var base = apiBase(config);
var formId = config && config.formId;
if (!base || !formId || !eventId) {
return Promise.resolve(null);
}
return fetch(base + '/public/events/' + encodeURIComponent(eventId) + '/forms/' + encodeURIComponent(formId), {
cache: 'no-store'
})
.then(parseJsonResponse)
.then(function (body) {
return (body && body.data) || body;
})
.catch(function () {
return null;
});
}
function buildSubmitPayload() {
var data = {};
var nameInput = formEl.querySelector('[data-contact-field="name"]');
var emailInput = formEl.querySelector('[data-contact-field="email"]');
var subjectInput = formEl.querySelector('[data-contact-field="subject"]');
var messageInput = formEl.querySelector('[data-contact-field="message"]');
data[fieldMap.name] = nameInput ? String(nameInput.value || '').trim() : '';
data[fieldMap.email] = emailInput ? String(emailInput.value || '').trim() : '';
data[fieldMap.subject] = subjectInput ? String(subjectInput.value || '').trim() : '';
data[fieldMap.message] = messageInput ? String(messageInput.value || '').trim() : '';
var payload = {
data: data,
_gotcha: formEl.querySelector('[name="_gotcha"]') ? formEl.querySelector('[name="_gotcha"]').value : ''
};
if (captchaMode === 'server' && captchaToken) {
payload.captchaToken = captchaToken;
payload.captchaAnswer = captchaInputEl ? String(captchaInputEl.value || '').trim() : '';
}
return payload;
}
function validatePayload(payload) {
if (!payload.data[fieldMap.name]) {
return 'Please enter your name.';
}
if (!payload.data[fieldMap.email]) {
return 'Please enter your email.';
}
var captchaAnswer = captchaInputEl ? String(captchaInputEl.value || '').trim() : '';
if (!captchaAnswer) {
return 'Please solve the captcha.';
}
if (captchaMode === 'local' && captchaAnswer !== localCaptchaAnswer) {
return 'Incorrect captcha answer. Please try again.';
}
return '';
}
function handleSubmit(event) {
event.preventDefault();
if (!currentConfig || !currentConfig.formId) {
showMessage('Contact form is not configured.', true);
return;
}
var base = apiBase(currentConfig);
if (!base) {
showMessage('Contact form API is not configured.', true);
return;
}
var payload = buildSubmitPayload();
var validationError = validatePayload(payload);
if (validationError) {
showMessage(validationError, true);
formEl.classList.add('shake', 'animated');
window.setTimeout(function () {
formEl.classList.remove('shake', 'animated');
}, 650);
return;
}
setSubmitting(true);
showMessage('Sending…', false);
fetch(base + '/forms/' + encodeURIComponent(currentConfig.formId) + '/submit', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
})
.then(parseJsonResponse)
.then(function () {
var thankYou = (currentConfig && currentConfig.thankYouMessage)
|| 'Thank you for contacting us, we will get back to you shortly!';
formEl.reset();
showMessage(thankYou, false);
return loadCaptcha();
})
.catch(function (error) {
showMessage(error.message || 'Could not send your message. Please try again.', true);
return loadCaptcha();
})
.finally(function () {
setSubmitting(false);
});
}
function bindForm() {
if (!formEl || formEl.getAttribute('data-contact-bound') === 'true') {
return;
}
formEl.setAttribute('data-contact-bound', 'true');
captchaQuestionEl = formEl.querySelector('[data-contact-captcha-question]');
captchaInputEl = formEl.querySelector('[data-contact-captcha-answer]');
captchaReloadBtn = formEl.querySelector('[data-contact-captcha-reload]');
submitBtn = formEl.querySelector('[type="submit"]');
msgEl = document.getElementById('msgSubmit');
if (captchaReloadBtn) {
captchaReloadBtn.addEventListener('click', function (event) {
event.preventDefault();
loadCaptcha();
});
}
formEl.addEventListener('submit', handleSubmit);
}
function init(contactConfig, siteConfig) {
currentConfig = contactConfig || {};
formEl = document.getElementById('contactForm');
if (!formEl || contactConfig.show === false) {
return;
}
var eventId = (siteConfig && siteConfig.meta && siteConfig.meta.eventId) || contactConfig.eventId || '';
formEl.setAttribute('data-event-id', eventId);
formEl.setAttribute('data-form-id', currentConfig.formId || '');
bindForm();
loadFormDefinition(currentConfig, eventId).then(function (definition) {
if (definition) {
applyFieldMapFromDefinition(definition);
if (definition.settings && definition.settings.thankYouMessage) {
currentConfig.thankYouMessage = definition.settings.thankYouMessage;
}
}
return loadCaptcha();
});
}
window.EventUpContactForm = {
init: init
};
})();