Reputation: 23563
I'm trying to validate a phone number with Yup:
phone: Yup.number()
.typeError("That doesn't look like a phone number")
.positive("A phone number can't start with a minus")
.integer("A phone number can't include a decimal point")
.min(8)
.required('A phone number is required'),
.min(8)
validates that the number is 8 or more. So simply entering 8
will pass. How can I make 8 characters required so 1000 0000
would pass?
Upvotes: 86
Views: 230853
Reputation: 1
const schema = yup.object().shape({
contact: yup.number().typeError('Contact number must be a number')
.required('Contact number is required')
.positive('Contact number must be positive')
.integer('Contact number must be an integer')
.min(1000000000, 'Contact number must be at least 10 digits')
.max(9999999999, 'Contact number must be at most 10 digits'),
});
Upvotes: 0
Reputation: 3520
In my case, phone number is an optional field and I didn't want to care about a complex pattern. So I used the test method with a simple regex
yup.string().test('phone', `Invalid phone number`, (v) => {
if (!v) {
return true;
}
return /^\+?\d{6,15}$/.test(v);
});
Upvotes: 0
Reputation: 41
Hi, This is regex for indian local mobile number validation and for Indian international .
starting with 9,8,7 you can add more as well.
you can test it using https://regex101.com/
import * as Yup from "yup";
const phoneNumberRules = /^(?:(?:\+|0{0,2})91(\s*[\-]\s*)?|[0]?)?[789]\d{9}$/;
const emailRules = /^[a-zA-Z0-9._%+-]+@(gmail|yahoo)\.com$/;
export const clientSchema=Yup.object().shape({
name:Yup.string().required("Name Not be Empty"),
email: Yup.string().email("Invalid Email!")
.matches(emailRules, { message: " Not valid :{" })
.required("Email Required !"),
phone: Yup.string()
.matches(phoneNumberRules, { message: "Invalid Phone Number!" })
.required("Phone Number Required !"),
})
Upvotes: 0
Reputation: 429
Here is how I combined yup with other 3rd phone validation libraries ("awesome-phonenumber" in my case):
import { parsePhoneNumber } from "awesome-phonenumber";
import * as Yup from "yup";
const schema = Yup.object().shape({
name: Yup.string().required("Required"),
phoneNumber: Yup.string()
.required("Required")
.test("phoneNumber", "Phone number is not valid", (str, context) => {
const pn = parsePhoneNumber(str);
return pn.valid;
}),
addressLine1: Yup.string().required("Required"),
// ...Other fields
});
Upvotes: 0
Reputation: 431
Try this, it might be helpful for you.
mobile: Yup.string().matches(/^[6-9]\d{9}$/, {message: "Please enter valid number.", excludeEmptyString: false})
Upvotes: 12
Reputation: 139
const phoneRegExp = /^((\\+[1-9]{1,4}[ \\-]*)|(\\([0-9]{2,3}\\)[ \\-]*)|([0-9]{2,4})[ \\-]*)*?[0-9]{3,4}?[ \\-]*[0-9]{3,4}?$/
phone_number: Yup.string()
.required("required")
.matches(phoneRegExp, 'Phone number is not valid')
.min(10, "too short")
.max(10, "too long"),
This works best for me...you can set your own length...i just wanted 10 digits not less or more
Upvotes: 13
Reputation: 9282
Here's a snippet from my code.
let schema = yup.object().shape({
phone: yup
.string()
// regexr.com/6anqd
.matches(/(\+91\ )[6-9]{1}[0-9 ]{4}[0-9 ]{4}[0-9]{3}/, {
message: "Invalid Indian number",
excludeEmptyString: false,
})
.required(),
email: yup.string().required().email(),
password: yup.string().required().min(8),
confirmPassword: yup
.string()
.required()
.oneOf([yup.ref("password")], "Passwords do not match"),
agree: yup
.boolean()
.oneOf(
[true],
"It is essential to accept our Privacy Policy to register.",
),
});
My regex checks for Indian Phone numbers following the format, +91 axxx xxx xxx
(where a
can be a digit in the range 6 to 9 and x
can be 0 - 9).
I tried yup-home but it was not able to actually verify the range for the Indian Number I wanted, plus, the package import size was costly.
Also, I'm using React with Formik at the frontend for form validation with react-phone-input-2
<PhoneInput
country={"in"}
value={values.phone}
name="phone"
onChange={(phone, data, e) => handleChange(e)}
onBlur={(e) => handleBlur(e)}
defaultMask=".... ... ..."
masks={{ in: ".... ... ..." }}
onlyCountries={["in"]}
inputProps={{
name: "phone",
required: true,
autoFocus: true,
}}
disableSearchIcon={true}
disableDropdown={true}
containerClass="mt-1 border h-12 text-sm focus:outline-none block w-full bg-gray-100 dark:bg-transparent border-transparent focus:bg-white"
inputClass="mt-1 border h-12 text-sm focus:outline-none block w-full bg-gray-100 dark:bg-transparent border-transparent focus:bg-white"
inputStyle={{
background: "transparent",
border: "1px solid grey",
height: "3em",
width: "100%",
outline: "none",
}}
buttonStyle={{
height: "3em",
background: "transparent",
outline: "none",
border: "none",
}}
/>
{handleFormikError(errors, touched, "phone")} // returns the span.alert with error message
Upvotes: 1
Reputation: 1927
I made a new package for this called yup-phone-lite. I had used the original yup-phone package but it uses the massive google-libphonenumber so I replaced it with a smaller fork.
Upvotes: 2
Reputation: 1721
Hi right now I'am solving same problem as you and I found possible solution.
Validate phone number with string that matches Regex
const phoneRegExp = /^((\\+[1-9]{1,4}[ \\-]*)|(\\([0-9]{2,3}\\)[ \\-]*)|([0-9]{2,4})[ \\-]*)*?[0-9]{3,4}?[ \\-]*[0-9]{3,4}?$/
phoneNumber: Yup.string().matches(phoneRegExp, 'Phone number is not valid')
You can search for different Regex Expressions and validate it. I've used Regex from this article https://www.sitepoint.com/community/t/phone-number-regular-expression-validation/2204
Upvotes: 160
Reputation: 5672
I've created a yup-phone
module that uses google-libphonenumber
which gives accurate validation checks and can be installed directly from github
npm install --save yup yup-phone
.
Check Usage
const Yup = require('yup');
require('yup-phone');
// validate any phone number (defaults to India for country)
const phoneSchema = Yup.string().phone().required();
phoneSchema.isValid('9876543210'); // → true
From Simple React Validator,
The regex for phone number validation is
/^(\+?\d{0,4})?\s?-?\s?(\(?\d{3}\)?)\s?-?\s?(\(?\d{3}\)?)\s?-?\s?(\(?\d{4}\)?)?$/
// index.js
const yup = require('yup');
const { rePhoneNumber } = require('./yup-phone')
const schema = yup.string().phone()
const phone = '+911234567890';
console.log('Is Valid? ', rePhoneNumber.test(phone)); // Is Valid? true
schema.validateSync(phone);
// yup-phone.js
const yup = require('yup');
const rePhoneNumber = /^(\+?\d{0,4})?\s?-?\s?(\(?\d{3}\)?)\s?-?\s?(\(?\d{3}\)?)\s?-?\s?(\(?\d{4}\)?)?$/;
module.exports.rePhoneNumber = rePhoneNumber
yup.addMethod(yup.string, "phone", function() {
return this.test("phone", "Phone number is not valid", value =>
rePhoneNumber.test(value)
);
});
Upvotes: 56
Reputation: 31
I have a similar use case, and here's my solution:
// Regex source: https://www.oreilly.com/library/view/regular-expressions-cookbook/9781449327453/ch04s02.html
const phoneRegex = RegExp(
/^\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/
);
const schema = yup.object().shape({
phone: yup.string().matches(phoneRegex, "Invalid phone").required("Phone is required")
});
Upvotes: 1
Reputation: 96
Just a little collaboration. On my case I don't want to validate if the input is empty (when is not required). Thank you all for your examples!
yup.addMethod(yup.string, "phone", function(messageError = 'Phone number is not valid') {
const phoneRegExp = /^((\\+[1-9]{1,4}[ \\-]*)|(\\([0-9]{2,3}\\)[ \\-]*)|([0-9]{2,4})[ \\-]*)*?[0-9]{3,4}?[ \\-]*[0-9]{3,4}?$/
return this.test('phone', messageError, value => {
if (value && value.length > 0) {
return phoneRegExp.test(value)
}
return true
})
})
Upvotes: 4