Set value in Select (Input) of reactstrap - reactjs

Code:
const [frequency, setFrequency] = useState({});
function handleSelect(event) {
const target = event.target;
const value = target.value;
const name = target.name;
setFrequency({
...frequency,
[name]: value
})
}
<FormGroup>
<Label for="exampleSelect">Select</Label>
<Input type="select" name="select" id="exampleSelect" onChange= {handleSelect} >
// I tried the below, But it does not seem to work
<Input type="select" name="frequency" id="frequency" value={frequency.frequency}>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</Input>
</FormGroup>
Dropdown:
Selected value:
When I select the value it renders in the input but when I want to set the selected value.
Meaning, I want to set the value such that when I load it should start from a selected value not from 1.
So how can I set the value?
I can setState by calling some select function. But in input tag I just want a value any value so when I refresh dropdown should show xyx...1,2,3,4.

If you write value="xyx", the value of select will always be xyz no matter what option you select.
So, instead of that you can provide value from react state and a handleChange function to change the value on select.
If you want to select the "first option" i.e. xyz at start, you can initialize the state with xyz:
export default function App() {
const [frequency, setFrequency] = useState({ frequency: "xyz" });
function handleSelect(e) {
setFrequency((prev) => ({
...prev,
[e.target.name]: e.target.value,
}))
}
return (
<>
{JSON.stringify(frequency)}
<FormGroup>
<Label for="exampleSelect">Select</Label>
<Input
type="select"
name="frequency"
id="frequency"
value={frequency.frequency}
onChange={handleSelect}
>
<option>xyz</option>
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</Input>
</FormGroup>
</>
);
}
Here is a demo

Related

How can i put value in input?

Why can't I put a value in the input? The problem is: I need to put a 'name' in <Form.Item> to apply the rules. Without that, the rules will not be able to work, but if you remove the name="userName" from <Form.Item the value appears at the input.
How can i solve that?
<Form autoComplete="off" layout="vertical" onFinish={handleFinish}>
<Form.Item name="userName" rules={getTextRule('name')}>
<Input value={fields?.firstName} name="firstName" onChange={(e) => {
handleInputChange(e)
}} />
</Form.Item>
</Form.Item>
simple we can code like
const [text,setText] = useState('')
return(
<input type='text' value={text} onChange={e=>setText(e.target.value)}/>
)
If you use the form you can let Ant Form manage the state by removing the value & the onChange props on the <Input />.
Else if you manage the state by yourself make sure to get the value from the e.target.value.
ex:
const [fields, setFields] = useState({})
const handleOnChange = (e) => {
setFields((state) => {
...state,
[e.target.name]: e.target.value,
})
}
return (
<Input
name="firstName"
value={fields.firstName}
onChange={handleOnChange}
/>
)

how to avoid repeating pattern when creating form in react

I am going to update the form with each keystroke with useState Hook this way I have to add an onChange event listener plus a function for each input and as you can imagine it's going to be lots of functions how can I avoid repeating myself?
function firstNamInput(){
}
function lastNameInput(){
}
function emailInput(){
}
function phoneInput(){
}
function addressInput(){
}
function genderInput(){
}
function jobInput(){
}
function ageInput(){
}
in react we try to collect form data on every keystroke but in the past, we used to collect form data when submit clicked. so because of this new approach, we have to listen for every keystroke on every input! isn't this crazy? yes, kind of but there is a way to go around I am going to explain it to you :
first I am going to talk about Rules you have to know about inputs:
we are going to use a useState Hook and we pass an object to it which contain:
a property for every input that's single
a property for group inputs (for example if there is checkboxes for gender we create only one property for gender)
what attributes every input should have?
name (it's going to be equal to its property in the useState)
value or checked (as a rule of thumb if the inputs gets true or false its usually checked vice versa )
onChange event
so let's create useState I am going to have a total of 7 properties in the object:
const [formData, setFormData] = React.useState(
{
firstName: "",
lastName: "",
email: "",
comments: "",
isFriendly: true,
employment: "",
favColor: ""
}
)
we need to create a function for the onChange event i am going to make it as reusable as possible it's going to get form data from each input and update it in our Hook.
function handleChange(event) {
const {name, value, type, checked} = event.target
setFormData(prevFormData => {
return {
...prevFormData,
[name]: type === "checkbox" ? checked : value
}
})
}
now we are going to add inputs look at note 2 again and now you are ready
import React from "react"
export default function Form() {
const [formData, setFormData] = React.useState(
{
firstName: "",
lastName: "",
email: "",
comments: "",
isFriendly: true,
employment: "",
favColor: ""
}
)
function handleChange(event) {
const {name, value, type, checked} = event.target
setFormData(prevFormData => {
return {
...prevFormData,
[name]: type === "checkbox" ? checked : value
}
})
}
function handleSubmit(event) {
event.preventDefault()
// submitToApi(formData)
console.log(formData)
}
return (
<form onSubmit={handleSubmit}>
<input
type="text"
placeholder="First Name"
onChange={handleChange}
name="firstName"
value={formData.firstName}
/>
<input
type="text"
placeholder="Last Name"
onChange={handleChange}
name="lastName"
value={formData.lastName}
/>
<input
type="email"
placeholder="Email"
onChange={handleChange}
name="email"
value={formData.email}
/>
<textarea
value={formData.comments}
placeholder="Comments"
onChange={handleChange}
name="comments"
/>
<input
type="checkbox"
id="isFriendly"
checked={formData.isFriendly}
onChange={handleChange}
name="isFriendly"
/>
<label htmlFor="isFriendly">Are you friendly?</label>
<br />
<br />
<fieldset>
<legend>Current employment status</legend>
<input
type="radio"
id="unemployed"
name="employment"
value="unemployed"
checked={formData.employment === "unemployed"}
onChange={handleChange}
/>
<label htmlFor="unemployed">Unemployed</label>
<br />
<input
type="radio"
id="part-time"
name="employment"
value="part-time"
checked={formData.employment === "part-time"}
onChange={handleChange}
/>
<label htmlFor="part-time">Part-time</label>
<br />
<input
type="radio"
id="full-time"
name="employment"
value="full-time"
checked={formData.employment === "full-time"}
onChange={handleChange}
/>
<label htmlFor="full-time">Full-time</label>
<br />
</fieldset>
<br />
<label htmlFor="favColor">What is your favorite color?</label>
<br />
<select
id="favColor"
value={formData.favColor}
onChange={handleChange}
name="favColor"
>
<option value="red">Red</option>
<option value="orange">Orange</option>
<option value="yellow">Yellow</option>
<option value="green">Green</option>
<option value="blue">Blue</option>
<option value="indigo">Indigo</option>
<option value="violet">Violet</option>
</select>
<br />
<br />
<button>Submit</button>
</form>
)
}

How Can I create a Handle an input object with React hooks

I have problem in my input object how can I change the onChage function this is my input code
<Form.Group as={Col} controlId="formGridResultat">
<Form.Label>Result</Form.Label>
<Form.Control required as="select"
type="text"
id="conduexam.id"
name="conduexam.id"
value={currentStates. conduexam?.nom}
className={"bg-white text-dark"}
onChange={handleInputChange}>
<option value="">Choisir un Resultat </option>
{result.map((value) => (
<option value={value.id} key={value.id}>
{value.nom}
</option>
))}
</Form.Control>
</Form.Group>
The function “onChange” how can I change it?
const handleInputChange = event => {
const { name, value } = event.target;
setCurrentStates({ ...currentStates, [name]: value });
};
Try this:
const [currentStates, setCurrentStates]= useState({
//your initial code here
})
const handleInputChange = event => {
console.log(event.target.value)
setCurrentStates({ ...currentStates, [name]: event.target.value});
};

How can I update values in state from one function rather than each value having its own event listener?

Background, I am currently working on a Food Truck Finder application based in React. In react, as I understand it, if you want to change the value in state you have to have a listener like:
handleTruckTypeChange = (idx) => (e) => {
const newTrucks = this.state.data.map((truck, sidx) => {
if (idx !== sidx) return truck;
return { ...truck, type: e.target.value };
});
this.setState({ data: newTrucks });
}
which works fine for some of my other values in the table but I have a large object for my schedule object. Its handling dozens of values and I don't want to have to write a special event listener for each one. On top of that I have an array of these schedule objects using idx as an index. for example, each day has a startTime, endTime, openClosed, and cost.
Is there a way they can all be handled by the same event listener so I'm not making 7 copies of the same function to handle each change?
an example of how I'm calling the onChange.
<td>
<FormControl className={classes.margin}>
<InputLabel htmlFor="openClosed">O/C</InputLabel>
<NativeSelect
id="openClosed"
value={this.state.schedule[idx].monOpen}
onChange={this.handleScheduleChange(idx)}
input={<BootstrapInput />}
>
<option aria-label="None" value="" />
<option value={"0"}>Open</option>
<option value={"1"}>Closed</option>
</NativeSelect>
</FormControl>
</td>
You can create a function handleOnChange
handleOnChange = field => event => {
this.setState({[field]: event.target.value})
}
and now you can call this function whenever you need to update state with the state that you want to change as parameter.
For your scenario
<td>
<FormControl className={classes.margin}>
<InputLabel htmlFor="openClosed">O/C</InputLabel>
<NativeSelect
id="openClosed"
value={this.state.schedule[idx].monOpen}
onChange={this.handleOnChange('schedule[idx].monOpen')}
input={<BootstrapInput />}
>
<option aria-label="None" value="" />
<option value={"0"}>Open</option>
<option value={"1"}>Closed</option>
</NativeSelect>
</FormControl>
</td>
I figured it out my own little way with yalls help. here's how I did it.
handleScheduleChange = (idx) => (e) => {
const target = e.target;
const value = target.value;
const name = target.name;
this.setState({
schedule: this.state.schedule.map((item, itemIndex) => {
if (itemIndex === idx) {
return {
...item,
[name]: value
}
}
return item;
})
});
console.log(this.state.schedule[idx]);
};
<td>
<FormControl className={classes.margin}>
<InputLabel htmlFor="openClosed">O/C</InputLabel>
<NativeSelect
id="openClosed"
name="monOpen"
value={this.state.schedule[idx].monOpen}
onChange={this.handleScheduleChange(idx)}
input={<BootstrapInput />}
>
<option aria-label="None" value="" />
<option value={"0"}>Open</option>
<option value={"1"}>Closed</option>
</NativeSelect>
</FormControl>
</td>
whats important is that you give each component a name value that coincides with the value in state you want to change, also pass in the index of the array so you update the correct one. This works consistently so you can pass it to multiple functions if they all access the same array in state, for this example I have this.state.schedule

Fetch initial value from Drop Down list in react.js

I have a drop down list of countries which is populated using an API like below
<select
name="country"
onChange={this.handleChange}
className="form-control"
>
<option value="" disabled>Select a Country</option>
{rows} //populated using an API & has a defult value
</select>
I am using handleChange function to collect values like below
handleChange = event => {
this.setState({ [event.target.name]: event.target.value });
};
Drop down list has a default value. I would like to collect that value if user don't change any value.
I'd suggest storing that default value in the state
state = {
country: <DEFAULT_VALUE>
}
...
render() {
return (
<select
...
value={this.state.country}
>
...
</select>
)
}

Resources