I am using a custom mailchimp form with various validators. One validation that is derailing my form is the duplicate email validation.
The problem I'm having occurs when someone tries to subscribe to the list with a duplicate email that is already subscribed.
Instead of just staying on the page with a validation message stating something like: "already subscribed" it instead redirects the user to the mailchimp owned landing page version of the form.
Here is the form page: https://www.silverlinkfunding.com/color-me-mine.html
Here is where it redirects you: https://silverlinkfunding.us17.list-manage.com/subscribe/post?u=459fcc96e094a6b4dbe3e69f8&id=4afd1b9608
If you would like to test the form yourself feel free to use: [email protected]
I was building the form using a guide from CSS tricks: https://css-tricks.com/form-validation-part-4-validating-mailchimp-subscribe-form/
Also, I don't know if this matters, but it's worth noting that this is being put on a weebly website using the embed code tool.
Here is my form code:
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
<style type="text/css">
.container-css {
background:#283184;
color: white;
clear:left;
width: 800px;
padding: 20px;
border-radius: 15px;
}
.form-text {
font-size: 19px;
}
.indicates-required{
margin-right: 20px;
}
.btn {
background-color: #339bff;
color: white;
margin-top: 10px;
}
.asterisk {
color: red;
}
.error-message {
color: red;
margin-top: 3px;
}
@media only screen
and (min-device-width: 320px)
and (max-device-width: 480px)
and (-webkit-min-device-pixel-ratio: 2)
and (orientation: portrait) {
.container-css {
width: 300px;
}
}
</style>
<div class="container container-css">
<form action="https://silverlinkfunding.us17.list-manage.com/subscribe/post?u=459fcc96e094a6b4dbe3e69f8&id=4afd1b9608" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" class="validate" target="_blank">
<div class="row d-flex justify-content-center">
<h2 class=>Apply Now</h2>
</div>
<div class="row d-flex justify-content-end">
<div class="indicates-required"><span class="asterisk">*</span> indicates required</div>
</div>
<!-- Name Row -->
<div class="row form-group">
<div class="col-sm-6">
<div class="row">
<div class="col-sm-12">
<label class="form-text" for="mce-FNAME">
<i class="fas fa-address-book"></i> First Name
<span class="asterisk">*</span></label>
<input class="form-control" type="text" name="FNAME" id="mce-FNAME" required>
</div>
</div>
</div>
<div class="col-sm-6">
<div class="row">
<div class="col-sm-12">
<label class="form-text" for="mce-LNAME">Last Name <span class="asterisk">*</span></label>
<input class="form-control" type="text" name="LNAME" id="mce-LNAME" required>
</div>
</div>
</div>
</div>
<!-- Email Row -->
<div class="row form-group">
<div class="col-sm-12">
<div class="row">
<div class="col-sm-12">
<label class="form-text" for="mce-EMAIL"><i class="fas fa-envelope"></i> Email Address
<span class="asterisk">*</span></label>
<input class="form-control" type="email" name="EMAIL" id="mce-EMAIL" title="The domain portion of the email address is invalid (the portion after the @)." pattern="^([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x22([^\x0d\x22\x5c\x80-\xff]|\x5c[\x00-\x7f])*\x22))*\x40([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d)(\x2e([^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+|\x5b([^\x0d\x5b-\x5d\x80-\xff]|\x5c[\x00-\x7f])*\x5d))*(\.\w{2,})+$" required>
</div>
</div>
</div>
</div>
<!-- Phone Row -->
<div class="row form-group">
<div class="col-sm-12">
<div class="row">
<div class="col-sm-12">
<label class="form-text" for="mce-MMERGE3"><i class="fas fa-phone"></i> Phone
<span class="asterisk">*</span></label>
<input class="form-control" type="tel" name="MMERGE3" id="mce-MMERGE3" required>
</div>
</div>
</div>
</div>
<!-- Business, City, State Row -->
<div class="row form-group">
<div class="col-sm-12">
<div class="row">
<div class="col-sm-6">
<label class="form-text" for="mce-MMERGE4"><i class="fas fa-briefcase"></i> Business Name
<span class="asterisk">*</span></label>
<input class="form-control" type="text" name="MMERGE4" id="mce-MMERGE4" required>
</div>
<div class="col-sm-4">
<label class="form-text" for="mce-MMERGE5">City <span class="asterisk">*</span></label>
<input class="form-control" type="text" name="MMERGE5" id="mce-MMERGE5" required>
</div>
<div class="col-sm-2">
<label class="form-text" for="mce-MMERGE9">State <span class="asterisk">*</span></label>
<input class="form-control" type="text" name="MMERGE9" id="mce-MMERGE9" required>
</div>
</div>
</div>
</div>
<!-- Loan Row -->
<div class="row form-group">
<div class="col-sm-12">
<div class="row">
<div class="col-sm-6">
<label class="form-text" for="mce-MMERGE7"><i class="fas fa-money-bill-alt"></i> Loan Amount Requested
<span class="asterisk">*</span></label>
<input class="form-control" type="text" name="MMERGE7" id="mce-MMERGE7" required>
</div>
<div class="col-sm-6">
<label class="form-text" for="mce-MMERGE8">Cash Available For Investment <span class="asterisk">*</span></label>
<input class="form-control" type="text" name="MMERGE8" id="mce-MMERGE8" required>
</div>
</div>
</div>
</div>
<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
<div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="b_459fcc96e094a6b4dbe3e69f8_4afd1b9608" tabindex="-1" value=""></div>
<div class="clear d-flex justify-content-center"><input type="submit" value="Apply Now" name="subscribe" id="mc-embedded-subscribe" class="button btn"></div>
</form>
</div>
<!-- JS -->
<script>
// Add the novalidate attribute when the JS loads
var forms = document.querySelectorAll('.validate');
for (var i = 0; i < forms.length; i++) {
forms[i].setAttribute('novalidate', true);
}
// Validate the field
var hasError = function (field) {
// Don't validate submits, buttons, file and reset inputs, and disabled fields
if (field.disabled || field.type === 'file' || field.type === 'reset' || field.type === 'submit' || field.type === 'button') return;
// Get validity
var validity = field.validity;
// If valid, return null
if (validity.valid) return;
// If field is required and empty
if (validity.valueMissing) return 'Please fill out this field.';
// If not the right type
if (validity.typeMismatch) {
// Email
if (field.type === 'email') return 'Please enter an email address.';
// URL
if (field.type === 'url') return 'Please enter a URL.';
}
// If too short
if (validity.tooShort) return 'Please lengthen this text to ' + field.getAttribute('minLength') + ' characters or more. You are currently using ' + field.value.length + ' characters.';
// If too long
if (validity.tooLong) return 'Please shorten this text to no more than ' + field.getAttribute('maxLength') + ' characters. You are currently using ' + field.value.length + ' characters.';
// If pattern doesn't match
if (validity.patternMismatch) {
// If pattern info is included, return custom error
if (field.hasAttribute('title')) return field.getAttribute('title');
// Otherwise, generic error
return 'Please match the requested format.';
}
// If number input isn't a number
if (validity.badInput) return 'Please enter a number.';
// If a number value doesn't match the step interval
if (validity.stepMismatch) return 'Please select a valid value.';
// If a number field is over the max
if (validity.rangeOverflow) return 'Please select a value that is no more than ' + field.getAttribute('max') + '.';
// If a number field is below the min
if (validity.rangeUnderflow) return 'Please select a value that is no less than ' + field.getAttribute('min') + '.';
// If all else fails, return a generic catchall error
return 'The value you entered for this field is invalid.';
};
// Show an error message
var showError = function (field, error) {
// Add error class to field
field.classList.add('error');
// If the field is a radio button and part of a group, error all and get the last item in the group
if (field.type === 'radio' && field.name) {
var group = field.form.querySelectorAll('[name="' + field.name + '"]');
if (group.length > 0) {
for (var i = 0; i < group.length; i++) {
group[i].classList.add('error');
}
field = group[group.length - 1];
}
}
// Get field id or name
var id = field.id || field.name;
if (!id) return;
// Check if error message field already exists
// If not, create one
var message = field.form.querySelector('.error-message#error-for-' + id );
if (!message) {
message = document.createElement('div');
message.className = 'error-message';
message.id = 'error-for-' + id;
// If the field is a radio button or checkbox, insert error after the label
var label;
if (field.type === 'radio' || field.type ==='checkbox') {
label = field.form.querySelector('label[for="' + id + '"]') || field.parentNode;
if (label) {
label.parentNode.insertBefore( message, label.nextSibling );
}
}
// Otherwise, insert it after the field
if (!label) {
field.parentNode.insertBefore( message, field.nextSibling );
}
}
// Add ARIA role to the field
field.setAttribute('aria-describedby', 'error-for-' + id);
// Update error message
message.innerHTML = error;
// Show error message
message.style.display = 'block';
message.style.visibility = 'visible';
};
// Remove the error message
var removeError = function (field) {
// Remove error class to field
field.classList.remove('error');
// Remove ARIA role from the field
field.removeAttribute('aria-describedby');
// If the field is a radio button and part of a group, remove error from all and get the last item in the group
if (field.type === 'radio' && field.name) {
var group = field.form.querySelectorAll('[name="' + field.name + '"]');
if (group.length > 0) {
for (var i = 0; i < group.length; i++) {
group[i].classList.remove('error');
}
field = group[group.length - 1];
}
}
// Get field id or name
var id = field.id || field.name;
if (!id) return;
// Check if an error message is in the DOM
var message = field.form.querySelector('.error-message#error-for-' + id + '');
if (!message) return;
// If so, hide it
message.innerHTML = '';
message.style.display = 'none';
message.style.visibility = 'hidden';
};
// Listen to all blur events
document.addEventListener('blur', function (event) {
// Only run if the field is in a form to be validated
if (!event.target.form.classList.contains('validate')) return;
// Validate the field
var error = hasError(event.target);
// If there's an error, show it
if (error) {
showError(event.target, error);
return;
}
// Otherwise, remove any existing error message
removeError(event.target);
}, true);
// Check all fields on submit
document.addEventListener('submit', function (event) {
// Only run on forms flagged for validation
if (!event.target.classList.contains('validate')) return;
// Get all of the form elements
var fields = event.target.elements;
// Validate each field
// Store the first field with an error to a variable so we can bring it into focus later
var error, hasErrors;
for (var i = 0; i < fields.length; i++) {
error = hasError(fields[i]);
if (error) {
showError(fields[i], error);
if (!hasErrors) {
hasErrors = fields[i];
}
}
}
// If there are errrors, don't submit form and focus on first element with error
if (hasErrors) {
event.preventDefault();
hasErrors.focus();
}
// Otherwise, let the form submit normally
// You could also bolt in an Ajax form submit process here
}, false);
</script>
So my overall question is:
How can I keep duplicate email validation to the same page?
How do I prevent the duplicate email validation from redirecting to the mailchimp domain page?
Thanks for the assistance!