React - How to get input from looped <form>? - javascript

I am new on React.
I have a condition which is to loop the form, please help me
Here is the code:
this.state.products.map(product => {
<form onSubmit={this.handleSubmit}>
<select name="size" className="form-control" style={{height: '46px;'}}>
<option key="1" value="1">Red</option>
<option key="2" value="2">Yellow</option>
<option key="3" value="3">Green</option>
</select>
<input type="submit" value="Pick This" className="form-control" onClick={() => this.handleSubmit} />
</form>
});
If there was 3 form, how to get the selected value from clicked submit button form?
Or is there another simple way?
Thank you

One method would be changing how your onSubmit function is handled.
So you could pass which index of products you are submitting like so
this.state.products.map((product, i) => {
<form onSubmit={event => this.handleSubmit(event, i)}>
<select name="size" className="form-control" style={{height: '46px;'}}>
<option key="1" value="1">Red</option>
<option key="2" value="2">Yellow</option>
<option key="3" value="3">Green</option>
</select>
<input type="submit" value="Pick This" className="form-control" onClick={() => this.handleSubmit} />
</form>
});
It also looks like your form is uncontrolled, which another possibly is having the select change a value in state.
<select name="size" onChange={e => this.handleChange(e, i)} className="form-control" style={{height: '46px;'}}>
<option key="1" value="1">Red</option>
<option key="2" value="2">Yellow</option>
<option key="3" value="3">Green</option>
</select>
and in your handleChange, you would change a value in state that would correspond to the product from your state.

You can use a ref to get form values from the DOM.
Here you need one ref per product, so you could use the index of product to save the ref and also to submit de form.
class Example extends Component {
constructor(props) {
super(props);
this.state = {
products: [],
};
this.selectByProduct = {};
this.handleSubmit = this.handleSubmit.bind(this);
}
handleSubmit(event, productIndex) {
event.preventDefault();
const size = this.selectByProduct[productIndex].value;
console.log(`you submitted the size ${size} of product ${productIndex}`)
}
render() {
return this.state.products.map((product, i) => (
<form onSubmit={event => this.handleSubmit(event, i)}>
<select ref={select => this.selectByProduct[i] = select} name="size" className="form-control" style={{height: '46px;'}}>
<option key="1" value="1">Red</option>
<option key="2" value="2">Yellow</option>
<option key="3" value="3">Green</option>
</select>
<input type="submit" value="Pick This" className="form-control" />
</form>
));
}
}

Related

Validate select list with react-hook-form

I want to implement validation for React form using react-hook-form. For input value I implemented this:
<div className='input-group mb-3'>
<Controller
control={control}
name={"email"} // the key of json
defaultValue={""}
render={({ field }) => (
<input
{...field}
type="email"
className="form-control"
placeholder="Email"
aria-label="email"
onChange={(e) => field.onChange(e.target.value)}
/>
)}
/>
</div>
For me it's not clear how I need to implement it for select menu:
<div className='input-group mb-3'>
<select
className='form-control form-select'
name='budget'
id='budget'
required=''
data-msg='Please select your budget.'
>
<option value=''>Budget</option>
<option value='budget3'>More than $500,000</option>
</select>
</div>
Wat is the proper way to implement it?
somethings like this works?
<Controller
control={control}
name="budget"
rules={{
budget: {
required: "Required",
},
}}
render={({ field }) => (
<select name="budget" onChange={field.onChange} value={field.value}>
<option value="">Please select your budget</option>
<option value="budget3">More than $500,000</option>
<option value="budget2">$250,000 - $500,000</option>
<option value="budget1">$100,000 - $250,000</option>
{/* more budgets */}
</select>
)}
/>;
control is destructured from useForm like so:
const { controls, register, setValue, ...moreEls } = useForm();

cascading dropdown is not working in react

I am new to Reactjs and trying to implement cascading dropdowns so that when user select state he will be able to get corresponding cities in next dropdown.
Expected result : For state: Maharashtra -> Cities : Nagpur, Pune
This is my code
enter code here
import React from "react";
import { useState } from "react";
import "./Form.css";
import states from "./city-state";
function Form() {
const stateList = states;
let citiesList = [];
const [cities, setcities] = useState([]);
const [stateName, setStateName] = useState(states[0].state);
const [cityName, setCityName] = useState();
const getCities = (e) => {
console.log("state:" + e.target.value);
for (let i = 0; i < stateList.length; i++) {
if (stateList[i].state == "" + e.target.value)
citiesList = stateList[i].cities;
}
console.log("cityList:" + citiesList);
setcities(citiesList)
setStateName(e.target.value);
setCityName(citiesList[0].districts)
}
const refreshCityName = (e) =>{
setCityName(e.target.value);
}
return (
<div>
<section className="part cos-form">
<div className="boxx01">
<h2 className="h2-awards">FILL THE FORM</h2>
<h3 className="h3-awards">we will call you back</h3>
</div>
<form className="boxx02" onSubmit={handleSubmit}>
<div className="bpart1">
<input
type="text"
name="firstname"
placeholder="Name"
autoComplete="off"
onChange={handleChange}
/>{" "}
<p>{formErrors.username}</p>
<input
type="text"
name="email"
placeholder="Email"
autoComplete="off"
onChange={handleChange}
/>
<p>{formErrors.email}</p>
<input
type="tel"
name="mobileno"
placeholder="Mobile No."
autoComplete="off"
maxLength={10}
onChange={handleChange}
/>
<p>{formErrors.mobile}</p>
<span className="policy">
By clicking on Submit, I allow Lakmé Academy Powered by Aptech{" "}
<br /> to contact me, and use & share my personal data as per
the <br />
<a href="/privacy-policy" target="_blank" title="Privacy Policy">
Privacy Policy.
</a>
</span>
</div>
<div className="bpart2">
<select name="b_course_id">
<option selected="selected" value="">
Select Course Interested in
</option>
<option value="385">Short Term Courses</option>
<option value="414">Make-up</option>
<option value="468">Cosmetology</option>
<option value="527">Nail Art</option>
<option value="542">Hair</option>
<option value="559">Salon Management</option>
<option value="563">Beauty Therapy/Skin</option>
</select>
<select name="stateList" onChange={getCities}>
{stateList.map((e,key)=>{
return(
<option key ={key} value={e.state}>
{e.state}
</option>
)
})}
</select>
<select name="CityList" onChange={refreshCityName}>
{cities.map((e,key)=>{
return(
<option key ={key} value={e.name}>
{e.name}
</option>
)
})}
</select>
<button
disabled=""
className="black_btn btn"
name="student_enquiry_form_submit"
id="student_enquiry_form_submit"
type="button"
>
Submit
</button>
</div>
</form>
</section>
</div>
);
}
export default Form;
This is my structure of data in city-state.json. In this file, I have states names and districts name only.
{
"states": [
{
"state": "Andhra Pradesh",
"districts": [
"Anantapur",
"Chittoor"
]
}
}
please help me

Does react have a hook for listening for interactions on multiple inputs and updating that inputs relevant state using a setFoo( ) method

Is there a way to set multiple pieces of state with one event listener function.
I am trying to get information from the user that will update in real time other sections of my app. I am using the const [state, setState ] = useState() method.
I would like each input to fire a function off that will update the relevant parts of state but I can't work out how to do it.
import React, {useState} from 'react'
import { Container } from 'react-bootstrap'
const HBB = () => {
const [planName ,setPlanName ] = useState('')
const [planType ,setPlanType ] = useState('')
const [HBBInstallation ,setHBBInstallation ] = useState(false)
const [HBBInstallationActivationDate, setHBBInstallationActivationDate ] = useState()
const [HBBInstallationSlot , setHBBInstallationSlot ] = useState()
const [planOptions, setPlanOptions] = useState()
const [planMonthlyCost, setPlanMonthlyCost] = useState(0)
const handleChange = (e) => {
let proToUpdate = e.target.name;
let value = e.target.value;
let test = e.target.id;
//set the state of the element eg setPlanName(value)
}
return (
<Container>
<div>
<div className="form-group">
<select name="planName" id="setPlanName" value={planName} className="plan w-40" onChange={handleChange}>
<option value="*">Plan</option>
<option value="TEST">TEST</option>
</select>
<select name="planType" className="plan w-40" value={planType} onChange={handleChange}>
<option value="*">Standard</option>
<option value="pro">Pro</option>
<option value="extra">Extra</option>
</select>
</div>
<div className="form-group">
<label htmlFor="No">No Installation Needed</label>
<input name="HBBinstallation" id="No" type="radio" className="plan" value="No" checked onChange={handleChange}/>
<label htmlFor="Yes">Installation needed</label>
<input name="HBBinstallation" type="radio" className="plan" value="Yes"/>
</div>
<div className="form-group">
<input name="HBBInstallationActivationDate" type="text" className="textInput plan" value={HBBInstallationActivationDate} placeholder="Installation/Activation date" onChange={handleChange}/>
<select name="HBBinstallationSlot" className="plan">
<option value="*" defaultValue>Choose slot--</option>
<option value="am">AM</option>
<option value="pm">PM</option>
</select>
</div>
<div className="form-group">
<input name="planMonthlyCost" type="number" className="plan" value={planMonthlyCost} placeholder="Plan Monthly Cost" onChange={handleChange}/>
</div>
</div>
</Container>
)
}
export default HBB
Is it possible to pass the setState method through the onChange attr?
Will I need to write a function for each setState inputs?
If you use useReducer hook, you can handle multiple state easily like below code.
import React, { useReducer } from "react";
import { Container } from "react-bootstrap";
const useReducerState = (initialState = {}) => {
const reducer = (prev, next) => ({ ...prev, ...next });
return useReducer(reducer, initialState);
};
const HBB = () => {
const [state, setState] = useReducerState({
planName: "",
planType: "",
HBBInstallationActivationDate: 0,
HBBInstallation: false,
HBBInstallationSlot: [],
planOptions: [],
planMonthlyCost: 0
});
const handleChange = (e) => {
let proToUpdate = e.target.name;
let value = e.target.value;
let test = e.target.id;
setState({ [proToUpdate]: value });
};
const {
planName,
planType,
HBBInstallationActivationDate,
HBBInstallation,
HBBInstallationSlot,
planOptions,
planMonthlyCost
} = state;
return (
<Container>
<div>
<div className="form-group">
<select
name="planName"
id="setPlanName"
value={planName}
className="plan w-40"
onChange={handleChange}
>
<option value="*">Plan</option>
<option value="TEST">TEST</option>
</select>
<select
name="planType"
className="plan w-40"
value={planType}
onChange={handleChange}
>
<option value="*">Standard</option>
<option value="pro">Pro</option>
<option value="extra">Extra</option>
</select>
</div>
<div className="form-group">
<label htmlFor="No">No Installation Needed</label>
<input
name="HBBinstallation"
id="No"
type="radio"
className="plan"
value="No"
checked
onChange={handleChange}
/>
<label htmlFor="Yes">Installation needed</label>
<input
name="HBBinstallation"
type="radio"
className="plan"
value="Yes"
/>
</div>
<div className="form-group">
<input
name="HBBInstallationActivationDate"
type="text"
className="textInput plan"
value={HBBInstallationActivationDate}
placeholder="Installation/Activation date"
onChange={handleChange}
/>
<select name="HBBinstallationSlot" className="plan">
<option value="*" defaultValue>
Choose slot--
</option>
<option value="am">AM</option>
<option value="pm">PM</option>
</select>
</div>
<div className="form-group">
<input
name="planMonthlyCost"
type="number"
className="plan"
value={planMonthlyCost}
placeholder="Plan Monthly Cost"
onChange={handleChange}
/>
</div>
</div>
</Container>
);
};
export default HBB;
Then, you can use setState function for changing all the state values.
For using this method, you always have to set the initial value for the state.

I don't know where it went wrong in react js

I have created a 3 select option inputs based on 1st selection option it should populate the 2nd dropdown and based on 1st and 2nd selected option then it should populate the 3rd dropdown.
Unexpected token
const availableState = data.countries.find((c) => c.name === selectedCountry);
const availableCities = availableState?.states?.find((s) => s.name === selectedState);
render method select options
<div>
<label>Country</label>
<select
placeholder="Country"
value={selectedCountry}
onChange={(e) => setSelectedCountry(e.target.value)}
>
<option>--Choose Country--</option>
{data.countries.map((value, key) => {
return (
<option value={value.name} key={key}>
{value.name}
</option>
);
})}
</select>
</div>
<div>
<label>State</label>
<select
placeholder="State"
value={selectedState}
onChange={(e) => setSelectedState(e.target.value)}
>
<option>--Choose State--</option>
{availableState?.states.map((e, key) => {
return (
<option value={e.name} key={key}>
{e.name}
</option>
);
})}
</select>
</div>
<div>
<label>City</label>
<select
placeholder="City"
value={selectedCity}
onChange={(e) => setSelectedCity(e.target.value)}
>
<option>--Choose City--</option>
{availableCities?.cities.map((e, key) => {
return (
<option value={e.name} key={key}>
{e}
</option>
);
})}
</select>
</div>

Filter List in React

I have a problem here. I have an react api and i want to make a select box to filter data by specific attribute.
constructor() {
super();
this.state = {
results: []
};
}
I receive a list of items with name and ratings. And I want to filter with select. If I want to see just items with 5 rating or greater, select 5.
return (
<div className="container clearfix">
{/* value={props.search} */}
<select>
<option value="" />
<option value="10">10</option>
<option value="9">9</option>
<option value="8">8</option>
</select>
<div>
{props.results
.map(item=> (
<div key={item.id} className="item-holder">
<img src={`${imagePath}${item.image}`} />
<span className="votes">{item.rating}</span>
<p>{item.title}</p>
</div>
))}
</div>
</div>
);
TX!
You need to attach a listener to Select e.g.
<Select onChange={(event) => this.setState({filterValue: event.target.value})}
then you can filter the results with
props.results.filter((item) => item.rating >= this.state.filterValue)
.map(...)

Categories

Resources