how to set props values of controls in react js - javascript

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

Related

How to pre-populate fields on click of a button in react?

I am trying to pre-populate the form fields, that are replicated, from the fields that are already filled. On clicking the "Add fields" button, the fields are getting replicated. But I want them to get pre-populated using the data filled in the already existing fields.
From where can I get hold of the input values?
import './style.css';
export default function App() {
const [inputFields, setInputFields] = useState([{ name: '', age: '' }]);
const addFields = (e) => {
e.preventDefault();
let newField = { name: "", age: '' };
setInputFields([...inputFields, newField]);
};
const handleFormChange = (index, e) => {
let data=[...inputFields];
data[index][e.target.name]=[e.target.value];
setInputFields(data);
}
return (
<div>
<form>
{inputFields.map((input, index) => {
return (
<div key={index}>
<input
type="text"
name="name"
placeholder="Enter name"
value={input.name}
onChange={(e)=>handleFormChange(index, e)}
/>
<input
type="number"
name="age"
placeholder="Enter Age"
value={input.age}
onChange={(e)=>handleFormChange(index, e)}
/>
<br />
<br />
</div>
);
})}
<button onClick={addFields}>Add Field</button>
<br />
</form>
</div>
);
}```
You will need to track changes in input with an onChange handler.
Also, you are not setting values from the last input fields anywhere to be able to duplicate them. The below code might work as you expect:
const { useState } = React;
function App() {
const [inputFields, setInputFields] = useState([{ name: '', age: '' }]);
const addFields = (e) => {
e.preventDefault();
const temp = inputFields.slice()
, length = temp.length - 1
, { name, age } = temp[length]
// Set value from last input into the new field
let newField = { name, age }
setInputFields([...temp, newField])
}
, handleChange = (index, event) => {
const temp = inputFields.slice() // Make a copy of the input array first.
inputFields[index][event.target.name] = event.target.value // Update it with the modified values.
setInputFields(temp) // Update the state.
};
return (
<div>
<form>
{inputFields.map((input, index) => {
return (
<div key={index}>
<input
onChange={e => handleChange(index, e)}
value={input.name}
type="text"
name="name"
placeholder="Enter name"
/>
<input
onChange={e => handleChange(index, e)}
value={input.age}
type="number"
name="age"
placeholder="Enter Age"
/>
<br />
<br />
</div>
);
})}
<button onClick={addFields}>Add Field</button>
<br />
</form>
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
You have to set the value property on the input field to populate, e.g:
<input
value={input.name}
type="text"
name="name"
placeholder="Enter name"
/>

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)}
/>

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;

Storing each input's data in its respective state

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 });
};

React change input value onChange

This is my SearchForm.js, handleKeywordsChange must handle input keywords changes
import React from 'react';
import ReactDOM from 'react-dom';
class SearchForm extends React.Component {
constructor(props) {
super(props)
this.state = {
keywords: '',
city: '',
date: ''
}
//this.handleChange = this.handleChange.bind(this)
//this.handleSubmit = this.handleSubmit.bind(this)
this.handleKeywordsChange = this.handleKeywordsChange.bind(this);
}
handleKeywordsChange(e) {
console.log(1);
this.setState({
value: e.target.value
});
}
render() {
return (
<form className='form search-form' onSubmit={this.handleSubmit}>
<div className="form-row">
<div className="form-group col-md-5">
<label htmlFor="keywords">Keywords</label>
<input type="text" className="form-control" name="keywords" id="keywords" placeholder="Keywords" onChange={this.handleKeywordsChange} value={this.state.keywords} />
</div>
<div className="form-group col-md-5">
<label htmlFor="city">City</label>
<input type="text" className="form-control" name="city" id="city" placeholder="City" onChange={this.handleChange} value={this.state.city} />
</div>
<div className="form-group col-md-2">
<label htmlFor="date">Date</label>
<select className="form-control" name="date" id="date" onChange={this.handleChange} value={this.state.date}>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
</div>
</div>
<div className="form-row">
<div className="form-group col-md-12">
<input id='formButton' className='btn btn-primary' type='submit' placeholder='Send' />
</div>
</div>
</form>
)
}
}
export { SearchForm }
The problem is input keywords doesn't change its value when I'm typing. What's wrong?
Make a common function for changing the state for input values.
handleInputChange(e) {
this.setState({
[e.target.name]: e.target.value
});
}
Make sure you mention name in every input tag. e.g:
<input name="someUniqueName" value={this.state.someState} onChange={this.handleInputChange} />
React Hooks makes this so much easier!!!
import React, {useState} from 'react'
function SearchForm () {
const [input, setInput] = useState("")
return (
<div className="SearchForm">
<input
value={input}
onChange={(e) => setInput(e.target.value)} />
</div>
)
}
It should be :
this.setState({
keywords: e.target.value
});
Your handleKeywordsChange function sets the state value whereas you are using this.state.keywords as value for input
handleKeywordsChange(e) {
console.log(1);
this.setState({
keywords: e.target.value
});
}
class InputKeywordCheck {
state = {
email: '',
}
handleInputChange (e) {
const {name, value } = e.target;
this.setState({[name]: value});
}
render() {
return (
<input name="email" value={this.state.email} onChange={this.handleInputChange} />
)
} }
I believe that you need to do something like this:
handleKeyWordsChange (e) {
this.setState({[e.target.name]: e.target.value});
}

Categories