I have a form with a textarea where users can put comments, and then trigger a onClick (when the form is submitet via the button).However, I cant get the value of the input, for example if a user writes "test", I want it to get into the handleSubmit function.
My form
<form onSubmit={this.handleSubmit.bind(this)} method="POST">
<label>Skicka</label>
<textarea placeholder="Type in comments (allergis etc.)" name ="name" ref ="name"></textarea>
<button className="btn" type="submit">
Send
</button>
</form>
//my handler
public handleSubmit = event => {
event.preventDefault();
console.log(event.name.value)
}
You have to save the textarea value separately in the onChange method of the textarea like this (for class component):
<form onSubmit={this.handleSubmit.bind(this)}
method="POST"
>
<label>Skicka</label>
<textarea
onChange={this.setComments}
placeholder="Type in comments (allergis etc.)"
name="name"
value={this.state.comment}/>
<button className="btn" type="submit">
Send
</button>
</form>
// The save function
const setComments = e => this.setState({comment: e.target.value});
This will save the textarea input in your local state and you can access it in your submit function with this.state.comment.
Hope this helps. Happy coding.
As you are using Uncontrolled Component. You can make use of ref to get value.
handleSubmit = (event) => {
event.preventDefault();
console.log(this.refs.name.value)
}
Demo
Note: In React you should never add method="POST" and action attribute's on form.
Don't add public keyword to your function (if you are not using typescript).
Better approach to work with form values, is Controlled Component
You can fix it by changing the handleSubmit method. Check below updated method.
public handleSubmit = event => {
event.preventDefault();
console.log(event.target.name.value)
}
But if you are work with React application then update the state variable via onChange event.
Related
I am using bootstrap and reactJS and want to build a form.
Consider the following snippet:
const CustomForm = () => {
const [alertText, setAlertText] = ('')
const [username, setUsername] = ('');
const handle_submit = () => {
//treat some possible error
setAlertText('some warnings...')
}
return (
<Form>
{alertText && <Alert className='mb-3' variant="warning" >
{alertText}
</Alert>}
<FormGroup className="mb-3">
<FloatingLabel label='username'>
<Form.Control type='text' name='username' placeholder='username' onChange={e => setUsername(e.target.value)} value={username} />
</FloatingLabel>
</FormGroup>
<Button className='float-end' type='submit' variant='outline-primary' onClick={handle_submit} >Submit</Button>
</Form>
)
}
the problem with that snippet is that when the button is declared as submit, it auto reloads the page and empties the form, or I would like to handle some error before and do all that stuff only if the are no errors.
If I declare the type as button, it works well, but I am a little bit confused. I would like to use the submit attribute; I think it is more appropriate.
So my first question is, I am right to think that ? and the second is, what do I need to change empty the form only if there are no errors?
Short answer:
type='button' is more appropriate in your case.
Long Answer:
As per MDN Documentation, a button will have by default a type of submit. If the type is submit, once clicked, it will submit the request to the server. If the form the submit button is a part of has action property defined, the POST request will be sent to that uri, otherwise it will be sent to the current uri. In your case it will trigger a page redirect to the same page, and that is the reason why your form is reset.
Since you have an event listener attached to the button, and you want to process the event client-side to later sent XHR(AJAX) request, you don't want the button to trigger the request to server. Thus you can safely set it to type='button'.
If for some reason you still need to keep type='submit', you can stop the submit to further propagate in your onClick event handler using:
e.stopPropagation();
Add the onSubmit prop to Form:
<Form onSubmit={handle_submit}>
and in the handle_submit function add the event (e) argument and call the function preventDefault (prevents refresh):
const handle_submit = (e) => {
// Prevent refresh
e.preventDefault();
//treat some possible error
setAlertText('some warnings...')
}
When using forms or input tags in react I use useState for the value of the form.
const [value,setvalue]=useState("");
onInput(e)=>{setvalue(e.target.value)};
But with this each time the user fills the form the component gets rerendered. Is there any better way to do that?
if you are using a form you can use onSubmit
<form onSubmit={this.handleSubmit}>
<input type="text" name="input1" />
<button type="submit">Submit</button>
</form>
and in handleSubmit function:
handleSubmit(event) {
event.preventDefault();
var input1 = event.currentTarget.input1.value;
// Do the rest
}
Description:
The submit button calls a function called displayFields. This function then console logs the state of the input fields. The start of the input fields is listened to by onChange that sets the new state.
Before clicking the submit button the input fields when something is entered console logs the current state of the fields and then provides each string character in the console. To my understanding onChange should listen for changes but not console anything. When the button is clicked it should perform the function one time and console the current state of what is entered in fields. Instead when clicked the fields clear and then console an empty string.
I will provide my code and screen shots to help.
const GetQuote = (props) => {
const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [question, setQuestion] = useState("");
const dispFields = () => {
console.log(name + email + question);
};
/*
This is used in case prevent defualt needs used
function handleSubmit(e) {
e.preventDefault(); }
*/
return (
<React.Fragment>
<form
id="quoteForm"
//onSubmit={handleSubmit}
>
<h1 id="quoteTitle"> Quote Help Form </h1>
<p id="quotePar">
{" "}
Please provide your Name, Contact Email, and what products you would
like more information about in this form:{" "}
</p>
<label id="formName" className="Form">
Name:
<input
type="text"
name="name"
onChange={(event) => {
setName(event.target.value);
}}
/>
</label>
<label id="formEmail" className="Form">
Email:
<input
type="text"
name="email"
onChange={(event) => {
setEmail(event.target.value);
}}
/>
</label>
<br />
<label id="formQuestion" className="Form">
What products would you like to know more about:
<input
type="text"
name="help"
onChange={(event) => {
setQuestion(event.target.value);
}}
/>{" "}
</label>
<br />
<br />
<button
id="quoteSubmit"
type="submit"
//funtion is called however seems to constantly call the useState which is used in onchange
//when submit is done returns empty string
onClick={dispFields()}
>
Submit{" "}
</button>
</form>
</React.Fragment>
);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
onClick={dispFields()} is getting called on every render. If you pass it without calling it (onClick={dispFields} that should only log it to the console when the button is clicked.
You try to alter from
<
button id = "quoteSubmit"
type = "submit"
//funtion is called however seems to constantly call the useState which is used in onchange
//when submit is done returns empty string
onClick = {
dispFields()
} >
Submit < /button>
to
<
button id = "quoteSubmit"
type = "button"
//funtion is called however seems to constantly call the useState which is used in onchange
//when submit is done returns empty string
onClick = {()=>
dispFields()
} >
Submit < /button>
Changed "button" from "submit", arrow function involved
Both solutions provided above work. Changing to example = {example} from example = {example()}. Also calling it from a arrow function also works. The issue is a node issue. What happens when the use breakpoints is set on the function, the values are console logged however after they are console logged the form refreshes and then the state refreshes so the console logs are never logged because the browser processes the value of event and clears the event at the same time. So as long as the values can be passed to the backend, the front end can remain clearing the value being rendered.
Good day, so I am trying to perform an intermediate function before a form action="POST" takes place. Ive tried two things firstly onSubmit={functionName} but the form always performs the action even if in the onSubmit function I return false. Secondly ive been trying to useRef instead to dispatch the submit event programtically but nothing happens? I essentially have to do a server side call to get a config for the form values that gets posted, unfortunately the external API I use needs the form to be submitted in this way. Please any help would be greatly appreciated.
Attempt 1:
const performSubmit =() => {
//Using onSubmit and then only performing the return after the axios call is done
axiosCallFunction.then((res) => {
setConfig(res.data)
return true
}).catch((error)) => {
//Dont submit form
return false
})
}
return (
<form name="form" onSubmit={performSubmit} id="x1" method="POST" action="https://url.aspx" target="_top">
<input value={config.param}/>
<button type="submit"> Submit</button>
</form>)
Attempt 2
const formEl = useRef();
const performSubmit =() => {
//Currently not calling the submit on the form
formEl.current.dispatchEvent(new Event("submit"))
}
return (
<form name="form" ref={formEl} id="x1" method="POST" action="https://url.aspx" target="_top">
<input value={config.param}/>
<button onClick={performSubmit} />
</form>)
Essentially want to do some call to a server and get results back before I submit the form or perform the action for the form.
Have you tried:
formEl.current && formEl.current.submit();
?
Starting from React 17 you have to add cancelable and bubbles properties to your event. Otherwise, the solution from the accepted answer won't work. It's caused by some changes in event delegation.
formEl?.current.dispatchEvent(
new Event("submit", { cancelable: true, bubbles: true })
);
I found the answer here.
pass the event then prevent its default action
const performSubmit =(e) => {
// stop the form from actually submitting
e.preventDefault();
//Using onSubmit and then only performing the return after the axios call is done
axiosCallFunction.then((res) => {
setConfig(res.data)
return true
}).catch((error)) => {
//Dont submit form
return false
})
}
pass the event
return (
<form name="form" onSubmit={(e) => performSubmit(e)} id="x1" method="POST" action="https://url.aspx" target="_top">
<input value={config.param}/>
<button type="submit"> Submit</button>
</form>)
Try
form?.current.dispatchEvent(new Event("submit"));
I am using reactJs coupled with redux-form.
And also using the semantic ui react library
When i want to submit my form, i don't want my page to be refreshed. Instead i want to reset my form after the submission.
Unfortunately, i can't clear my input whereas i set the state to void the value.
/** Form component **/
<Form onSubmit={handleSubmit(this.handleSubmitAction)}>
<Field name="input" component={renderTitleInput} onChangeAction={this.handleInputChange} defaultValue={this.state.input} />
<input type="submit" name="submit" />
</Form>
/** HandleSubmit function **/
handleSubmitAction = (e) => {
this.setState({input:''})
}
The field remain filled after submitting the form.
Any suggestion ? thanks
What you created is an uncontrolled component, which means that update must be handled through the DOM. To do that you need to add the refattribute to get access to the DOM element in the form submit callback. Here is the changes you need to make.
<Form onSubmit={handleSubmit(this.handleSubmitAction)}>
<Field name="input" component={renderTitleInput} onChangeAction={this.handleInputChange} defaultValue={this.state.input} ref={(input) => this.input = input} />
<input type="submit" name="submit" />
</Form>
/** HandleSubmit function **/
handleSubmitAction = (e) => {
// This can be used when using controlled component.
//this.setState({input:''})
this.input.val = '';
}
But maybe what you want is to handle it as controlled component.
I had a similar issue and I want to clear input after submit button is clicked & use the functional component. here is an example of how I reset the value of input field after submitting.
Set value of the input to state value & when state value is reset input field get reset and the field is empty.
const [cancelInput, setCancelInput] = useState('');
const inputChange = (event, data) => {
// console.log(data)
setCancelInput(data.value)
}
const handleClick = (e) => {
setCancelInput(e.target.value)
}
<Input onChange={inputChange} placeholder='Type cancel here' value={cancelInput}/>
<Button color='red' onClick={handleClick} disabled={cancelInput !== 'cancel'} loading={loading} >Cancel</Button>