【发布时间】:2019-09-09 14:07:42
【问题描述】:
我有一个表单,其中包含一组复选框,名称为: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
我的组件本质上呈现以下 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),
但我确信必须有一种更简单的方法来验证复选框。
【问题讨论】: