Hello,
I'm working on some form validation in marketo. The current setup is a webhook connected to an external email validation service. On form submit, marketo launches the webhook and stores the email status (valid, invalid, accept all, etc.) in a custom field. This works well on post-submit, however we are looking to introduce some validation prior to the form being submitted as well. This way, we prevent invalid emails from ever entering the database, plus potential leads entering invalid emails have the opportunity to re-enter valid ones. Regex or other kinds of format detection don't always work reliably so I want to avoid using those methods if possible.
When testing the webhook, we found the response time is almost instantaneous, which is why I was wondering if there is a way to launch the webhook when someone attempts to submit the form, then have a short wait step, and then only successfully submit the form if the webhook returns the email status as 'valid'. Any advice is greatly appreciated!
This works well on post-submit, however we are looking to introduce some validation prior to the form being submitted as well. This way, we prevent invalid emails from ever entering the database, plus potential leads entering invalid emails have the opportunity to re-enter valid ones.
As long as people don’t deliberately skip JS validation, yes, this is certainly possible.
I wouldn’t call this a “webhook” however — it ceases to be a webhook if you connect to the service from a browser. A webhook is by definition a server-to-server callout. In the browser, it’s simply an XMLHttpRequest/Fetch call to an external service.
When testing the webhook, we found the response time is almost instantaneous,
Yes, if you get an immediate positive/negative validation result from the remote service, that can be pre-processed in the browser before the form submits.
There’s also a 3rd kind of result, when the connection from the validator service to the remote mailserver is greylisted and would need to retry after a period. That can’t be done on the client side. You’d likely allow the form submit to continue, even though you don’t know one way or the other yet, and retry via Call Webhook from the server side.
if there is a way to launch the webhook when someone attempts to submit the form, then have a short wait step, and then only successfully submit the form if the webhook returns the email status as 'valid'. Any advice is greatly appreciated!
Not sure what any extra wait/pause would be for? You‘d just call the the remote service via XHR/Fetch and get the result. The Marketo Forms JS API has all the hooks you need to perform a remote call and wait for a result before allowing the form to submit.
isn't there also a risk that a service of that nature might have an authentication key that you are exposing client side?
Cheers
Jo
@adaydan1 please return to your thread to check responses.
Hi Sanford, thanks for the quick response and apologies for my delayed one. Following your advice, I worked on some code using forms 2.0, but I've run into a few issues. I've been learning javascript as I go with this project so this code is an amalgam of the documentation for the vendor we're using as well as the marketo forms 2.0 documentation. I'm using a fetch call to the service, then parsing the email status from the response. Prior to making the call, I am excluding obvious invalid emails ('@gmai.com') as well as null email addresses.
I'm still having issues with the code, particularily with submitting the form when the email address is verified as 'valid'. If I set form.submittable(false); at the beginning of the function, the form doesn't submit, even if the status returns as valid. Additionally, if I put a form.submit(); into the code on a valid email submission, I am seeing the fetch call fire multiple times before throwing the error.
I would appreciate any advice you can provide.
<div>
<script src="//******.marketo.com/js/forms2/js/forms2.min.js"></script>
</div>
<form id="mktoForm_*****"></form>
<div>
<script>
MktoForms2.loadForm("//app-****.marketo.com", "*******", ****, function(form) {
form.onValidate(function(){
form.submittable(false);
var vals = form.vals();
const conditionsArray = [
vals.Email.indexOf("@gmail1.com") >= 0,
vals.Email.indexOf("@gmai.com") >= 0,
vals.Email.indexOf("@gmeil.com") >= 0
]
if (conditionsArray.indexOf(true) === -1 && String(vals.Email) !== ''){
var myHeaders = new Headers();
myHeaders.append("Content-Type", "application/json");
myHeaders.append("Authorization", "ApiKey: ******");
var raw = JSON.stringify({
"email": String(vals.Email)
});
var requestOptions = {
method: 'POST',
headers: myHeaders,
body: raw,
redirect: 'follow'
};
//creates a fetch call
fetch("*********************", requestOptions)
.then(response => response.json()) //converts the response to json
.then(data => data.email.status) //parses the email validity from the response
.then(function(status){ //accepts or rejects the form submission based on the status of the email
if (status == 'invalid'){
var emailElem = form.getFormElem().find("#Email");
form.showErrorMessage("The status is invalid, please enter a valid email", emailElem);
}
else if (status !== ''){
form.submittable(true);
form.submit();
console.log('not invalid');
}
else{
console.log('error')
}
})
.catch(function(error){
var emailElem = form.getFormElem().find("#Email");
form.showErrorMessage("There is an error with the server", emailElem);
});
}
else{
var emailElem = form.getFormElem().find("#Email");
form.showErrorMessage("The status is invalid, please enter a valid email", emailElem);
}
});
});
</script>
</div>
I'm going to let @SanfordWhiteman dig into the code for you, but one thing that he'll ask of you (so I'll save him the trouble) is that paste your code in using the syntax highlighter.
To do that, you need to expand the toolbar:
Then
It makes it so much easier to read!
Cheers
Jo
Hi Jo,
Thanks a ton! I'm new to posting on here so kind of still learning the right way to do things.
Best Regards,
Daniel
All good @adaydan1 .... we were all novices once 🙂