我有一个表单,其中包含多个复选框,其名称为:choices []。我有一个PHP后端,复选框的名称无法更改。我正在尝试构建Yup模式以创建验证规则,其中必须选择其中一项。
我当前的解决方案是通过onchange更新带有值的隐藏字段。该值是针对其进行验证的。但这不可能是对的。
有什么主意吗?我已经尝试过了,但这是行不通的。我似乎无法在网上找到一个很好的例子,所以我决定在这里问。
choices[]: Yup.boolean().required('error we need to pick one')
编辑以添加一些代码:
import React, { ChangeEvent, useState, useEffect } from 'react'
import Checkbox from ...
import CheckboxProps from ...
import CheckboxGroup from ...
import Label from ...
export interface CheckboxGroupChoicesProps {
setFieldValue?: any
}
/**
*
* @param props
*/
const CheckboxGroupChoices: React.FunctionComponent<
CheckboxGroupChoicesProps
> = props => {
/**
* State management for the checked counter, we use this in a hidden field for validation purposes
*/
const [checkedCounter, setCheckedCounter] = useState(0)
const [initialLoad, setInitialLoad] = useState(1)
const hiddenFieldName = 'cbxSFVal'
/**
* Enable validation on this checkbox field
*
* This is a required field, as such we need to ensure that at least one of the
* checkboxes has been selected. By incrementing the <hidden> field we ensure
* that we have an idea on how many of the checkboxes have been selected. We
* then use this within the validation.tsx to do some stuff.
*
* @param e: ChangeEvent
*/
function validateCheckboxRequired(e: ChangeEvent) {
if ((e.currentTarget as HTMLInputElement).checked) {
setCheckedCounter(checkedCounter + 1)
} else {
setCheckedCounter(checkedCounter - 1)
}
}
/**
* Handle the state change for checkedCounter.
* setFieldValue is from formik and we can use it to update the hidden field
* that we use for validation.
*/
useEffect(() => {
if (initialLoad != 1) {
props.setFieldValue(hiddenFieldName, checkedCounter)
} else {
setInitialLoad(0)
}
}, [checkedCounter])
/**
* Create an array of checkboxes that will be sent to the Checkboxgroup molecule.
*
* @return Array<ChecboxProps>
*/
const getCheckboxes: any = () => {
const checkboxes: Array<React.ReactElement<CheckboxProps>> = []
const options = ['Car', 'Van', 'Bike']
options.forEach((option, key) => {
checkboxes.push(
<Checkbox
label={option}
value={option}
disabled={false}
name={'choices[]'}
key={`choices-${key}`}
handleOnClick={(e: ChangeEvent) => validateCheckboxRequired(e)}
/>
)
})
return checkboxes
}
return (
<>
<Label>Pick choices</Label>
<CheckboxGroup columns={3}>{getCheckboxes()}</CheckboxGroup>
<input type={'hidden'} name={hiddenFieldName} />
</>
)
}
export default CheckboxGroupChoices
我的组件essentiall呈现以下html:
<div>
<checkbox name='choices[]' value='car'> Car<br />
<checkbox name='choices[]' value='van'> Car<br />
<checkbox name='choices[]' value='bike'> Car<br />
</div>
我使用formik进行如下验证模式的验证:
<Formik
enableReinitialize
initialValues={postingForm.initialValues}
validationSchema={postingForm.validationSchema}
>
{form => (
<Form> ....</Form>
)}
</Formik>
提交后,我想确认是否已检查我的至少一项选择。我当前的组件将基于复选框的选中状态来+1和-1隐藏字段的值。使用以下方法对此进行了验证:
cbxSFVal: Yup.number().min(1, required_message),
但是我敢肯定,必须有一种更简单的方法来验证复选框。
答案 0 :(得分:1)
您需要使用引号设置属性名称。
const schema = Yup.object().shape({
"choices[]": Yup.boolean().required('error we need to pick one')
});
此外,请确保您以正确的方式访问属性。
// Syntax Error
obj.choices[]
// Correct Way
obj["choices[]"]
您可以做的是使用每个复选框的状态创建一个数组,因此,如果您有3个选项,它将是一个长度为3且带有false
的数组,并在单击时将其更新为true。
这样,您可以通过以下方式验证其中一个复选框为真
"choices[]": Yup.array().oneOf(['true']).required('error we need to pick one')