Storing each input's data in its respective state - javascript

I have three inputs, and I want each input's data to be stored in a state. For example, the name input should be stored in the name state, because I'll need it later to push the three states' values in a firebase database.
I used the onChange function to store the data, but I didn't know how to make each input's function relative to the state I want to put it in.
import React from "react";
import ReactDOM from "react-dom";
export default class Inputs extends React.Component {
constructor(props) {
super(props);
this.state = {
name: "",
email: "",
age: ""
};
}
handleChange = e => {
this.setState({ name: e.target.value });
};
render() {
return (
<div>
<form>
<label>
name:
<input type="text" name="name" onChange={this.handleChange} />
</label>
<label>
email:
<input type="text" name="email" onChange={this.handleChange} />
</label>
<label>
age:
<input type="text" name="age" onChange={this.handleChange} />
</label>
<input type="submit" value="Submit" />
</form>
<textarea value={this.state.value} onChange={this.handleChange} />
<button onClick={() => this.props.onClick(this.state.value)}>
Add task
</button>
</div>
);
}
}

getChanges = (e) => {
console.log(e);
this.setState({[e.target.name]: e.target.value}, function () {
console.log(this.state)
})
};
call this function,
<Input onChange={(e) => this.getChanges(e)} name={'name'}
value={this.state.name} placeholder={'Name'}/>

You can pass key and value
<input type="text" name="name" onChange={(event)=>this.handleChange(event,'name')} />
and in your function you can do something like this
handleChange = (e,key) => {
this.setState({ [key] : e.target.value });
};

Related

two select forms on one page [reactjs]

I need help by a simple question:
how i can use two select forms on one site with one handleChange function? i have two select forms but every-time i am using one after the other one the value will be overwritten. Should i separate the handleChange function? I dont want to work with an npm like react select. Is anyone able to help me out here? Im really stuck on this
import React from "react";
import axios from "./axios.js";
import { useState } from "react";
import Select from "react-select";
import Creatives from "./creatives";
import FormatType from "./formattype";
export default class Form extends React.Component {
constructor(props) {
super(props);
this.state = {
value: "",
value1: "",
manager: "",
gpNummer: "",
caNummer: "",
gpNummer: "",
advertiser: "",
agency: "",
campaignName: "",
formatType: "",
startDate: "",
creative: "",
enddate: "",
error: false,
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}
updateField(e) {
this.setState({
[e.target.name]: e.target.value,
});
}
/*
submit1() {
axios
.post("/Login", { mail: this.state.mail, password: this.state.password })
.then((response) => {
console.log(response.data);
if (response.data.success) {
/*location.replace('/');
} else {
this.setState({ error: response.data.error });
}
});
}
submit2() {
axios
.post("/Login", { mail: this.state.mail, password: this.state.password })
.then((response) => {
console.log(response.data);
if (response.data.success) {
/*location.replace('/');
} else {
this.setState({ error: response.data.error });
}
});
}
*/
handleChange(e) {
this.setState({ value: e.target.value });
}
handleSubmit(e) {
const {
gpNummer,
caNummer,
advertiser,
creative,
agency,
campaignName,
formatType,
startDate,
enddate,
} = this.state;
e.preventDefault();
}
render() {
return (
<div className="Main">
<div className="allforms">
<span id="Linetitle">New LineItem:</span>
{this.state.error && <div className="error">{this.state.error}</div>}
<label> Manager </label>
<select manager={this.state.manager} onChange={this.handleChange}>
<option manager="Katja">Katja</option>
<option manager="Seba">Seba</option>
<option value="aylina">aylina</option>
<option value="Christina">Christina</option>
</select>
<label> GP-Nummer </label>
<input
type="text"
onChange={(e) => this.updateField(e)}
name="gpNummer "
placeholder=" GP-Nummer "
/>
<label> CA-Nummer </label>
<input
type="text"
onChange={(e) => this.updateField(e)}
name="caNummer "
placeholder=" Fill in CA-Nummer "
/>
<label> Werbetreibender </label>
<input
type="text"
onChange={(e) => this.updateField(e)}
name="advertiser"
placeholder=" Fill in Werbetreibender "
/>
<label> Agentur </label>
<input
type="text"
onChange={(e) => this.updateField(e)}
name="agency "
placeholder=" Fill in Agentur"
/>
<label> Media Campaign Name </label>
<input
type="text"
onChange={(e) => this.updateField(e)}
name="campaignName "
placeholder=" Fill in Campaign Name"
/>
<label> Formattyp </label>
{/* <div className="select"> <FormatType /></div>*/}
<select value1={this.state.creative} onChange={this.handleChange}>
<option value1="MR">MR</option>
<option value1="premiumAdbundle">premiumAdbundle</option>
<option value1="adBundle">AdBundle</option>
<option value1="fireplace">Fireplace</option>
</select>
<label> Creative </label>
<select value={this.state.formatType} onChange={(e)=>this.handleChange(e)}>
<option value="native">native</option>
<option value="display">display</option>
<option value="advertorial">advertorial</option>
<option value="mobile">mobile</option>
</select>
{/*<div className="select"><Creatives /></div>*/}
<label>Start Date </label>
<input
type="date"
onChange={(e) => this.updateField(e)}
name="startDate"
placeholder=" Fill in Formattyp"
/>
<label>End Date </label>
<input
type="date"
onChange={(e) => this.updateField(e)}
name="enddate"
placeholder=" Fill in Formattyp"
/>
<input
onClick={(e) => this.submit1(e)}
type="submit"
value="Save to List"
/>
<input
onClick={(e) => this.submit2(e)}
type="submit"
value="Push to gam"
/>
</div>
</div>
);
}
}
You can write your handlechange this way :
onChange={e => this.handleChange(e, customParam)}>
This way, you can add a condition check on your handlechange function on the second parameter, and change behaviour as needed.
As someone already suggested, you can write a single function that accepts two parameters (the event and the state that you change).
Also, if you want, you can use a single State, but as an Array. In you case you can create the state like this:
this.state{
Form: {
State1: '',
State2: '',
},
// other states
}
and then you can access to a single state with Form.State1.
So, you can write a function like the following one to update the single state:
const updateField = (name, value) => {
//Change the state with the new field updated
const newData = { ...Form, [name]: value };
this.setState({Form: newData});
};
And on the single component, to update the state, you have to call on onChange, I show you an example with input:
<input
type="text"
onChange={(e) => this.updateField(e)}
name="gpNummer "
placeholder=" GP-Nummer "
value={this.state.Form.State1}
onChange={ev => updateField(ev.target.name, ev.target.value)}
/>

how to set props values of controls in react js

I am new to react. I have almost 15 input controls on UI. Some are dropdowns, some are textboxes, couple of calender controls and radio buttons. I want to retrive all values before submitting a page. Do I need to define 15 props in state object of component for 15 inputs? is there any way to have it in one object.
Also how to set the values of each control. For example for textbox I know, its like
<input type="text" name="username" className="form-control" id="exampleInput" value={this.props.name} onChange={this.handleChange} placeholder="Enter name"></input>
How to handle same for dropdown,calender and radio buttton. Thanks in advance.
Normally, these wouldn't be props, they'd be state (which is different). You can use objects in state. If you're doing a class-based component (class YourComponent extends React.Component), state is always an object you create in the constructor and update with setState. If you're doing this in a function component, typically you use separate state variables for each thing (const [name, setName] = useState("");), but you can use an object if you prefer. There's more about state in the documentation.
That said, if you only want the values when you take an action, you could make the inputs "uncontrolled."
Here's a three-input example using a class component:
class Example extends React.Component {
constructor(props) {
super(props);
this.state = {
firstName: "",
lastName: "",
about: ""
};
this.handleChange = this.handleChange.bind(this);
}
handleChange({target: {name, value}}) {
this.setState({[name]: value});
}
render() {
const {firstName, lastName, about} = this.state;
const {handleChange} = this;
return <div>
<div>
<label>
First name:
<br/>
<input type="text" value={firstName} name="firstName" onChange={handleChange} />
</label>
</div>
<div>
<label>
Last name:
<br/>
<input type="text" value={lastName} name="lastName" onChange={handleChange} />
</label>
</div>
<div>
<label>
About you:
<br />
<textarea value={about} name="about" onChange={handleChange} />
</label>
</div>
<div>{firstName} {lastName} {(firstName || lastName) && about ? "-" : ""} {about}</div>
</div>;
}
}
ReactDOM.render(<Example/>, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script>
Here's one using a functional component with discrete state items (usually best):
const { useState } = React;
const Example = () => {
const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
const [about, setAbout] = useState("");
// There's are lots of ways to do this part, this is just one of them
const handleChange = ({target: {name, value}}) => {
switch (name) {
case "firstName":
setFirstName(value);
break;
case "lastName":
setLastName(value);
break;
case "about":
setAbout(value);
break;
}
};
return <div>
<div>
<label>
First name:
<br/>
<input type="text" value={firstName} name="firstName" onChange={handleChange} />
</label>
</div>
<div>
<label>
Last name:
<br/>
<input type="text" value={lastName} name="lastName" onChange={handleChange} />
</label>
</div>
<div>
<label>
About you:
<br />
<textarea value={about} name="about" onChange={handleChange} />
</label>
</div>
<div>{firstName} {lastName} {(firstName || lastName) && about ? "-" : ""} {about}</div>
</div>;
}
ReactDOM.render(<Example/>, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script>
Here's one using a functional component with an object in state:
const { useState } = React;
const Example = () => {
const [data, setData] = useState({firstName: "", lastName: "", about: ""});
const handleChange = ({target: {name, value}}) => {
setData(current => ({...current, [name]: value}));
};
const {firstName, lastName, about} = data;
return <div>
<div>
<label>
First name:
<br/>
<input type="text" value={firstName} name="firstName" onChange={handleChange} />
</label>
</div>
<div>
<label>
Last name:
<br/>
<input type="text" value={lastName} name="lastName" onChange={handleChange} />
</label>
</div>
<div>
<label>
About you:
<br />
<textarea value={about} name="about" onChange={handleChange} />
</label>
</div>
<div>{firstName} {lastName} {(firstName || lastName) && about ? "-" : ""} {about}</div>
</div>;
}
ReactDOM.render(<Example/>, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script>
Here is the sample code, I used in my application.
class CreditCardForm extends React.Component {
constructor() {
super()
this.state = {
name: '',
address: '',
ccNumber: ''
}
}
handleChange(e) {
// If you are using babel, you can use ES 6 dictionary syntax
// let change = { [e.target.name] = e.target.value }
let change = {}
change[e.target.name] = e.target.value
this.setState(change)
}
render() {
return (
<form>
<h2>Enter your credit card details</h2>
<label>
Full Name
<input type="name" onChange={(e)=>this.handleChange(e)} value={this.state.name} />
</label>
<label>
Home address
<input type="address" onChange={(e)=>this.handleChange(e)} value={this.state.address} />
</label>
<label>
Credit card number
<input type="ccNumber" onChange={(e)=>this.handleChange(e)} maxlength="16" value={this.state.ccNumber} />
</label>
<button type="submit">Pay now</button>
</form>
)
}
}
You can set name for input and update state base on event.target.name and event.target.value
constructor() {
super();
this.state = {
text: "",
select: "",
radio: ""
};
}
handeInput = e => {
this.setState({
[e.target.name]: e.target.value
});
};
render() {
console.log(this.state);
return (
<div className="App">
<input
onChange={this.handeInput}
type="input"
name="text"
value={this.state.text}
/>
<select
name="select"
onChange={this.handeInput}
value={this.state.select}
>
<option value="option1">option1</option>
<option value="option2">option2</option>
</select>
<input
type="radio"
name="radio"
value="Option1"
checked={this.state.radio === "Option1"}
onChange={this.handeInput}
/>
Option1
<input
type="radio"
name="radio"
value="Option2"
checked={this.state.radio === "Option2"}
onChange={this.handeInput}
/>
Option2
</div>
);
}
You can check here CodeSandBox Hope it helps

Can't uncheck checkbox using react

This checkbox is permanently checked, I want the pre selected checkbox to change the boolean state. I'm currently using this handleChange method to deal with text inputs. Do I have to create another method to deal with the checkbox or can I add to the existing method?
state = {
billingEmail:'',
billingAddressSame: true,
}
handleChange = input => e => {
this.setState({[input]: e.target.value})
}
<input
className="col-sm-12"
type="email"
placeholder="Email"
onChange={handleChange('billingEmail')}
defaultValue={values.billingEmail}
/>
<label className="col-sm-12" style={{paddingLeft: "0"}}>
<input
type="checkbox"
checked={values.billingAddressSame}
onChange={handleChange('billingAddressSame')}
/>
Same as company address
</label>
Change your handleChange function to
handleChange = input => e => {
this.setState({[input]: !this.state[input]})
}
You can control your checkbox and input by a single method.
See
Constructor and handle change function-
constructor(props) {
super(props);
this.state = {
isGoing: true,
numberOfGuests: 2
};
this.handleInputChange = this.handleInputChange.bind(this);
}
handleInputChange(event) {
const target = event.target;
const value = target.type === 'checkbox' ? target.checked : target.value;
const name = target.name;
this.setState({
[name]: value
});
}
And in your render function -
render() {
return (
<form>
<label>
Is going:
<input
name="isGoing"
type="checkbox"
checked={this.state.isGoing}
onChange={this.handleInputChange} />
</label>
<label>
Number of guests:
<input
name="numberOfGuests"
type="number"
value={this.state.numberOfGuests}
onChange={this.handleInputChange} />
</label>
</form>
);
}
See this for more info
try this and let me know, its working fine for me
import React, { Component, Fragment } from 'react';
class SignUp extends Component{
state = {
billingEmail:'',
billingAddressSame: true,
}
render(){
return(<Fragment>
<input className="input" type="email" className="col-sm-12" placeholder="Email" value={this.state.billingEmail} onChange={e => this.setState({billingEmail: e.target.value})}/>
<label className="col-sm-12" style={{paddingLeft: "0"}}>
<input type="checkbox" value="CheckBox1" checked={this.state.billingAddressSame} onChange={e => this.setState({ billingAddressSame: !this.state.billingAddressSame })} />
Same as company address
</label>
</Fragment>)
}
}
export default SignUp;

How to process onChange and change focus to new <Field>?

I'm using Formik (with withFormik()) and want to check a <Field> as a user types in it - after it has 4 characters in it, I want to focus on the next field so they can keep typing without having to move to the next field.
So my InnerForm has:
<Field
type="text"
name="credit1"
inputmode="numeric"
maxlength="4" />
<Field
type="text"
name="credit2"
inputmode="numeric"
maxlength="4" />
And my FormikInnerFormContainer = withFormik(...) has a validationSchema.
How could I catch changes on the first field, and move focus to the 2nd field if the first has 4 characters in?
I tried to override the onChange, but couldn't figure out how to update the Field contents with each character the user types.
You might use like this in Formik.
focusChange(e) {
if (e.target.value.length >= e.target.getAttribute("maxlength")) {
e.target.nextElementSibling.focus();
}
...
//Example implementation
import React from "react";
import { Formik } from "formik";
export default class Basic extends React.Component {
constructor(props) {
super(props);
this.inputRef = React.createRef();
this.focusChange = this.focusChange.bind(this);
}
focusChange(e) {
if (e.target.value.length >= e.target.getAttribute("maxlength")) {
e.target.nextElementSibling.focus();
}
}
render() {
return (
<div>
<h1>My Form</h1>
<Formik
initialValues={{ name: "" }}
onSubmit={(values, actions) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
actions.setSubmitting(false);
}, 1000);
}}
render={props => (
<form onSubmit={props.handleSubmit} ref={this.inputRef}>
<input
type="text"
onChange={props.handleChange}
onBlur={props.handleBlur}
value={props.values.name}
name="name"
maxlength="4"
onInput={e => this.focusChange(e)}
/>
<input
type="text"
onChange={props.handleChange}
onBlur={props.handleBlur}
value={props.values.lastName}
name="lastName"
maxlength="4"
onInput={this.focusChange}
/>
<button type="submit">Submit</button>
</form>
)}
/>
</div>
);
}
}
In vanilla javascript you can do this:
document.querySelectorAll('input').forEach(function(input) {
input.addEventListener('keyup', function() {
if(input.value.length >= input.getAttribute('maxlength'))
input.nextElementSibling.focus();
});
})

Need to get the multiple form elements in uncontrolled components in reactjs

i am trying to get the multiple form fields input values and sending that to server. But i am only able to get the last field's value on submit.
I am using uncontrolled component because i am trying to editing the form and then updating it.Please help me out to get all the form details entered in the form.
import React from 'react';
import axios from 'axios';
class Update extends React.Component {
constructor(props) {
super(props);
this.state = {
info:''
};
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(event) {
event.preventDefault();
console.log(event);
alert(event);
}
componentDidMount(){
let self = this;
axios.get('http://localhost:8080/studentById')
.then(function(data) {
//console.log(data);
self.setState({info:data.data});
});
}
render() {
return (
<div>
<form onSubmit={this.handleSubmit} >
<label className="w3-label w3-text-blue w3-large w3-margin-0 ">
First Name:
<input autoFocus type="text" className="w3-input w3-border" defaultValue={this.state.info.Firstname} ref={(input) => this.input = input} required />
</label>
<label className="w3-label w3-text-blue w3-large">
Last Name:
<input type="text" className="w3-input w3-border" defaultValue={this.state.info.Lastname} ref={(input) => this.input = input} required />
</label>
<input className="w3-btn-block w3-blue w3-margin-bottom w3-large" type="submit" value="Submit" />
</div>
)};
}
In your code, you assign all refs to the same variable. (your code simplified for showing what I mean)
First Name:
<input ref={(input) => this.input = input} />
Last Name:
<input ref={(input) => this.input = input} />
Instead use different variable for different input fields:
First Name:
<input ref={(input) => this.firstNameInput = input} />
Last Name:
<input ref={(input) => this.lastNameInput = input} />
You should use different property names for each input inside refs callbacks (currently you override this.input so it points to the last input):
<input autoFocus type="text" className="w3-input w3-border" defaultValue={this.state.info.Firstname} ref={(input) => this.input1 = input} required />
<input autoFocus type="text" className="w3-input w3-border" defaultValue={this.state.info.Firstname} ref={(input) => this.input2 = input} required />
Then inside your component methods you can access value of an input this way:
let inputValue = this.input1.value;

Categories