I have the next form component in my application:
function App() {
const [state, setState] = useState(false)
const { register, control, handleSubmit, resetField, watch } = useForm();
const [checkedItems, setCheckedItems] = useState([]);
useEffect(()=> {
setCheckedItems(watch('test'))
},[watch('test')])
const onSubmit = (data) => alert(JSON.stringify(data, null, 4));
return (
<form onSubmit={handleSubmit(onSubmit)}>
<h1>Field Array </h1>
<p>The following demo allow you to delete, append, prepend items</p>
<span className="counter">Render Count: {renderCount}</span>
<ul>
{[{value: 1}, {value:2}].map((item, index) => {
return (
<li key={item.userId}>
<Controller
render={({ field }) => <input type='checkbox' {...field} />}
name={`test[${index}]`}
control={control}
/>
</li>
);
})}
</ul>
<input onChange={e => setState(e.target.checked)} type='checkbox' />
{state && <input {...register(`test[${checkedItems.length}]`)}/>}
<input type="submit" />
</form>
);
}
If check this input:
<input onChange={e => setState(e.target.checked)} type='checkbox' />
I display an input where i can add data. Taking into account this scenario:
i click the checkbox, add some data, click again check box, the input dissapear, click again and add data and click submit, then as response i get a lot of data, but i need only the last value; Question: How to fix my issue?
demo: https://codesandbox.io/s/64182981-how-to-preserve-fields-in-react-hook-form-fieldarray-forked-qw18xs
Related
I have created a form in react and store the details in firebase but my problem is even if the feilds are empty the form is submitted, i want validation that feild should not be empty if the user wants to submit.
const Account2 = () => {
const [kookid, setKookID] = useState("");
const [kookname, setKookName] = useState("");
const userCollectionRef = collection(db, "mastermenu")
const handleSubmit = () => {
addDoc(userCollectionRef,{
kookid: kookid,
kookname: kookname,
}).then(() => {
if(!alert("form Submitted Successfully!!!"));
navigate("/account");
})
return (
<><div className='outer-container'>
<h1 className='text-3xl font-bold py-2'>MASTER MENU</h1>
</div>
<div className='outer-container'>
<form className='contactform'>
<label>Kook ID</label>
<input
placeholder=""
onChange={(e) => setKookID(e.target.value) } />
<label>Kook Name</label>
<input
required
placeholder=""
onChange={(e) => setKookName(e.target.value)} />
</form>
<button onClick={handleSubmit}>Submit</button>
</div></>
)
}
New to react and currently working on a project with a backend.
Everything functions correctly apart from targeting the value of user selection.
basically whenever a user enters a number the setId is saved properly to the const with no problems while using the onChange method.
this method would render my page every change on text.
I am trying to save the Id only when the user clicks the button. however,
event.target.value does not work with onClick.
I tried using event.currentTarget.value and this does not seem to work.
Code:
<form onSubmit={handleSubmit}>
<label>Company ID</label>
<input value={id} onChange={(e) => setId(e.target.value)} type="number" />
{/* <button value={id} type="button" onClick={(e) => setId(e.currentTarget.value)}>Search</button> */}
</form>
Handle Submit:
const handleSubmit = (e) => {
e.preventDefault();
console.log(id)
}
is there a way of doing this with onclick? since I wouldn't like my component to render on every typo and only once a user has clicked the button.
Componenet:
interface GetOneCompanyProps {
company: CompanyModel;
}
interface RouteParam {
id: any;
}
interface CompanyById extends RouteComponentProps<RouteParam> {
}
function GetOneCompany(): JSX.Element {
const [id, setId] = useState('4');
const [company, setCompany] = useState<any>('');
const handleSubmit = (e) => {
e.preventDefault();
console.log(id)
}
async function send() {
try {
const response = await axios.get<CompanyModel>(globals.adminUrls.getOneCompany + id)
store.dispatch(oneCompanyAction(response.data));
console.log(response);
const company = response.data;
setCompany(company)
} catch (err) {
notify.error(err);
}
}
useEffect(() => {
send();
}, [id]);
return (
<div className="getOneCompany">
<h1>hi </h1>
<form onSubmit={handleSubmit}>
<label>Company ID</label>
<input value={id} onChange={(e) => setId(e.target.value)} type="number" />
{/* <button value={id} type="button" onClick={(e) => setId(e.currentTarget.value)}>Search</button> */}
</form>
<div className="top">
</div>
<br/>
Company: {id}
<br/>
Client Type: {company.clientType}
<br/>
Company Name: {company.name}
<br/>
Email Adress: {company.email}
<br/>
</div>
);
}
export default GetOneCompany;
Hope I am clear on this.
Thanks.
You can turn your input from being a controlled input to an uncontrolled input, and make use of the useRef hook. Basically, remove most of your attributes from the input element, and grab the current value of the input form on click of the button. From there, you can do whatever you want with the input value.
const inputRef = useRef()
...other code
<form onSubmit={handleSubmit}>
<label>Company ID</label>
<input type="number" ref={inputRef} />
<button value={id} type="button" onClick={() => console.log(inputRef.current.value)}>Search</button>
</form>
...other code
I'm afraid to say that here onChange is mandatory as we also are interested in the value which we set by setId. onClick can't be used as we can't set the value in the input.
Hope I'm clear.
Thankyou!
I am coding with react. I created a Form and on submit I want to send the value of the input field as parameter of another react component, here is "cypher_query" of . Here is my code, it's not working, I don't know where I did mistake. Please help 🙏
const AppGraph = () => {
const [query, setQuery] = useState("");
const handleSubmit = (evt) => {
evt.preventDefault();
}
return (
<div>
<form id="myForm" onSubmit={handleSubmit} >
<div className="App" style={{ fontFamily: "Quicksand" }}>
<label htmlFor="CommentsOrAdditionalInformation">enter your query</label>
<input
name = "requete"
type="text"
id="CommentsOrAdditionalInformation"
value = {query}
onChange={e => setQuery(e.target.value)}
>
</input>
<input type = "submit" value="Submit" className="btn_submit" alt = "submit Checkout"/>
</div>
<p>{query}</p>
</form>
{<ResponsiveNeoGraph
containerId={"id0"}
neo4jUri={NEO4J_URI}
neo4jUser={NEO4J_USER}
neo4jPassword={NEO4J_PASSWORD}
cypher_query={query}
/>}
</div>
);
};
export default AppGraph;
After I submit my form, which contains data fields and a file field, only the data fields are cleared, but the uploaded file field is kept. See image: Here
OnChange Function
onChange = (e) => {
if(e.target.name === 'audio') {
this.setState({
[e.target.name]: e.target.files[0], loaded: 0,
}, () => console.log(this.state.audio))
} else {
this.setState({
[e.target.name]: e.target.value
}, () => console.log(this.state))
}
}
Submit Function
onSubmit = e => {
e.preventDefault();
let { title, content, audio} = this.state;
//const story = { title, content, audio};
let formDataStory = new FormData();
formDataStory.append('audio', audio);
formDataStory.append('title', title);
formDataStory.append('content', content);
this.props.addStory(formDataStory);
this.setState({
title: "",
content:"",
audio: ""
});
};
Form
render() {
const {title, content, audio} = this.state;
return (
<div className="card card-body mt-4 mb-4">
<h2>Add Story</h2>
<form onSubmit={this.onSubmit}>
<div className="form-group">
<label>Title</label>
<input
className="form-control"
type="text"
name="title"
onChange={this.onChange}
value={title}
/>
</div>
<div className="form-group">
<label>Content</label>
<input
className="form-control"
type="text"
name="content"
onChange={this.onChange}
value={content}
/>
</div>
<div className="form-group">
<label>Audio</label>
<input
className="form-control"
type="file"
name="audio"
onChange={this.onChange}
//value={audio}
/>
</div>
<div className="form-group">
<button type="submit" className="btn btn-primary">
Submit
</button>
</div>
</form>
</div>
);
}
}
How can I reset the file upload field together with the other data fields after submitting the form?
Many thanks!
Since the file input is always uncontrolled you'll need to use a dom ref and manually clear the value.
Here's an example functional component that does this:
function ExampleFileInput() {
const ref = React.useRef();
function handleClick() {
ref.current.value = ""
}
return (
<div className="App">
<input type="file" ref={ref}/><br />
<button type="button" onClick={handleClick}>Clear file</button>
</div>
);
}
To use in a class component, see the docs. You can read about more ways to clear the file input in this question.
Docs
Create ref to file input this.inputRef = React.createRef();
add ref to input <input type="file" ref={this.inputRef} />
Inside submit function this.inputRef.current.value = '';
If you use Formik you can do this:
I had the same issue and I managed it creating a ref in the parent component (the one that use Formik) and passing it to the Field using innerRef prop.
Then on the onReset I used the ref to clear the real input value.
const UserForm = props => {
const logoRef = useRef();
const handleReset = (values, formikBag) => {
logoRef.current.value = null; //THIS RESETS THE FILE FIELD
}
const handleSubmit = (values, formikBag) => {
//...
axios({method, url, data})
.then(response => {
formikBag.resetForm();
})
}
//...
return (
<Formik initialValues={initialValues} onSubmit={handleSubmit} onReset={handleReset}>
...
<Field
type="file"
name="logo"
onChange={({target}) => setFieldValue(props.name, target.files[0])}
innerRef={logoRef}
/>
</Formik>
)
}
In my React component there is a required textarea that shouldn't submit empty. After submit I stay within the same component so the textarea has red borders to indicate its errored state.
const CommentForm = ({ postId, addComment }) => {
const [text, setText] = useState('');
const onSubmit = evt => {
evt.preventDefault();
addComment(postId, text);
setText('');
};
const onChange = evt => {
setText(evt.target.value)
};
return (
<div className='post-form'>
<div className='bg-primary p'>
<h3>Add a Comment</h3>
</div>
<form className='form my-1' onSubmit={onSubmit}>
<textarea
name='text'
placeholder='Comment on this post...'
required
value={text}
onChange={onChange}
/>
<input type='submit' className='btn btn-dark my-1' value='Submit' />
</form>
</div>
);
};
How do I remove the red borders after submitting a non empty value? The complete component code is at https://github.com/ElAnonimo/leansquad/blob/master/src/components/post/CommentForm.js.