The issue lies with this if conditional: if ($.inArray(emailaddressVal,invalidEmailAddresses) > 0)
.
Since the $.inArray()
method returns the index of a string found, when a value of 0
is returned, it is actually found—but at the start of the string (position 0, because JS is zero-based). So, you should use !== -1
instead, i.e.: if ($.inArray(emailaddressVal,invalidEmailAddresses) !== -1)
.
However, this does not completely solve your issue — $.inArray()
only compares string, it does not search for it. Therefore if your string contains the blacklisted email domains, but does not match exactly, it will return false. In this case, you should use regular expression instead. The strategy is simple: use .each()
to loop through your array, and take the value, use it to construct an expression which we will test your email address that is provided against.
Also, since there is the possibility that the user-entered email address fails both tests, two <div>
of identical IDs will appear. This is invalid HTML. Instead, try using a class instead.
p/s: I also recommend changing listening to .blur()
to .change()
instead. It is more robust :)
With all the points above considered, I have refactored your code a little:
- Declare a global (but still within function scope) error array called
hasError
. It will be used to store all error messages you get, since we cannot be sure if there will be one, or more than one error.
- We construct two tests:
- To test if email matches against blacklist using the
string.search(regexp)
method. If there is a match, the value returned will exceed -1
. We then push the relevant error message into hasError
in an object
- To test if email contains the
@
sign, we use your default logic (which works beautifully). If there is an error, we push, again, the relevant error message into hasError
in an object
- At the end, we evaluate
hasError
. If it is not empty, then we know there is an error somewhere, and loop through it. The error messages are accessible via the messages
keyword :)
Without further ado, here's your code:
$(document).ready(function() {
$("input[name='emailAddress']").change(function() {
// Actual Email Validation function
var hasError = [],
emailaddressVal = $("input[name='emailAddress']").val(),
invalidEmailAddresses = ['godaddy.com', 'aol.com', 'yahoo.com', 'yahoo.fr'];
// Check against blacklist
$.each(invalidEmailAddresses, function(i, v) {
var pattern = new RegExp(v, 'i');
if (emailaddressVal.search(pattern) > -1) {
hasError.push({
'test': 'blacklist',
'message': 'The email provided is not from a business related domain. Please use an appropriate email address instead.'
});
}
});
// Check if there is an '@' character
if ($("input[name='emailAddress']").val().indexOf('@') === -1) {
hasError.push({
'test': '@ sign',
'message': 'The email provided does not contain an @ symbol'
});
}
console.log(hasError);
// Error handling
$('#error').remove();
if(hasError.length > 0) {
var $error = $('<div id="error"><ul></ul></div>');
$.each(hasError, function(i,v) {
$error.find('ul').append('<li>'+v.message+'</li>');
});
$error.insertAfter("input[name='emailAddress']");
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<input name="emailAddress" type="email" />
</form>