Some Useful Tips And Tricks About Form Validation
Claudio Cortese
Posted on January 8, 2020
As time goes by, sooner or later, every developer has been tasked with building a form. ๐ ๏ธ
Well, as far as I'm concerned, that's not one of the funniest things to do. ๐
But it turns out that even the simpler of websites out there is going to need at least a basic contact form. ๐คทโโ๏ธ
And, sometimes, there are cases where you are building a really complex and big application with forms everywhere. ๐ค
They might be so big that you have to split them into multiple steps! ๐ฎ
But, in this post, I'm not going to show you a specific way of building a form nor how to split it into multiple steps, for example.
I'm going to try to be framework agnostic as well, but I might use a couple of lines of React
here and there, as that's what I mostly use day by day.
Anyway, I promise you that this will not retain you from using what I will show you in any other framework you might happen to use or even Vanilla JS!
Well, at this point you may be wondering what I'm precisely going to talk about, then? ๐ง
Data Validation โ /โ
In computer science, data validation is the process of ensuring data have undergone data cleansing to ensure they have data quality, that is, that they are both correct and useful.
-- Wikipedia
To my advice, one of the most important task we have while building a form is to ensure that the data is proactively validated.
Of course, there MUST be validation on the backend as well, that's mandatory. โ๏ธ
Never validate data only on the front-end! This might be dangerous. โข๏ธ
But, actually, the real reason why you should do that, is to preserve the mental health of your user. Really! ๐
As a matter of fact, as a user, I often run into long and/or complex and evil form that gives no hint to me about what I should do next or if the data that I provided is correct. ๐
These are some question that I'm sure even you had while filling-out this kind of forms:
1) Is there life on mars? ๐ฝ
2) Will the code I wrote yesterday compile? ๐ค
3) But most importantly... Why the hell is the f**** submit button disabled?!? ๐คฌ
Well, to be honest sometimes happens that the submit button is ALWAYS enabled (really?). ๐ถ
As a developer, I strive to do my best to avoid these frustrating situations.
If only we could make the user โfail fast, fail oftenโ...
What if I told you we can accomplish this task easily?
Yup to the rescue ๐
Yup is a JavaScript object schema validator and object parser.
-- Yup GitHub Page
Install
yarn add yup
If you are using TypeScript
you should install @types
as well.
yarn add -D @types/yup
Play with it! ๐จโ๐ป
We are now ready to get our hands dirty!
For the sake of it, I'm going to show you how to validate a simple contact form.
Let's pretend we require the user to provide us these pieces of information:
- Name
- Surname
- Birth Date
- Sex
- Years Of Proficiency in Web Development
- Phone Number
- A link to a portfolio
All of the fields are required but Sex
and Phone Number
.
We should end up writing this schema with Yup
:
Yup.object({
name: Yup.string().required(),
surname: Yup.string().required(),
birthDate: Yup.date().required(),
sex: Yup.mixed().oneOf(['Male', 'Female']),
yearsOfProficiency: Yup.number().positive().required("Don't be shy!"),
email: Yup.string().email().required(),
phoneNumber: Yup.string(),
portfolio: Yup.string().url()
})
Straightforward, right?
But, what if we want to make a property required based on the value of another field?
Let's say that we would like to be able to contact the user in some way: we don't care if by email or by calling them.
Thereafter, we have to make sure that at least the email OR the phone is provided.
Well, that's easily done with this schema:
Yup.object({
name: Yup.string().required(),
surname: Yup.string().required(),
birthDate: Yup.date().required(),
sex: Yup.mixed().oneOf(["Male", "Female"]),
yearsOfProficiency: Yup.number()
.positive()
.required("Don't be shy!"),
email: Yup.string()
.email(),
phoneNumber: Yup.string()
.test(
"at-least-email-or-phone-number",
"You should provide at least either an email or a phone number",
function(value) {
const email = this.parent.email;
if (!email || value ? .length === 0) {
return false;
}
return true;
}
),
portfolio: Yup.string().url()
})
Whit this schema in place, if we were to validate an object of this shape:
{
name: 'Jimmy',
surname: 'Hopkins',
sex: 'Male',
age: 28,
yearsOfProficiency: 2,
birthDate: '1991-04-29T22:00:00.000Z'
}
We would get a nice Validation Error:
ValidationError: You should provide at least either an email or a phone number
Password example ๐
Another example that came to my mind is the one where the user has to enter a password twice as a mean of security.
Yup.object({
password: Yup.string().required('Password is required'),
confirmPassword: Yup.string()
.oneOf([Yup.ref('password'), null], "Passwords must match")
.required('Password confirm is required')
})
Doing that we make sure that the two passwords are exactly the same!
Profit! ๐
All of that being said, you should be now able to validate a complex shaped object with ease.
If you are using React, you might want to try Formik or React Hook Form.
These two libraries are going to make your life so much easier while building forms, and leverage the possibility to use Yup as a schema validator!
That's all for this post, see you next one!
Happy hacking until then! ๐จโ๐ป
Posted on January 8, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.