Last active
August 29, 2015 14:17
-
-
Save shiftyp/06ea2bf7bcd61ced7e11 to your computer and use it in GitHub Desktop.
Form Validation Example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Form Validation</title> | |
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet"> | |
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js" type="text/javascript"></script><script src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.3.2/js/bootstrap.min.js" type="text/javascript"></script> | |
<script src="./index.js" type="text/javascript"></script> | |
</head> | |
<body> | |
<div class="container"> | |
<div class="row"> | |
<div class="col-md-12"> | |
<h1>Form With Validation</h1> | |
<form class="form"> | |
<div class="form-group"> | |
<label for="name">Name</label> | |
<input id="name" name="name" type="text" class="form-control"></input> | |
</div> | |
<div class="form-group"> | |
<label for="email">Email</label> | |
<input id="email" name="email" type="text" class="form-control"></input> | |
</div> | |
<div class="form-group"> | |
<label for="message">Message</label> | |
<textarea id="message" name="message" class="form-control"></textarea> | |
</div> | |
<div class="form-group"> | |
<button class="btn btn-primary" type="submit">Send us a message!</button> | |
</div> | |
</form> | |
</div> | |
</div> | |
</div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// I put all the messages here so that they can be easily edited in one place. | |
// You could also imagine these messages not being hardcoded, and coming from | |
// somewhere else so they could be localized to the users language. | |
var messages = { | |
'success': 'Thanks for your interest. We\'ll respond within two business days.', | |
'name': 'You must put your full name. We\'ll be happy to make your acquaintance.', | |
'email': 'You must put a valid email address. We\'ll definitely be in touch.', | |
'message': 'Please put a description of your issue. We\'d love to hear from you!' | |
}; | |
// I also put the validation rules in an object. Again this puts them in one place | |
// making them easy to edit. Putting a `!` before any value converts it to a boolean | |
// which is true if the value is falsey. Putting `!!` is an easy way to convert | |
// truthy and falsey values to their boolean equivilents. It's not super neccessary, | |
// but I'd like the rules to always return true and false instead of truthy and | |
// falsey values like objects and numbers. This is more accurate for what we're trying | |
// to do, and may prevent wierd errors in the future. | |
var rules = { | |
// This checks that the name has some length, and that there is a space indicating | |
// that it's a full name. | |
'name': function(val) { return !!val.length && val.indexOf(' ') !== -1; }, | |
// We also check the email length, and additionally check it against a regular expression | |
// (the stuff between the forward slashes passed to `match`). Emails are sort of difficult | |
// to validate against a regular expression, so this is somewhat simplistic and will fail in | |
// some instances. Here is an in depth article on the subject: http://www.regular-expressions.info/email.html | |
'email': function(val) { return !!val.length && !!val.match(/[A-Z0-9]+@[A-Z0-9]+\.[A-Z]{2,4}/i); }, | |
'message': function(val) { return !!val.length; } | |
}; | |
// Here is the form submit callback. | |
function validateForm(e) { | |
// The target of the event is the form. `this` also is the form DOM element, so | |
// we could do $(this) instead. | |
var form = $(e.target); | |
// A boolean flag to store the validation state of the form | |
var valid = true; | |
// Remove any existing alerts from the form and reset the validation states | |
// on the form groups. These classes are specific to Bootstrap, so if you | |
// are using something else you'll have different classes and styles. | |
form.find('.alert').remove(); | |
form.find('.form-group').removeClass('has-error'); | |
// I put the ids of the different elements in an array and loop over them. | |
// This helps with consolidating the code a bit since I can use the same | |
// callback function to check all the elements. | |
['name', 'email', 'message'].forEach(function(id) { | |
// Get the element to check. | |
var el = form.find('#' + id); | |
// We start with an empty validation error. If this has | |
// a length later we display the alert with the approprate | |
// message. | |
var validationError = ''; | |
// Even though we're looping over the ids, each one has a different | |
// validation rule and a different message. Because we have the | |
// rules and the messages in an object with the id as a key, we | |
// can access them like so instead of having to write out a switch | |
// or an if/else statement. Pretty slick. | |
if (!rules[id](el.val())) { | |
validationError = messages[id]; | |
valid = false; | |
} | |
// If we have a validation error | |
if (validationError.length) { | |
// Again, these classes are bootstrap specific, but you could do whatever | |
// you want here to display the appropriate message. | |
el.before('<div class="alert alert-danger">' + validationError + '</div>'); | |
el.parent().addClass('has-error'); | |
} else { | |
// Otherwise we add the bootstrap success class to the element's parant (the | |
// form group) to indicate that the form is valid. | |
el.parent().addClass('has-success'); | |
} | |
}); | |
if (valid) { | |
// After we've processed all the fields and if the form is valid we display | |
// a success message. If the form submitted to an endpoint in the normal way, | |
// you wouldn't see this message because a new page will be loaded using the | |
// response for posting to the endpoint. If we do an ajax request however to | |
// post the form data, the page won't reload and we'll see this message. | |
form.prepend('<div class="alert alert-success">' + messages.success + '</div>'); | |
} | |
// If you actually wanted the form to submit you'd return true. I have it return | |
// false since the form doesn't have an endpoint to submit to. Alternatively, you | |
// could return false and send the form data using an ajax post if you wanted the | |
// user to stay on the current page. | |
return false; | |
} | |
// We can define all of our stuff outside of the dom ready handler, but we need | |
// to attach the listener for submit on the form after the dom is loaded, otherwise | |
// the form won't exist and you'll be like "Why isn't it working?". So we create | |
// a dom ready listener in the usual jQuery way and attach our submit handler in it. | |
$(function() { | |
$('form').on('submit', validateForm) | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment