How can I check if the value of the inputs is the same? - reactjs

I have a form where two fields have to have the same value to be able to continue with the process, for this I have created a component that is in charge of the comparison, the problem is that it does not show me the value of the input to be able to make the comparison . this is my component.
const UIInput = ({ register, rules, name, errors, label, type, options, equals, getValues, ...props }) => {
return (
<div>
<label >{label}</label>
{type === 'select' ?
<select
{...(register && register(name, rules))}>
{options.map(o => (
<option key={o}>{o}</option>
))}
</select>
:
<input
name={name}
{...props}
placeholder={label}
/* {...(register && register(name, rules))} */
{...(register && register({validate:{
name:value=>(value === getValues().email) || console.log('are not the same')
}}))}
/>
/* register && register(name, rules)) */
}
{errors[name] && <ErrorMessaje>{errors[name]?.message}</ErrorMessaje>}
</div>
)
}
export default UIInput
And this is how I use it:
<UIInput
name="email"
register={register}
errors={errors}
label="Email"
defaultValue={dataForm.email}
type="email"
rules={{ required: 'Enter an email' }}
/>
<UIInput
name="email2"
register={register}
errors={errors}
label="Confirmar Email"
type="email"
rules={{ required: 'Has to be the same value' }}
getValues={getValues}
/>
when I run the code the error it sends me is "path.split is not a function"

Related

React hooks form doesn't accept files, but string to system path instead

I'm trying to load a file using React hooks form and yup, but by wrapping the input type file component in Controller I get instead of the usual Blob, system paths like value
Example of result:
C:\\fakepath\\image.jpeg
Expected result
Blob file
Code example:
Link to sandbox: https://codesandbox.io/s/react-select-with-react-hook-form-forked-4t6ncr?file=/src/App.js
Code:
<form onSubmit={handleSubmit(saveData)}>
{!countryValue && (
<Controller
name="country"
control={control}
render={({ onChange, value, ref }) => (
<Select
options={country}
value={country.find((c) => c.value === value)}
onChange={(val) => onChange(val.value)}
/>
)}
rules={{ required: true }}
/>
)}
{countryValue && (
<Controller
name="country"
control={control}
render={(field) => {
const { onChange } = field;
return <input {...field} type="file" onChange={onChange} />;
}}
rules={{ required: true }}
/>
)}
{errors.country && <div>Field is rquired</div>}
<button type="submit">Save</button>
</form>

Conditional Error Handling on MUI controls in react hook form

I want to make field mandatory on the base of condition. Here is my code snippet
<Controller
name={"InvoicingAddress.address_line_1"}
control={control}
rules ={{
required: "This field is required"
}}
render={({ field: { onChange, value },
}) => (
<Input
theme={theme}
fullWidth={true}
label={"Address Line 1"}
placeholder="House number, street name"
type="text"
onChange={onChange}
value={value}
error={errors?.InvoicingAddress?.address_line_1?.message}
></Input>
)}
/>
I want to make required on the basis of condition:
something like this:
{condition &&
rules ={{
required: "This field is required"
}}
}
but the above code is not working
After a lot of research, I've solved something like this
const [applyValidation, setApplyValidation] = useState<boolean>(false);
function setError(): boolean {
if(got error depending upon your condition)
return true;
else
return false;
}
<Controller
name={"OfficeAddress.City"}
control={control}
rules={{
required: {
value: applyValidation,
message: ValidationMessages.CITY_REQUIRED
}
}}
render={({ field: { onChange, value } }) => (
<Input
theme={theme}
fullWidth={true}
label={"City"}
placeholder="e.g. company, apartment, building..."
type="text"
onChange={(e) => {
onChange(e)
setApplyValidation(setError());
}}
value={value}
error={errors?.OfficeAddress?.City?.message}
></Input>
)}
/>

Validating radio button with React Hook Form

I have a custom radio button component in React looking like this:
export default function SingleSelectionButton(props) {
const {
values, name, required, errors, defaultData,
xs, md, register, infoBox, infoBoxContent, validateField } = props;
return (
<>
<Form.Group>
<Form.Label>
<FormattedMessage
id={name}
/>
</Form.Label>
{values.map((value) => (
<span key={value} className="SingleSelectionButton">
<input
{...register(name, { required: required}
id={name + value}
type="radio"
name={name}
value={value}
defaultChecked={defaultData.primary[name] === value}
/>
<label htmlFor={name + value}>
<FormattedMessage id={value} />
</label>
</span>
))}
</Form.Group>
</>
);
};
I call it like this, using an array for the different values:
<SingleSelectionButton
name="us_person"
md={6}
values={["yes", "no"]}
register={register}
required={true}
errors={errors}
validateField="no"
/>
The validation with required is working fine.
The problem is that I don't manage to validate a value in particular.
I have tried the following:
<input
{...register(name, { required: required, validate: value => value === validateField })}
id={name + value}
type="radio"
name={name}
value={value}
defaultChecked={defaultData.primary[name] === value}
/>
And also:
<input
{...register(name, { required: required, pattern: validateField })}
id={name + value}
type="radio"
name={name}
value={value}
defaultChecked={defaultData.primary[name] === value}
/>
So far no joy. What am I missing?

Input not writing into input field.. Issue caused by React useForm Hook register validations

const { register, handleSubmit, errors, setValue } = useForm();
<div className="col pl-0 pr-3">
<FormInput
id="id"
name="name"
isAllowed={e => e.value == '' || (e.value.length <= 14 && e.floatValue >= 0)}
allowLeadingZeros={true}
decimalScale={0}
onChange={e => setName(e.target.value)}
value={Name}
ref={register({ required: { value: true, message: "Please enter name" } })}
/>
<ErrorMessage
errors={errors}
className="col-md-6"
name="name"
as="small"
/>
</div>
In above mentioned code,, here FormInput is customized from StyledInput.
After displaying invalid message, when I am trying to enter something in input field, first character is not writing in field but it is clearing invalid error message from second character writing into field. What's the problem How to solve it Can anyone help me on this ?
UPDATED
By using control input, 3rd party library can work with react-hook-form.
https://react-hook-form.com/get-started#IntegratingControlledInputs
<Controller
as={
<NumberFormat
thousandSeparator={true}
allowLeadingZeros={true}
decimalScale={0}
onValueChange={(value) => {
console.log(value);
}}
isAllowed={(e) =>
e.value === "" || (e.value.length <= 14 && e.floatValue >= 0)
}
/>
}
id="id"
name="name"
defaultValue="1234"
control={control}
rules={{
required: true,
minLength: 2
}}
/>
There is no need to use another state to control the value.
The component is register in react-hooks-form with name "name", it will create the name state and handled state change for you.
Remove the following lines:
const [name, setName] = useState(); // I think you have your own name state, remove it
value={name} // remove it
onChange={(e) => setName(e.target.value)} // remove it

React final form - Validation return key & value instead of string

Currently I am using React-Final-Form and I want to return an object or key/value instead of an error string.
This is my validation rule:
validate={values => {
const errors = {}
if (!values.username) {
errors.username = 'Required'
}
if (!values.password) {
errors.password = 'Required'
}
if (!values.confirm) {
errors.confirm = 'Required'
} else if (values.confirm !== values.password) {
errors.confirm = 'Must match'
}
return errors
}}
This prints the error:
{meta.error && meta.touched && <span>{meta.error}</span>}
Instead of seeing Required I want to be able to say: key -> 'required' and the value of this key is 'please fill in the field'. I know it is possible to change the string of 'Required' but I want to have a key value. I cannot make an object it won't allow me.
Desired result:
{meta.error && meta.touched && {meta.error.required}}
UI will show:
Please fill in the field
This playground of react-final-form can be used since it is almost the same:
https://final-form.org/docs/react-final-form/examples/record-level-validation
Well, you can do it like this:
<Form
onSubmit={onSubmit}
validate={values => {
const errors = {}
if (!values.username) {
errors.username = { required: true, text: "Please fill in the field"} // this is used as an object
}
if (!values.password) {
errors.password = 'Required'
}
if (!values.confirm) {
errors.confirm = 'Required'
} else if (values.confirm !== values.password) {
errors.confirm = 'Must match'
}
return errors
}}
render={({ handleSubmit, form, submitting, pristine, values }) => (
<form onSubmit={handleSubmit}>
<Field name="username">
{({ input, meta }) => {
console.log(meta) // to see the structure of your meta
return (
<div>
<label>Username</label>
<input {...input} type="text" placeholder="Username" />
{meta.error && meta.touched && <span>{meta.error.text}</span>}
// then here if you still want to use string you can put what you need
</div>
)}}
</Field>
<Field name="password">
{({ input, meta }) => (
<div>
<label>Password</label>
<input {...input} type="password" placeholder="Password" />
{meta.error && meta.touched && meta.required && <span>{meta.error}</span>}
</div>
)}
</Field>
<Field name="confirm">
{({ input, meta }) => (
<div>
<label>Confirm</label>
<input {...input} type="password" placeholder="Confirm" />
{meta.error && meta.touched && <span>{meta.error}</span>}
</div>
)}
</Field>
<div className="buttons">
<button type="submit" disabled={submitting}>
Submit
</button>
<button
type="button"
onClick={form.reset}
disabled={submitting || pristine}
>
Reset
</button>
</div>
<pre>{JSON.stringify(values, 0, 2)}</pre>
</form>
)}
/>

Resources