ZAR
ZAR

Reputation: 2736

yup.js Validate number field is larger than sibling, or nullable

I'm using Yup.js to validate some form fields.

I have two integer fields, Year Built & Year Renovated.

Year Built is a required field, Year Renovated is not.

Year renovated can be left blank, however if there is a value it should be larger than year built (for a renovation certainly must occur after the date it was built).

I believe I need to use yup's ref() as well as yup's when() function. I've tried the following:

let currentYear = new Date().getFullYear();

yup.object().shape({
  yearBuilt     : yup.number().integer().min(1700).max(currentYear+1).required(),
  yearRenovated : yup.number().integer().when(
                    '$yearRenovated', (yearRenovated, schema)=>{
                        return yearRenovated > 0 ? 
                            schema.min(yup.ref('yearBuilt')).max(currentYear+1) :
                            schema.transform(emptyStringToNull).nullable()
                    }
                )
})

* The transform function, emptyStringToNull simply checks if value === '' and returns null if so.

The above does allow null values, as well as does correctly check for an integer. However it does not properly evaluate yearRenovated > yearBuilt. How do I properly check that if yearRenovated is not null, that it is greater than yearBuilt?

Thank you all so much for your help.

Upvotes: 19

Views: 31371

Answers (4)

Danilson Kayumbuca
Danilson Kayumbuca

Reputation: 1

Whenever You want to expecify a value from corrent key, just use the yup.ref("key"), in this way you can use this to create better conditions in yup validation schema!

Upvotes: 0

Prajapati Ghanshyam
Prajapati Ghanshyam

Reputation: 142

const schema = Yup.object({
  // -- snip --
  billAmount: Yup.number().nullable(),
  approvedAmount: Yup.number()
    .typeError("you must specify a number")
    .notRequired()
    .when("billAmount", (billAmount: any, schema: any) => {
      return schema.test({
        test: (approvedAmount: any) => {
          if (!approvedAmount) return true;
          return approvedAmount < billAmount;
        },
        message: "Approved Amount not gether then billAmount",
      });
    }),
});

Upvotes: 3

king
king

Reputation: 302

Yup (Less than or Equal To): https://github.com/jquense/yup/issues/538#issuecomment-495340254

If you end up needing a less than or equal to implementation (<=) consider this:

number().max(5) // is <= 5

Upvotes: -1

ZAR
ZAR

Reputation: 2736

@JQuense, the owner of the repo had an eloquent solution, using moreThan():

const schema = yup.object().shape({
    yearBuilt: yup
      .number()
      .integer()
      .min(1700)
      .max(currentYear+1)
      .required(),
    yearRenovated: yup
      .number()
      .integer()
      .nullable()
      .moreThan(yup.ref("yearBuilt")) //<-- a whole lot neater than using a when conditional...
      .max(currentYear+1)
});

Hope that helps! Thank you @JQuense.

Upvotes: 31

Related Questions