React showing value required on edit case even if the field is already populated - reactjs

I am using react-hook-form and Joi for the validataion in react. But in case of edit, if I don't touch any field and hit directly update, it shows value required, even when the field is already populated there.
But, once I focus or clicked on the input field, and hit update, then its get updated.
Here is the form:
const MarketplaceForm = ({ submitAction, submitBtnText, item }) => {
//joi schema
const schema = Joi.object({
name: Joi.string().required().min(3).max(191).label("Marketplace Name"),
});
//react hook form setup
const {
register,
handleSubmit,
setError,
clearErrors,
formState: { errors },
} = useForm({
resolver: joiResolver(schema),
});
const onSubmit = async (input) => {
submitAction(input, setError);
};
return (
<div className="intro-y box p-5">
<form id="add_marketplace_form" onSubmit={handleSubmit(onSubmit)}>
<div>
<label htmlFor="crud-form-1" className="form-label">
Marketplace Name
</label>
<input
className={`form-control w-full ${
errors["name"] ? "border-red-500" : ""
}`}
type="text"
id="name"
name="name"
autoComplete="on"
{...register("name")}
defaultValue={item.name ?? ""}
/>
<ErrorSpan errors={errors} fieldName="name" />
</div>
<div className="text-right mt-5">
<button
type="button"
className="btn btn-outline-secondary w-24 mr-1"
>
Cancel
</button>
<button type="submit" className="btn btn-success w-24">
{submitBtnText}
</button>
</div>
</form>
</div>
);
};
export default MarketplaceForm;

I guess you should check validation as your validation is not working properly or see the name props
is this default value working
defaultValue={item.name ?? ""}

Related

My firebase Create User trigger 2 times instead of one

Creating a react app usign react-firebase-hook,firebase,react-hook-form,daisyUI
The problem is When I am pressing submit button it triggers 2 times in the console and when using the Button; Sign Up With Google it triggers 3times.Thanks for your time in advance.
In SingUP function:
import auth from '../../firebase.init';
import { useSignInWithGoogle } from 'react-firebase-hooks/auth';
import { useForm } from "react-hook-form";
import { useCreateUserWithEmailAndPassword } from 'react-firebase-hooks/auth';
function SignUp() {
const [signInWihGoogle, googleUser, googleLoading, googleError] = useSignInWithGoogle(auth);
const { register, formState: { errors }, handleSubmit } = useForm();
const [
createUserWithEmailAndPassword,
user,
loading,
error,
] = useCreateUserWithEmailAndPassword(auth);
This function is triggering:
const onSubmit = data =>{
createUserWithEmailAndPassword(data.email,data.password);
alert('You successfully created your account');
}
<form onSubmit={handleSubmit(onSubmit)}>
<div class="form-control w-full max-w-xs">
<label class="label">
<span class="label-text">Name</span>
</label>
<input
type="text"
placeholder="Pls type name here"
class="input input-bordered w-full max-w-xs"
{...register("name", {
required:{
value: true,
message:'Name is Required'
},
minLength: {
value:2,
message:'Name must be 2 or more characters
}
})}/>
</div>
... .... ...
<input
type='submit'
value= 'Signup'
class="btn w-full max-w-xs text-white"/>
</form>
<p className='text-center text-xs pt-1'>Already have an account?<Link
className='text-secondary' to='/login'> Please Login</Link></p>
<div class="divider">OR</div>
<button
onClick={() => signInWihGoogle()}
class="btn btn-outline">Continue with Google</button>
</div>
Do you still have the strict mode tag in your App?
If so: delete it and if you want you can read more on it here: https://reactjs.org/docs/strict-mode.html

If statement within an input field

I am using Bootstrap with React and there is an option within an input <input ... readonly/> field to set readonly, now I have an input field set to readonly. However, when the user clicks on a button, I want the readonly mode to disappear and the user to be able to use that input field. However, my if statement does not work. What is the best way to do this?
What I tried
{ clicked ?
readOnly : null
}
My Code
const Profile = () => {
const [clicked, setClicked] = useState(true);
const onClickBack = () => {
setClicked(false);
}
return (
<div>
<div className="form-group">
<div className="col-xs-4">
<label for="exampleInputName">Name</label>
<input
type="text"
className="form-control"
placeholder="Name"
// THIS IS WRONG ↓
{ clicked ?
readOnly : null
}
// THIS IS WRONG ↑
/>
</div>
</div>
<button
type="button"
id="submit"
name="submit"
className="btn btn-primary submit-button ml-5"
onClick={onClickBack}
>
Back
</button>
</div>
);
};
export default Profile;
This should work...
<input readOnly={!clicked}/>

In React with Formik how can I build a search bar that will detect input value to render the buttons?

New to Formik and React I've built a search component that I'm having issues with the passing of the input value and rendering the buttons based on input length.
Given the component:
const SearchForm = ({ index, store }) => {
const [input, setInput] = useState('')
const [disable, setDisable] = useState(true)
const [query, setQuery] = useState(null)
const results = useLunr(query, index, store)
const renderResult = results.length > 0 || query !== null ? true : false
useEffect(() => {
if (input.length >= 3) setDisable(false)
console.log('input detected', input)
}, [input])
const onReset = e => {
setInput('')
setDisable(true)
}
return (
<>
<Formik
initialValues={{ query: '' }}
onSubmit={(values, { setSubmitting }) => {
setInput('')
setDisable(true)
setQuery(values.query)
setSubmitting(false)
}}
>
<Form className="mb-5">
<div className="form-group has-feedback has-clear">
<Field
className="form-control"
name="query"
placeholder="Search . . . . ."
onChange={e => setInput(e.currentTarget.value)}
value={input}
/>
</div>
<div className="row">
<div className="col-12">
<div className="text-right">
<button type="submit" className="btn btn-primary mr-1" disabled={disable}>
Submit
</button>
<button
type="reset"
className="btn btn-primary"
value="Reset"
disabled={disable}
onClick={onReset}
>
<IoClose />
</button>
</div>
</div>
</div>
</Form>
</Formik>
{renderResult && <SearchResults query={query} posts={results} />}
</>
)
}
I've isolated where my issue is but having difficulty trying to resolve:
<Field
className="form-control"
name="query"
placeholder="Search . . . . ."
onChange={e => setInput(e.currentTarget.value)}
value={input}
/>
From within the Field's onChange and value are my problem. If I have everything as posted on submit the passed query doesn't exist. If I remove both and hard code a true for the submit button my query works.
Research
Custom change handlers with inputs inside Formik
Issue with values Formik
Why is OnChange not working when used in Formik?
In Formik how can I build a search bar that will detect input value to render the buttons?
You need to tap into the props that are available as part of the Formik component. Their docs show a simple example that is similar to what you'll need:
<Formik
initialValues={{ query: '' }}
onSubmit={(values, { setSubmitting }) => {
setInput('')
otherStuff()
}}
>
{formikProps => (
<Form className="mb-5">
<div className="form-group has-feedback has-clear">
<Field
name="query"
onChange={formikProps.handleChange}
value={formikProps.values.query}
/>
</div>
<button
type="submit"
disabled={!formikProps.values.query}
>
Submit
</button>
<button
type="reset"
disabled={!formikProps.values.query}
onClick={formikProps.resetForm}
>
</Form>
{/* ... more stuff ... */}
)}
</Formik>
You use this render props pattern to pull formiks props out (I usually call them formikProps, but you can call them anything you want), which then has access to everything you need. Rather than having your input, setInput, disable, and setDisable variables, you can just reference what is in your formikProps. For example, if you want to disable the submit button, you can just say disable={!formikProps.values.query}, meaning if the query value in the form is an empty string, you can't submit the form.
As far as onChange, as long as you give a field the correct name as it corresponds to the property in your initialValues object, formikProps.handleChange will know how to properly update that value for you. Use formikProps.values.whatever for the value of the field, an your component will read those updates automatically. The combo of name, value, and onChange, all handled through formikProps, makes form handing easy.
Formik has tons of very useful prebuilt functionality to handle this for you. I recommend hanging out on their docs site and you'll see how little of your own code you have to write to handle these common form behaviors.

Formik handleReset is going through validation

I'm trying to add a Reset button on my Formik form. Trouble is, when I click the Reset button Formik shows me the validation errors. Only after I click the Reset button a second time does the form actually reset. Why should the user go through form validation if all they want is to reset the form, right? Here's my form component:
const ContactForm = () => {
const submit = async (values, { setSubmitting, resetForm }) => {
... submit logic ...
}
return (
<Formik
initialValues={{
name: '',
email: '',
message: '',
}}
validationSchema={Yup.object({
name: Yup.string()
.min(3, 'Tamanho mínimo: 3 caracteres')
.max(20, 'Tamanho máximo: 20 caracteres')
.required('Campo obrigatório.'),
...more fields ...
})}
onSubmit={submit}
>
{({ isValid, isSubmitting, handleReset }) => (
<Form>
<div className="mb-3">
<label htmlFor="name" className="form-label">
Nome
</label>
<Field
name="name"
type="text"
className="form-control"
aria-describedby="nameHelp"
/>
<ErrorMessage
component="div"
id="nameHelp"
name="name"
className="form-text text-warning"
/>
</div>
... more fields ...
<button
type="submit"
disabled={isSubmitting || !isValid}
className="btn btn-primary shadow me-3"
>
Enviar
</button>
<button
disabled={isSubmitting}
className="btn btn-outline-primary shadow"
onClick={handleReset}
>
Apagar
</button>
</Form>
)}
</Formik>
)
}
export default ContactForm
I must be doing something wrong. How can I reset the form without going through the validation process?
I think you should update your reset button as follows -
<button type="reset" onClick={ e => formik.resetForm()}> Reset</button>

Trying to disable Send button when there are errors

I have this form in a react-redux component.
The problem is that I’m trying to make the Send button disabled when the input.trim() is empty.
It is not behaving as expected.
If I type something, the button remains disabled,
export default function TodoInput() {
const [todoText, setTodoText] = React.useState('');
const [errors, setErrors] = React.useState('');
const dispatch = useDispatch()
function validate(text) {
text.trim()
return (text.length !== 0 ? 'Error' : '')
}
function handleInputChange(e) {
setTodoText((e.target.value).trim())
setErrors(validate(e.target.value));
}
function submitButton() {
if (errors.length !== 0)
return <input type="submit" onSubmit={onSubmit} className="btn btn-primary mx-2" disabled/>
else
return <input type="submit" className="btn btn-primary mx-2"/>
}
function onSubmit() {
dispatch(todoAdded(todoText))
}
return (
<div>
<div className="row m-2">
<form className={style.todoForm}
onSubmit={(e) => {
e.preventDefault(); // the default behavior is to refresh the whole window
onSubmit(todoText);
setTodoText('')
}}>
<input type="text"
className="col form-control"
placeholder="Todo Text..."
name="todoText"
value={todoText}
onChange={handleInputChange}
/>
{submitButton()}
</form>
</div>
</div>
)
}
What could it be?
Thanks in advance
Rafael

Resources