305 lines
8.5 KiB
JavaScript
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
|
|
};
|
|
})();
|