SOLVED

Re: Require Business Email Address on Forms

Go to solution
Trevor_Parsell
Level 6

Hello,

I found the script below in this discussion: How do I require a BUSINESS email

I pasted the script in my Marketo landing page template and tested the form with a Yahoo email address and it still is allowing me to submit the form. Where exactly should this script be placed to reject non-business email addresses for particular forms? Any help would be greatly appreciated.

<script>
(function (){
  // Please include the email domains you would like to block in this list
  var invalidDomains = ["@yahoo.","@hotmail.","@live.","@aol.","@msn.","@outlook."];
  MktoForms2.whenReady(function (form){
   form.onValidate(function(){
   var email = form.vals().Email;
   if(email){
   if(!isEmailGood(email)) {
   form.submitable(false);
   var emailElem = form.getFormElem().find("#Email");
   form.showErrorMessage("Must be Business email.", emailElem);
  }else{
   form.submitable(true);
  }
  }
  });
  });
  function isEmailGood(email) {
   for(var i=0; i < invalidDomains.length; i++) {
   var domain = invalidDomains[i];
   if (email.indexOf(domain) != -1) {
   return false;
  }
  }
   return true;
  }
})();
</script>



Thanks!

Trevor

1 ACCEPTED SOLUTION
SanfordWhiteman
Level 10 - Community Moderator

Lawdy, how I hate that code.

It should have barebones functionality, though.  Are you being sure to include it after the <script> that loads forms2.min.js? On a Marketo LP, you'll want to put this just inside the closing </body> tag (because Mkto may inject the forms2.min.js at any point in the body content).

View solution in original post

35 REPLIES 35
SanfordWhiteman
Level 10 - Community Moderator

Lawdy, how I hate that code.

It should have barebones functionality, though.  Are you being sure to include it after the <script> that loads forms2.min.js? On a Marketo LP, you'll want to put this just inside the closing </body> tag (because Mkto may inject the forms2.min.js at any point in the body content).

Trevor_Parsell
Level 6

Thanks, Sanford. I just needed to move it down the page and it is now working.

Do you hate the code because it prevents potentially good leads from filling out forms if they prefer to use a non-business email address? Are there other downsides?

Just curious as I am not a huge fan of doing this although there are some scenarios where it will be useful.

Thanks!

SanfordWhiteman
Level 10 - Community Moderator

It's not about the concept (it has its uses) but the implementation.

  • There are 1000s of free domains, but the code only (mis)identifies a few (the seminal list is the Freemail list).
  • The pattern matching is incorrect. If my email address is sandy@live.event24.com, that isn't a Microsoft domain; if my company sets up a domain for outlook users @outlook.college.edu, that isn't an Outlook 365 domain. The freemail providers don't actually own all the instances of their domain at all levels of the domain tree and under all TLDs!
  • The function name isEmailGood is frustrating, because it isn't validating the email as a whole.
Trevor_Parsell
Level 6

Hey Sanford,

I see what you mean. So would it make more sense to include the larger list of free email domains and to change the script to only block "@live.com" instead of "@live."

Example:  var invalidDomains = ["@yahoo.com","@hotmail.com","@live.com","@aol.com","@msn.com","@outlook.com"];

This should solve for the sandy@live.event24.com and @outlook.college.edu scenarios.

Thanks for your help!

SanfordWhiteman
Level 10 - Community Moderator

No, that'll still bug out should someone have a username like jill@outlook.comcorp.edu. The domains need to be firmly anchored to the right-hand-side of the email address.

Also, did I mention the original code is case-sensitive, so joe@YAHOO.COM is considered valid?  That's an even bigger problem than the rest, really.

This is a much tighter and more accurate function:

function inDomainList(email,domains){
return domains
.map(function(domain){
return new RegExp('@' + domain.replace('.','\\.') + '$','i');
})
.some(function(reDomain){
return reDomain.test(email);
});
}
‍‍‍‍‍‍‍‍‍

then pass the domain list to the function (this is better practice than requiring the domain list to be up-scope, not that I don't do that myself sometimes):

var freemailDomains = ["yahoo.com","hotmail.com","live.com","aol.com","msn.com","outlook.com"];
if ( inDomainList(email,freemailDomains) ) {
/* it's in the list of domains you don't like */
}
Brennan_McAdam2
Level 4

While I agree with your assessment in potentially missing good prospects, this solution matches some business requirements and while not absolute, certainly hits across a large segment.  

Brennan McAdams
Denise_Greenbe7
Level 3

Hey Sanford Whiteman‌ - I have a client that wants to require business email addresses for one specific form but the form is on their website - not on a Marketo LP. Would the code above work in that context, too? If so, where does it belong?

SanfordWhiteman
Level 10 - Community Moderator

Sure, it'll work fine with an embedded form as well. Make sure it's placed after the embed code -- custom Marketo forms behaviors require the global MktoForms2 object, and that object won't exist unless forms2.min.js has finished loading.

Denise_Greenbe7
Level 3

Sanford Whiteman‌ - I'm trying to get this code to work on a Marketo LP first - and it's having no effect. Is there other code that needs to go around the sample you provided that a developer (which, as you know, I'm not) would automatically be adding? I did put it the whole thing inside <script> </script> tags.

Denise_Greenbe7
Level 3

One more question - if we use this code, how do we get the form to provide an error message to the user? "Please provide a business email address."

Denise_Greenbe7
Level 3

Hey Sandy,

Can I copy and paste that code as is? Or when you say "then pass the domain list to the function...", is there more required than simply pasting the code that follows that sentence?

Thank you!

Denise

SanfordWhiteman
Level 10 - Community Moderator

To combine the original logic with the fixed validator function:

<script>
function inDomainList(email,domains){
return domains
.map(function(domain){
return new RegExp('@' + domain.replace('.','\\.') + '$','i');
})
.some(function(reDomain){
return reDomain.test(email);
});
}

MktoForms2.whenReady(function(form){

var freemailDomains = ["yahoo.com","hotmail.com","live.com","aol.com","msn.com","outlook.com","gmail.com"],
errorFreemail = "Must be Business email.";

/* no need to touch below this line */
var formEl = form.getFormElem()[0],
emailEl = formEl.querySelector("input[name='Email']"),
emailJq = MktoForms2.$(emailEl);

form.onValidate(function(native){
if (!native) return;

var currentValues = form.getValues(),
currentEmail = currentValues.Email;

if ( inDomainList(currentEmail, freemailDomains) ) {

form.submittable(false);
form.showErrorMessage(errorFreemail, emailJq);
} else {

form.submittable(true);
}
});
});
</script>‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
Trish_ITRenew
Level 1

I added this code to LP template at bottom above final </body> tag.

<script>
function inDomainList(email,domains){ return domains .map(function(domain){ return new RegExp('@' + domain.replace('.','\\.') + '$','i'); }) .some(function(reDomain){ return reDomain.test(email); });}MktoForms2.whenReady(function(form){ var freemailDomains = ["yahoo.com","hotmail.com","live.com","aol.com","msn.com","outlook.com","gmail.com"], errorFreemail = "Must be Business email."; /* no need to touch below this line */ var formEl = form.getFormElem()[0], emailEl = formEl.querySelector("input[name='Email']"), emailJq = MktoForms2.$(emailEl); form.onValidate(function(native){ if (!native) return; var currentValues = form.getValues(), currentEmail = currentValues.Email; if ( inDomainList(currentEmail, freemailDomains) ) { form.submittable(false); form.showErrorMessage(errorFreemail, emailJq); } else { form.submittable(true); } });});
</script>

 

I then loaded the free.txt file to design studio Images and files.  

 

The main ones are working and won't allow me to use on a form "yahoo.com","hotmail.com","live.com","aol.com","msn.com","outlook.com","gmail.com"

 

but if I  fill out form with one of the other domains on free.txt list (for example trish@1nsyncfan.com) it was accepted. 

 

So hmm, not sure what I am doing wrong. do I need to put .txt file in a specifically named folder for code to see it?

 

thanks!

Trish

SanfordWhiteman
Level 10 - Community Moderator
Hard to read your code with the line breaks taken out! But doesn't look like it's calling in the remote file at all. This is different code.
TrishVoskoSpear
Level 2

Hi Sandford,

OH - I misunderstood then!

 

I just copied and pasted what you put in this topic string in response to someone else about this code block;

 

"To combine the original logic with the fixed validator function:"

<script>function inDomainList(email,domains){  return domains    .map(function(domain){      return new RegExp('@' + domain.replace('.','\\.') + '$','i');    })    .some(function(reDomain){      return reDomain.test(email);    });}MktoForms2.whenReady(function(form){  var freemailDomains = ["yahoo.com","hotmail.com","live.com","aol.com","msn.com","outlook.com","gmail.com"],      errorFreemail = "Must be Business email.";  /* no need to touch below this line */  var formEl = form.getFormElem()[0],      emailEl = formEl.querySelector("input[name='Email']"),      emailJq = MktoForms2.$(emailEl);  form.onValidate(function(native){    if (!native) return;    var currentValues = form.getValues(),        currentEmail = currentValues.Email;    if ( inDomainList(currentEmail, freemailDomains) ) {      form.submittable(false);      form.showErrorMessage(errorFreemail, emailJq);    } else {      form.submittable(true);    }  });});</script>

 

and make sure the free.txt file is loaded into Design Studio.  I assumed code covered both issues. so i am missing the code to call the file- can you help with that and tell where also where to add to above code or does it completely replace?

 

As you can tell I am not a developer but learning to do a bit more. 

 

Trish

 

 

TrishVoskoSpear
Level 2

here it is a bit prettier:

TrishVoskoSpear_0-1613083398213.png

 

SanfordWhiteman
Level 10 - Community Moderator
If you just copy it from view-source and then paste it into the Insert/Edit Code Sample window, that's best.
Trish_ITRenew
Level 1

 

Hi @SanfordWhiteman   this code below is working on my LP templates but I would also like to figure out what code needs to be added to also not allow domains from the free.txt file. You mentioned that was different code. Do you add to this or is it completely different code?

 

<script>
function inDomainList(email, domains) {
return domains.map(function(domain) {
return new RegExp('@' + domain.replace('.', '\\.') + '$', 'i');
}).some(function(reDomain) {
return reDomain.test(email);
});
}
MktoForms2.whenReady(function(form) {
var freemailDomains = ["yahoo.com", "hotmail.com", "live.com", "aol.com", "msn.com", "outlook.com", "gmail.com"],
errorFreemail = "Must be Business email."; /* no need to touch below this line */
var formEl = form.getFormElem()[0],
emailEl = formEl.querySelector("input[name='Email']"),
emailJq = MktoForms2.$(emailEl);
form.onValidate(function(native) {
if(!native) return;
var currentValues = form.getValues(),
currentEmail = currentValues.Email;
if(inDomainList(currentEmail, freemailDomains)) {
form.submittable(false);
form.showErrorMessage(errorFreemail, emailJq);
} else {
form.submittable(true);
}
});
});
</script>

 

 

thanks!

Trish

SanfordWhiteman
Level 10 - Community Moderator

You can load the freemail.txt list into the builder I just created for this purpose: <textarea> to JS array builder

 

That'll give you a block of JS (in the bottom output pane). Copy and paste that into a JS file, exactly as-is, and upload it to your Design Studio. Include that script with a <script> tag, then you can refer to that large array as your freemail domains.

 

2021-02-16 17_43_42-CodePen - _textarea_ to JS array builder — Mozilla Firefox.png

 

TrishVoskoSpear
Level 2

@SanfordWhiteman 

 

Hi Sanford, 

 

This part is still confusing to me "Include that script with a <script> tag, then you can refer to that large array as your freemail domains." do you mean the URL of the .js file in Design studio so code would now be like this? I assume this is incorrect but in reading back through this topic string I a not sure what script you are referring to with "include that scriptp

 

sorry, there has been so much within this topic I have gotten a bit lost:)

 

 

script>
function inDomainList(email, domains) {
return domains.map(function(domain) {
return new RegExp('@' + domain.replace('.', '\\.') + '$', 'i');
}).some(function(reDomain) {
return reDomain.test(email);
});
}
MktoForms2.whenReady(function(form) {
var freemailDomains = ["yahoo.com", "hotmail.com", "live.com", "aol.com", "msn.com", "outlook.com", "gmail.com"],
errorFreemail = "Must be Business email."; /* no need to touch below this line */
var formEl = form.getFormElem()[0],
emailEl = formEl.querySelector("input[name='Email']"),
emailJq = MktoForms2.$(emailEl);
form.onValidate(function(native) {
if(!native) return;
var currentValues = form.getValues(),
currentEmail = currentValues.Email;
if(inDomainList(currentEmail, freemailDomains)) {
form.submittable(false);
form.showErrorMessage(errorFreemail, emailJq);
} else {
form.submittable(true);
}
});
});
</script>
<script>
https://info.lacework.com/rs/016-ATL-295/images/freetxt.js
</script>
</body>