/*
validates the email field, show and hides error message, enables and disables signup button
Angular 1.2 doesn't support touched and untouched states so we have to do this ourselves
*/
!function () {
function trackOfferCheckboxChanged(checked) {
if (checked) {
window.parent.postMessage({ name: 'offer-checkbox-checked', newsletter: 'receiveInsideWashingtonNews' }, '*');
} else {
window.parent.postMessage({ name: 'offer-checkbox-unchecked', newsletter: 'receiveInsideWashingtonNews' }, '*');
}
}
const errors = {
unknown_error: 'An unknown problem occurred. Please try again later.',
email_validation_error: 'Please enter a valid email address',
existing_email_error: 'Your email is already signed up to this newsletter',
};
function validateEmail(email) {
const EMAIL_REGEX = /^(?=(.{1,64}@.{1,255}))([!#$%&'*+\-\/=?\^_`{|}~a-zA-Z0-9}]{1,64}(\.[!#$%&'*+\-\/=?\^_`{|}~a-zA-Z0-9]{0,}){0,})@((\[(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}\])|([a-zA-Z0-9-]{1,63}(\.[a-zA-Z0-9-]{2,63}){1,}))$/;
return EMAIL_REGEX.test(email);
}
const formState = {
inputField: {
dirty: false,
touched: false,
valid: false,
},
errorMessage: errors.email_validation_error,
};
const emailInput = document.getElementById('email-input');
const errorMessageField = document.getElementById('error-message');
const submitButton = document.getElementById('submit-button');
const offerCheckbox = document.getElementById('offers');
offerCheckbox.addEventListener('change', (event) => {
trackOfferCheckboxChanged(event.target.checked);
});
function updateInputView() {
if (formState.inputField.dirty) {
emailInput.classList.add('dirty');
} else {
emailInput.classList.remove('dirty');
}
if (formState.inputField.valid) {
emailInput.classList.add('valid');
emailInput.classList.remove('invalid');
} else {
formState.errorMessage = errors.email_validation_error;
emailInput.classList.add('invalid');
emailInput.classList.remove('valid');
}
// can only be touched once
if (formState.inputField.touched) {
emailInput.classList.add('touched');
}
}
function updateErrorMessageView() {
if (!formState.inputField.valid
&& formState.inputField.touched
&& formState.inputField.dirty) {
errorMessageField.style.opacity = 1;
errorMessageField.textContent = formState.errorMessage;
} else {
errorMessageField.style.opacity = 0;
}
}
function updateSubmitButton() {
if (formState.inputField.valid) {
submitButton.disabled = false;
} else {
submitButton.disabled = true;
}
}
function setLogoBackground(newsletter) {
const logoBackground = document.getElementById('logo-background');
if (newsletter === 'receiveClimate' || newsletter === 'receiveClimateWarriors') {
logoBackground.setAttribute('fill', 'url(#paint0_linear)');
} else {
logoBackground.setAttribute('fill', '#e30d24');
}
}
function hideLogo() {
const logo = document.getElementById('logo');
let isSmallScreen = window.visualViewport.width < 621;
if ('receiveInsideWashingtonNews' == 'receiveIndyBreakingNews' && !isSmallScreen) {
logo.setAttribute('visibility', 'hidden');
} else {
logo.setAttribute('visibility', 'visible');
}
}
setLogoBackground('receiveInsideWashingtonNews');
hideLogo('receiveInsideWashingtonNews');
function updateView() {
updateErrorMessageView();
updateInputView()
updateSubmitButton();
}
// call this to render the initial state
updateView();
emailInput.addEventListener('blur', () => {
formState.inputField.touched = true;
updateView();
});
emailInput.addEventListener('change', () => {
formState.inputField.dirty = true;
updateView();
});
emailInput.addEventListener('input', () => {
formState.inputField.valid = validateEmail(event.target.value);
updateView();
});
function queryAll(items) {
return items
.map(id => document.getElementById(id))
.filter(Boolean);
}
function onSuccess() {
const successPanel = document.getElementById('success-panel');
const itemsToHide = queryAll(['heading-desktop', 'heading-mobile', 'email-input', 'submit-button', 'error-message', 'offer']);
itemsToHide.forEach(item => {
item.addEventListener('transitionend', () => {
item.style.visibility = 'hidden';
});
item.style.transition = 'opacity 0.4s linear';
item.style.opacity = 0;
successPanel.style.visibility = 'visible';
successPanel.offsetHeight;
successPanel.style.opacity = 1;
});
}
function onError(errorKey) {
formState.inputField.valid = false;
formState.errorMessage = errors[errorKey] || errors.unknown_error;
updateView();
}
window.addEventListener('message', (event) => {
if (event.data && event.data.piano) {
const result = event.data.piano;
if (result.success) {
onSuccess();
} else {
onError(result.error);
}
}
});
window.addEventListener('resize', () => {
hideLogo()
});
}();