Is possible combine two fields in one Controller? #2363
-
show a example , i am created a addres field,have two field my idea is use one controller to wrap two field, and i try it like this to combine value,in one Controller , look like working fine select field props.onChange({ ...props.value, districtId: district.districtId }) input field props.onChange({ ...props.value, streetAddress: e.target.value }) ex: export const Address = () => {
const { control, handleSubmit, watch, register } = useForm({
defaultValues: {
address:{
districtId:"",
streetAddress:""
}
},
})
console.log(watch())
return (
<form>
<Controller control={control} name="address" as={<FieldAdress />} />
</form>
)
} FieldAddress const Address = (props) => {
// console.log(props) value,name,onChange,onBlur
// ...
return (
<S.Field>
<S.SelectGroup>
//....
<S.Select
onChange={(e) => {
const district = JSON.parse(e.target.value)
// console.log(district)
setDistrict(district)
props.onChange({ ...props.value, districtId: district.districtId })
}}
>
<S.SelectOption value="{}">鄉鎮</S.SelectOption>
{districts.map((d, i) => {
const {
value: { name, ...dValue },
} = d
const dString = JSON.stringify(dValue)
return (
<S.SelectOption key={i} value={dString}>
{name}
</S.SelectOption>
)
})}
</S.Select>
<Input disabled defaultValue={postalCode} placeholder="郵遞區號" />
</S.SelectGroup>
<Input
onChange={(e) => {
props.onChange({ ...props.value, streetAddress: e.target.value })
}}
placeholder="地址"
/>
</S.Field>
)
} |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 8 replies
-
yes, it's possible. it depend on how you structure you inner component, i would make component local state to be an object. onChange({ |
Beta Was this translation helpful? Give feedback.
-
can you please show me a example . |
Beta Was this translation helpful? Give feedback.
-
hi, I've tried the method above and it works fine. but the problem is I can't make the field required. Parrent: <Controller
name={'phone_number'}
control={control}
rules={{
required: true
}}
render={({field}) => (
<InputPhoneNumber
{...field}
label='phone'
required />
)}
/>
<ErrorMessage
isActive={errors.phone_number?.ext_phone?.type === 'required' }
message={errorMessage.required}
/>
<ErrorMessage
isActive={errors.phone_number?.phone?.type === 'required'}
message={errorMessage.required}
/> Child: const [isFocus, setIsFocus] = useState(false)
const [options, setOptions] = useState<SelectOptionType[]>([])
const handleChangeExtPhone = (data: SelectOptionType | null) => {
const value = rest.value
rest.onChange({ ...(value as InputPhoneNumberType), ext_phone: data?.value})
}
const handleChangePhone = (data: ChangeEvent) => {
const target = data.target as HTMLInputElement;
const value = rest.value
rest.onChange({ ...(value as InputPhoneNumberType), phone: target.value})
}
useEffect(() => {
setOptions([])
phoneDialCodeList.map((item) => {
setOptions(prevState => [...prevState, {label: item.name, value: item.dial_code}])
})
}, [])
return (
<Wrapper {...rest} onFocus={() => setIsFocus(true)} onBlur={() => setIsFocus(false)}>
<InputLabel required={required}>{label}</InputLabel>
<InputRow isFocus={isFocus}>
<ReactSelect
name='ext_phone'
styles={customSelectStyle}
onChange={(e) => handleChangeExtPhone(e)}
isLoading={isLoading}
isSearchable={true}
options={options}
/>
<Input
type='number'
onChange={(e: ChangeEvent) => handleChangePhone(e)}
/>
</InputRow>
</Wrapper>
) |
Beta Was this translation helpful? Give feedback.
yes, it's possible. it depend on how you structure you inner component, i would make component local state to be an object.
onChange({
address: 'yes',
another: 'yes',
})