New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Require only one of 4 fields #248
Comments
Tried this aswell but get the cyclic error
Edit: In the mean time going to use |
Please see previous issues on deal with cyclic errors thanks! |
@pmonty I've made an |
I use this: const Yup = require('yup')
Yup.addMethod(Yup.object, 'atLeastOneOf', function(list) {
return this.test({
name: 'atLeastOneOf',
message: '${path} must have at least one of these keys: ${keys}',
exclusive: true,
params: { keys: list.join(', ') },
test: value => value == null || list.some(f => value[f] != null)
})
})
const Schema = Yup.object()
.shape({
one: Yup.number(),
two: Yup.number(),
three: Yup.number()
})
.atLeastOneOf(['one', 'two'])
Schema.isValidSync({ three: 3 }) // false
Schema.isValidSync({ one: 1, three: 3 }) // true |
@calmattack, I had a similar situation and solved it with the following code. My solution requires selecting other input elements and checking the value. With more time you could probable adept @risenforces solution to pass in the schema for validation instead of selecting elements. yup.addMethod(yup.string, 'requiredIf', function(list, message) {
return this.test('requiredIf', message, function(value) {
const { path, createError } = this;
// check if any in list contain value
// true : one or more are contains a value
// false: none contain a value
var anyHasValue = list.some(value => {
// return `true` if value is not empty, return `false` if value is empty
return Boolean(document.querySelector(`input[name="${value}"]`).value);
});
// returns `CreateError` current value is empty and no value is found, returns `false` if current value is not empty and one other field is not empty.
return !value && !anyHasValue
? createError({ path, message })
: true;
});
});
const schema = yup.object().shape({
email: yup.string().requiredIf(['work','home','cell']),
work: yup.string().requiredIf(['email','home','cell']),
home: yup.string().requiredIf(['email','work','cell']),
cell: yup.string().requiredIf(['email','work','home']),
}); |
The check in that test doesn't work well for strings because it allows an empty string. To support strings, you can change it to: test: value => value == null || list.some(f => !!value[f]) |
Updated: const Yup = require('yup')
Yup.addMethod(Yup.object, 'atLeastOneOf', function(list) {
return this.test({
name: 'atLeastOneOf',
message: '${path} must have at least one of these keys: ${keys}',
exclusive: true,
params: { keys: list.join(', ') },
test: value => value == null || list.some(f => !!value[f])
})
})
const Schema = Yup.object()
.shape({
one: Yup.number(),
two: Yup.number(),
three: Yup.number()
})
.atLeastOneOf(['one', 'two']) I can see the validation returns I tried the helper of @Anber Yup.addMethod(Yup.object, 'atLeastOneRequired', function (list, message) {
return this.shape(list.reduce((acc, field) => ({
...acc,
[field]: this.fields[field].when(without(list, field), {
is: (...values) => !values.some((item) => item),
then: this.fields[field].required(message),
}),
}), {}), list.reduce((acc, item, idx, all) => [...acc, ...all.slice(idx + 1).map((i) => [item, i])], []));
}); and it produces the error message correctly. Why doesn't the former code yield any error messages? |
Hi I used your code but got this error: Uncaught ReferenceError: without is not defined |
"without" is from lodash library, in reactjs for example do: |
Basically I am getting an error on the
value => {
definition sayingIs there an easy way to do this so only one field is required?
The text was updated successfully, but these errors were encountered: