How to fetch input from text box and print in React? - reactjs

I am new to React trying to write a very simple project that fetches input of both text boxes and when button is clicked, the 'data' in text boxes is printed on paragraph.
How do I fetch text's in input text boxes when button is clicked?
class Input extends Component {
state = {
tagged: false,
message: '',
}
handleClick(e) {
this.setState({tagged: true});
e.preventDefault();
console.log('The link was clicked.');
}
render() {
return (
<div id="id" style={divStyle}>
<p> hello </p>
<input
style = {textStyle}
placeholder="user#email.com"
type="text">
</input>
<input
style = {textStyle}
placeholder="tag"
type="text">
</input>
<button
onClick={(e) => this.handleClick(e)}
style={buttonStyle}>
{this.state.tagged ? 'Tagged' : 'Tag ' }
</button>
<p>
{this.state.tagged ? 'Clicked' : 'Still' }
</p>
</div>
)
}
}

You can add onChange event handler in each input.
class Input extends Component {
state = {
tagged: false,
message: '',
input1: '',
input2: '',
}
handleClick(e) {
// access input values in the state
console.log(this.state) // {tagged: true, input1: 'text', input2: 'text2'}
this.setState({tagged: true});
e.preventDefault();
console.log('The link was clicked.');
}
handleInputChange = (e, name) => {
this.setState({
[name]: e.target.value
})
}
render() {
return (
<div id="id" style={divStyle}>
<p> hello </p>
<input
style = {textStyle}
placeholder="user#email.com"
type="text"
onChange={(e) => this.handleInputChange(e, 'input1')}
>
</input>
<input
style = {textStyle}
placeholder="tag"
type="text"
onChange={(e) => this.handleInputChange(e, 'input2')}
>
</input>
<button
onClick={(e) => this.handleClick(e)}
style={buttonStyle}>
{this.state.tagged ? 'Tagged' : 'Tag ' }
</button>
<p>
{this.state.tagged ? 'Clicked' : 'Still' }
</p>
</div>
)
}
}

There are two different ways of working with react inputs - you can either make them controlled or uncontrolled. When you say fetch text from inputs, this is called uncontrolled components and means that form data is handled by the DOM itself and not by react.
This is achieved by using ref and literally getting a reference to your input and fetching its value when you need it. you can read more about this approach in react docs.
According to react docs, it is recommended using controlled components
In most cases, we recommend using controlled
components to implement forms. In a controlled
component, form data is handled by a React component.
This means that you don’t use references to the inputs and instead handle changes of your inputs with an event handler and update state with the new values that the user has entered into the input fields. According to react docs here is how react handles form with controlled components:
the React component that
renders a form also controls what happens in that form on subsequent
user input. An input form element whose value is controlled by React in this way is called a “controlled component”.
In your case you can do this if you choose controlled inputs:
class ControlledInput extends React.Component {
constructor(props) {
super(props);
this.state = {
tagged: false,
firstInput: '',
secondInput: ''
}
this.handleChange = this.handleChange.bind(this);
}
handleChange(event) {
this.setState({ [event.target.name]: event.target.value });
}
handleClick(e) {
this.setState({ tagged: true });
e.preventDefault();
console.log('The link was clicked.');
}
render() {
const { firstInput, secondInput, tagged } = this.state;
return (
<div id="id">
{tagged && <p>{firstInput} {secondInput}</p> }
<input
value={firstInput}
name="firstInput"
onChange={this.handleChange}
type="text" />
<input
value={secondInput}
name="secondInput"
onChange={this.handleChange}
type="text" />
<button onClick={(e) => this.handleClick(e)}>
{tagged ? 'Tagged' : 'Tag '}
</button>
</div>
)
}
}
Here you put the inputs' values on state and update state when the user writes something in your inputs. If you however want to use uncontrolled components you can do it this way:
class UncontrolledInput extends React.Component {
state = {
tagged: false,
message: '',
}
handleClick(e) {
e.preventDefault();
const messageFromInputs = `${this.firstInput.value} ${this.secondInput.value}`;
this.setState({ tagged: true, message: messageFromInputs });
}
render() {
return (
<div id="id">
<p>{this.state.message}</p>
<input ref={(input) => this.firstInput = input} type="text" />
<input ref={(input) => this.secondInput = input} type="text" />
<button onClick={(e) => this.handleClick(e)}>
{this.state.tagged ? 'Tagged' : 'Tag '}
</button>
<p>
{this.state.tagged ? 'Clicked' : 'Still'}
</p>
</div>
)
}
}
Here you will actually fetch values from your inputs when the button is clicked.
I made a working example with both ways on codesandbox.

Related

React form error: Form submission canceled because the form is not connected

I have a form inside a class component. When I submit the form, I get a warning Form submission cancelled because the form is not connected. There are no errors—just a warning.
I have linked it to my netlify site. I have added all the form data properties that are required to send the data to netlify.
I have used styled-components for styling.
Not sure, what I am missing.
class ContactThreeForm extends React.Component {
constructor(props) {
super(props);
this.state = {
name: "",
email: "",
phone: "",
message: "",
error: false,
};
}
formSubmit() {
if (
this.state.name === "" ||
this.state.email === "" ||
this.state.phone === "" ||
this.state.message === ""
) {
this.setState({ error: true });
} else {
this.setState({ error: false });
}
this.forceUpdate();
}
check(val) {
if (this.state.error && val === "") {
return false;
} else {
return true;
}
}
render() {
return (
<ContactForm>
<Heading>Get In Touch</Heading>
<Separator />
<form
name="contact"
method="POST"
netlify-honeypot="bot-field"
data-netlify="true"
data-netlify-recaptcha="true"
>
<InputElement>
<Input
type="text"
defaultValue={this.state.name}
className={`name ${this.check(this.state.name) ? "" : "error"}`}
placeholder="Name"
onChange={(e) => this.setState({ name: e.target.value })}
/>
</InputElement>
<InputElement>
<Input
type="text"
defaultValue={this.state.email}
className={`email ${this.check(this.state.email) ? "" : "error"}`}
placeholder="Email"
onChange={(e) => this.setState({ email: e.target.value })}
/>
</InputElement>
<InputElement>
<Input
type="text"
defaultValue={this.state.phone}
className={`phone ${this.check(this.state.phone) ? "" : "error"}`}
placeholder="Phone"
onChange={(e) => this.setState({ phone: e.target.value })}
/>
</InputElement>
<InputElement>
<Textarea
placeholder="Message"
defaultValue={this.state.message}
className={`message ${
this.check(this.state.message) ? "" : "error"
}`}
onChange={(e) => this.setState({ message: e.target.value })}
/>
</InputElement>
<Submit onClick={() => this.formSubmit()}>
<span>Submit</span>
</Submit>
</form>
</ContactForm>
);
}
}
The browser's default handling of a form submission is to make an HTTP POST request to the server and reload the page with whatever is in the response (which may or may not even be content the browser can render). This is almost never what you want in a single page application, because your entire app and all of its state is simply discarded.
Instead of wiring up the form submit as a click handler on the submit button, you should instead wire it up as the onSubmit event of the form. You also want to call preventDefault() on the event, which prevents the native browser behavior. The button doesn't need a click handler at all as long as it has the attribute type="submit" (presumably, inside of your Submit component, there is a regular button element).
formSubmit(event) {
event.preventDefault();
// your submit logic
}
render() {
// ...
<form onSubmit={(event) => this.formSubmit(event)}
// ... Inside `Submit` should be something like:
<button type="submit" />
</form>
}

Not able to update form data in React

I am using react to accept input from the user. And when the user submits I want to get rid of the form and display the user input data.
I am not able to see the user input data on my result page. I have uploaded the screenshots and the code below.
class Form extends React.Component {
constructor(props){
super(props)
this.state = {isFormOn: true, isResult: false , firstname: "", lastname: ""};
this.handleClick = this.handleClick.bind(this);
this.handleChange = this.handleChange.bind(this);
}
handleClick(){
this.setState(state => ({
isFormOn: !state.isFormOn,
isResult: !state.isResult
}));
}
handleChange({ event }) {
this.setState({
[event.target.name]: event.target.value
});
}
render(){
return(
<div>
{ this.state.isFormOn && (
<div>
First name :
<input type="text" name="firstname" onChange={this.handleChange} /><br />
Last name :
<input type="text" name="lastname" onChange={this.handleChange} /><br />
<br />
<button onClick={this.handleClick}>
{this.state.isFormOn ? 'ON' : 'OFF'}
</button>
</div>
)}
{ this.state.isResult && (
<div>
<h4>The name entered is : {this.state.firstname} {this.state.lastname} </h4>
<button onClick={this.handleClick}>
{this.state.isFormOn ? 'ON' : 'OFF'}
</button>
</div>
)}
</div>
);
}
}
ReactDOM.render(
<Form />,
document.getElementById('root')
);
Render form to accept user input
Result of the user entered information
Your event handler (handleChange) is destructuring the event object, and trying to extract a property called event from it, which doesn't exist.
You need to use the event object directly instead:
handleChange(event) {
this.setState({
[event.target.name]: event.target.value
});
}

Can't clear input field after pressing button

class CategoryBox extends Component {
constructor(props) {
super(props);
this.state = {
newCategoryTitle: '',
errorMsg: null,
updateCategoryTitle: '',
};
this.handleCreateCategory = this.handleCreateCategory.bind(this);
this.handleUpdateCategory = this.handleUpdateCategory.bind(this);
}
...
...
handleUpdateCategory(e) {
e.preventDefault();
this.setState({
updateCategoryTitle: ''
});
}
render() {
return (
//...
<form>
<input
type={'text'}
className={styles.tabSmallField}
placeholder={ category.name }
onChange={(e) => { this.setState({ updateCategoryTitle: e.target.value }); }} />
<button type="submit" onClick={this.handleUpdateCategory}>Update</button>
</form>
//...
}
}
I want to clear input text field after pressing the button.
It looks like it enters into "handleUpdateCategory(e)" after pressing the button. But it does not clear the input field above the button.
How can I clear the input text field?
Answer is in comment.
It didn't clear because you never bind the state value to your <input>. Change it like this <input value={this.state.updateCategoryTitle} ...other props... />

ReactJS - pass input values from child to parent

child component
import React, { Component } from 'react'
export default class Login extends Component {
constructor (props) {
super(props);
this.state = {Id: '',name: '',gender: ''};
this.show = this.show.bind(this);
}
show (event) {
if (this.state.Id === "123456" && this.state.name !== '' && this.state.gender !== '') {
this.props.show();
alert('you are login');
console.log('A ID was submitted: ' + this.state.Id);
console.log('A Name was submitted: ' + this.state.name);
console.log('A Gender was submitted: ' + this.state.gender);
} else {
alert('Please enter your valid id,Your Name & Gender');
}
event.preventDefault();
}
render () {
return (
<div className="login">
<form onSubmit={ this.show.bind(this) }>
<div>
<label>Your ID:</label>
<input type="text" onChange={ event => this.setState({ Id: event.target.value }) } placeholder="Enter your ID" />
</div>
<br />
<div>
<label>Your Name:</label>
<input type="text" onChange={ event => this.setState({ name: event.target.value }) } placeholder="Enter your Name" />
</div>
<br />
<div>
<label>Your Gender:</label>
<label>Female:</label>
<input type="radio" name="gender" value="Female" onChange=
{ event => this.setState({ gender: event.target.value }) } />
<label>Male:</label>
<input type="radio" name="gender" value="Female" onChange={ event => this.setState({ gender: event.target.value }) } />
</div>
<input type="submit" value="Submit" onClick={ this.props.comingvalue } />
</form>
</div>
)
}
}
parent component
class App extends Component {
constructor (props) {
super(props);
this.state = { Id: '', name: '', gender: '' };
}
getvalue () {
console.log('getting values as props');
this.setState({ Id: this.state.Id });
this.setState({ name: this.state.name });
this.setState({ gender: this.state.gender });
}
render () {
return (
<div className="App">
<Login comingvalue={ this.getvalue } />
<button type="button" className="btn btn-primary" onClick=
{ this.handleLogin }>Sign In</button>
</div>
);
}
}
export default App;
now here is the my question i want that when i enter value in my child component i get those values in parent compnent how i can get this please help..'i thing you peeple should know that i cut alot of code from above code there is possibilty of any other error but i want to know only one thing which i mention above i want child coponents value in parent component.. please suggest me right solution..thanks
Just a pointer for future posts: the less code the better and please, for the love of God, make sure the formatting is correct.
A standard pattern in React for passing information back up the tree is to pass children a callback as a prop.
parent
class Parent extends React.Component {
onChildCallback = (data) => {
alert(data)
}
render() {
return (
<div>
...
<Child onAction={this.onChildCallback}/>
</div>
)
}
}
child
class Child extends React.Component {
render() {
return (
<button onClick={() => this.props.onAction('hello from the child')}>
Click Me!
</button>
)
}
}
this is, of course, simplified, but you can extend it however you like. Some things to watch out for:
make sure you're either binding the callback in the parent or using arrow functions (in this case, I'm using a ES7 class property)
if you need data from a child of a child, you need to chain these... you can get away with using context, but ... don't. Just don't.

Controlled React form reloads instead of submitting after manually submitting from keyDown event

I have a controlled form. If you type in the textarea and click the submit button it works. However im trying to also make the form submit when you press enter while typing. The following instead of submitting the form reload the page.
import React from 'react';
class PostComment extends React.Component {
constructor(props) {
super(props);
this.state = { value: '' };
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.keyDown = this.keyDown.bind(this);
}
handleChange(e) {
e.preventDefault();
this.setState({ value: e.target.value });
}
keyDown(e) {
if (e.keyCode == 13 && e.shiftKey == false) {
e.preventDefault();
this.myFormRef.submit();
}
}
handleSubmit(e) {
e.preventDefault();
const text = e.target.body.value;
// Call backend here
e.target.body.value = '';
}
render() {
return (
<form onSubmit={this.handleSubmit} ref={el => (this.myFormRef = el)}>
<textarea
rows="3"
name="body"
onKeyDown={this.keyDown}
value={this.state.value}
onChange={this.handleChange}
/>
<button className="btn" type="submit">
Comment
</button>
</form>
);
}
}
export default PostComment;
My first guess would be that *.submit() does not trigger the onSubmit event, see also a similar question here, which suggests calling the onsubmit handler directly (in this case this would mean e.g. calling this.handleSubmit with a "fake" event payload) ... Another way you could work around this problem would be to trigger the submit button click rather than the form submit on enter:
keyDown () {
if (e.keyCode == 13 && e.shiftKey == false) {
e.preventDefault();
this.button.click();
}
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<textarea
rows="3"
name="body"
onKeyDown={this.keyDown}
value={this.state.value}
onChange={this.handleChange}
/>
<button className="btn" type="submit" ref={el => (this.button = el)}>
Comment
</button>
</form>
);
}

Resources