Fetch initial value from Drop Down list in react.js - reactjs

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

Related

Can't take value from Input Type ="select"

I am trying to take value from a drop down menu but isn't able to do so .
My code for the dropdrop is :
<Input type="select" name="type" id="etype" value={this.state.type} onChange={this.changeTypeHandler}>
<option value="Doctor">Doctor</option>
<option value ="Nurse"> Nurse</option>
</Input>
while my changeTypeHandler is
changeTypeHandler = (event) => {
this.setState({ type: event.target.value });
}
I have seen this.state.selectedValue in on of the solution for type . So what should be done in this case ?
Sorry If its a basic question but I am new to react and isn't able to find the solution for this .Thanks
Try it like this :
<select name="type" id="etype" value={this.state.selectedValue}
onChange={this.changeTypeHandler}>
<option value="Doctor">Doctor</option>
<option value ="Nurse"> Nurse</option>
</select >
and for onChange function
changeTypeHandler =(event) =>
{
this.setState({selectedValue:event.target.value});
}
hi there you can use this instead of that
function get_selected_input() {
alert(document.querySelector('#etype').value)
}
<select type="select" name="type" id="etype" onChange=get_selected_input(this)>
<option value="">Select Option</option>
<option value="Doctor">Doctor</option>
<option value ="Nurse"> Nurse</option>
</select>
You need to use value instead of selectedValue.
changeTypeHandler = (event) => {this.setState({type: event.target.value})}
Its better todo it in the Reactjs way, which means you can use select tag
<select value={this.state.value} onChange={this.handleChange}>
<option value="Doctor">Doctor</option>
<option value="Nurse">Nurse</option>
</select>
and the handeler
handleChange(event) {
this.setState({value: event.target.value});
}
and this way of doing it is also recomanded by React official web site.
Try this
import React from "react";
import { Input } from "reactstrap";
export default class App extends React.Component {
state = {
type: ""
};
changeTypeHandler = (e) => {
this.setState({ type: e.target.value });
};
render() {
console.log(this.state)
return (
<div className="App">
<Input
type="select"
name="type"
id="etype"
value={this.state.type}
onChange={this.changeTypeHandler }
>
<option value="Doctor">Doctor</option>
<option value="Nurse"> Nurse</option>
</Input>
</div>
);
}
}

Set value in Select (Input) of reactstrap

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

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

Why are my React form submission values undefined?

I'm trying to create a form and store the values of it in state – so far, so reasonable.
I think I've set it all up right, but when I return the contents of state, each and every field comes back undefined. I don't doubt that there's something simple I've overlooked in setting it up, but I can't for the life of me see what it is...
Can someone put me out of my misery?
handleAddProperty = (event) => {
event.preventDefault();
console.log(this.state.fields);
console.log(this.state.fields.type);
};
handleFieldChange = (event) => {
this.setState({
fields: {
title: event.target.value.title,
type: event.target.value.type,
bedrooms: event.target.value.bedrooms,
bathrooms: event.target.value.bathrooms,
price: event.target.value.price,
city: event.target.value.city,
email: event.target.value.email,
},
});
};
render() {
return (
<div className="addproperty">
<form onSubmit={this.handleAddProperty}>
<button type="submit">Add</button>
<input name="title" value={this.state.fields.title} onChange={this.handleFieldChange} />
<select name="type" value={this.state.fields.type} onChange={this.handleFieldChange}>
<option value={this.state.fields.type}>Flat</option>
<option value={this.state.fields.type}>Detached</option>
<option value={this.state.fields.type}>Semi-Detached</option>
<option value={this.state.fields.type}>Terraced</option>
<option value={this.state.fields.type}>End of Terrace</option>
<option value={this.state.fields.type}>Cottage</option>
<option value={this.state.fields.type}>Bungalow</option>
</select>
<input name="bedrooms" value={this.state.fields.bedrooms} onChange={this.handleFieldChange} />
<input name="bathrooms" value={this.state.fields.bathrooms} onChange={this.handleFieldChange} />
<input name="price" value={this.state.fields.price} onChange={this.handleFieldChange} />
<select name="city" value={this.state.fields.city} onChange={this.handleFieldChange}>
<option value={this.state.fields.city}>Manchester</option>
<option value={this.state.fields.city}>Leeds</option>
<option value={this.state.fields.city}>Sheffield</option>
<option value={this.state.fields.city}>Liverpool</option>
</select>
<input name="email" value={this.state.fields.email} onChange={this.handleFieldChange} />
</form>
</div>
);
}
}
You should access to event.target.value rather then to event.target.value[key] because handleFieldChange function triggers for each input field (when they change their state) and for each of that triggers event.targetis referring to a different input field (basically the input which has been changed).
To update the state you can use event.target.name as a key to your form object members inside the component state. The code might look like the following:
constructor(props) {
super(props);
this.state = { form: { name: 'Jane' } };
}
handleFieldChange(event) {
// This will update specific key in your form object inside the local state
this.setState({
form: Object.assign({}, this.state.form, {
[event.target.name]: event.target.value,
}),
});
}
<input
name="test"
type="text"
onChange={e => this.handleFieldChange(e)}
/>

Use onSubmit to setState for the multiple inputs?

I want to take the data from these two inputs within my form and set one as state.name, and the other as state.option. Is there a way to set them upon using the form submit button rather than using individual onChange handlers to set each of those states? If not, it feels awkward having a submit button that doesn't really do anything.
onTextChange(name) {
this.setState({ name });
console.log(this.state.name);
}
onOptionChange(option) {
this.setState({ realm });
console.log(this.state.option);
}
onSubmitForm(event) {
event.preventDefault();
}
render() {
return (
<div>
<h3>Enter Name:</h3>
<form onSubmit={event => this.onSubmitForm(event.target.value)}>
<input
type="text"
placeholder="Name"
value={this.state.name}
onChange={event => this.onTextChange(event.target.value)}
/>
Select Option:
<select onChange = {event => this.onOptionChange(event.target.value)}>
<option value="1">Option 1</option>
<option value="2">Option 2</option>
</select>
<input type="submit" />
</form>
In React, you have to control what happens in form/input in state and setState to change it. That's call Single source of truth
Welcome to React :)

Resources