Multiple Dropdown using ReactJS - reactjs

I am designing and developing a CRUD API where it has 3 dropdowns. If I click on 1 dropdown and select an option it should prompt to another dropdown.
The error I am getting, which is at handlechange(), is:
"`TypeError: Cannot set property 'param_type' of undefined`".
Where is the mistake i am doing?
Below is the code:
handleChange(event) {
console.log(event.target.id)
var errors = this.state.errors
if (event.target.id.split('_')[0] == 'name') {
var ids = event.target.id.split('_')
let szs = this.state.parameters
szs[ids[1]].param_name = event.target.value
this.setState({ parameters: szs })
}
else if (event.target.id.split('_')[0] == 'type') {
var ids = event.target.id.split('_')
let szs = this.state.parameters
szs[ids[1]].param_type = event.target.value
this.setState({ parameters: szs })
console.log(szs)
}
else if (event.target.id.split('_')[0] == 'data') {
var ids = event.target.id.split('_')
let szs = this.state.parameters
szs[ids[1]].param_data = event.target.value
this.setState({ parameters: szs })
}
else if (event.target.id.split('_')[0] == 'type_of_configuration_data') {
var ids = event.target.id.split('_')
let szs = this.state.parameters
szs[ids[1]].type_of_config_data = event.target.value
this.setState({ parameters: szs })
}
this.setState({
errors: errors
})
}
The render which I do is:
{this.state.parameters[idx_fields].param_type === "list"?
<Col md="2">
<Label>Data <span style={{ color: "red" }}>*</span></Label>
<select id={"data" + '_' + idx_fields} className="form-control select2" value=
{this.state.parameters[idx_fields].param_data} onChange={this.handleChange} title="Kind">
<option value="type_of_configuration_data">Type of Configuration</option>
<option value="user-defined-data">User Defined Data</option>
</select>
</Col>
:null}
{this.state.parameters[idx_fields].param_data === "type_of_configuration_data"?
<Col md="2">
<Label>Type of configurations <span style={{ color: "red" }}>*</span></Label>
<select id={"type_of_configuration_data" + '_' + idx_fields} className="form-control select2" value=
{this.state.parameters[idx_fields].type_of_config_data} onChange={this.handleChange} title="Kind">
<option value="crops">Crops</option>
<option value="tanks">Tanks </option>
<option value="type-of-growing-system">Type Of Growing System </option>
<option value="seeding-units">Seeding Units </option>
<option value="batch-units">Batch Units </option>
<option value="facilities">Facilities </option>
<option value="users">Users </option>
<option value="task-categories">Task categories </option>
</select>
</Col>
:null}

What the error says is the object from where you are using the property is not present in other words its undefined.
In the code param_type is used here, szs[ids[1]].param_type. Console and check if the required property is present in szs[ids[1]].
You can use if statement here:
if (szs[ids[1]]) {
szs[ids[1]].param_type = event.target.value;
}
or szs[ids[1]]?.param_type = event.target.value;

Related

How to have second dropdown menu values be dependent on value of first dropdown menu in React render function

In the render function of a React component, I have the following code
<select name="env" id="env">
<option value="Dev">Dev</option>
<option value="Staging">Staging</option>
<option value="Prod">Prod</option>
</select>
<select name="region" id="region">
<option value="option1">op1</option>
<option value="option2">op2</option>
<option value="option3">op3</option>
<option value="option4">op4</option>
</select>
If Dev option is selected in first dropdown, there should only be op1 choice available in the 2nd dropdown. Similarly if Staging is selected, then op1, op2 and op3 are the available choices. If Prod is selected, then all 4 choices are available. How can I achieve this in React?
You should render different region options by env.
const regionsByEnv = {
Dev: ["option1"],
Staging: ["option1", "option2", "option3"],
Prod: ["option1, option2, option3, option4"],
};
const YourComponent = () => {
const [env, setEnv] = useState("");
const regionOptions = useMemo(() => {
if (!env) {
return regionsByEnv.Prod.map((option) => (
<option value={option} key={option}>
{option}
</option>
));
}
return regionsByEnv[env].map((option) => (
<option value={option} key={option}>
{option}
</option>
));
}, [env]);
return (
<>
<select
value={env}
onChange={(e) => setEnv(e.target.value)}
name="env"
id="env"
>
<option value="Dev">Dev</option>
<option value="Staging">Staging</option>
<option value="Prod">Prod</option>
</select>
<select name="region" id="region">
{regionOptions}
</select>
</>
);
};
You should filter option for select region base on selected option of select env. So you can create a state for handling value of select env
export default function App() {
const [select1, setSelect1] = useState("Dev");
const filterOption2 = allOption2.filter((i) => {
return (
(select1 === "Dev" && i.value === "option1") ||
(select1 === "Staging" && i.value !== "option4") ||
select1 === "Prod"
);
});
return (
<div className="App">
<select name="env" id="env" onChange={(e) => setSelect1(e.target.value)}>
<option value="Dev">Dev</option>
<option value="Staging">Staging</option>
<option value="Prod">Prod</option>
</select>
<select name="region" id="region">
{filterOption2.map((op) => (
<option key={select1 + op.value} value={op.value}>
{op.name}
</option>
))}
</select>
</div>
);
}
const allOption2 = [
{
name: "op1",
value: "option1"
},
{
name: "op2",
value: "option2"
},
{
name: "op3",
value: "option3"
},
{
name: "op4",
value: "option4"
}
];
You can check in my codesandbox

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

when I add a component of select to the render(), then i have two select instead of one select having multiple options

I am adding a select component like code below. After adding an author, i have two authors in the array, but I am having two select with the code below. Sorry for being stupid first I just started learning React.
let authorNames = this.state.authors.map((author, index) => {
return (
<select
onChange={e => {
let { newBookData } = this.state;
newBookData.author_id = e.target.value;
this.setState({ newBookData });
}}
key={author.id}
className="form-control"
>
<option>Select an author ...</option>
<option key={author.id} value={author.id}>
{this.getAuthorName(author.id)}
</option>
</select>
);
});
and I add like this..
render(){
{authorNames}
}
then I have the view like this, having two selects. What i have done wrong?
You can see the result image from here
I guess what you want to build is a select input that has all the authors in the this.state.authors array as options. For that, this would be how I go about it.
let selectAuthorOptions = this.state.authors.map((author, index) => {
return (<option key={author.id} value={author.id}>
{this.getAuthorName(author.id)}
</option>)
})
selectAuthorOptions = [(<option key="default">Select an author ...</option>)].concat(selectAuthorOptions)
let selectAuthor = (<select onChange={e => {
let { newBookData } = this.state;
newBookData.author_id = e.target.value;
this.setState({ newBookData });
}}
className="form-control">
{selectAuthorOptions}
</select>
You'll need to render just 1 select then use the .map to create the options you want.
render(){
<select
onChange={e => {
let { newBookData } = this.state;
newBookData.author_id = e.target.value;
this.setState({ newBookData });
}}
key={author.id}
className="form-control"
>
<option>Select an author ...</option>
{this.state.authors.map((author, index) => {
<option key={author.id} value={author.id}>
{this.getAuthorName(author.id)}
</option>
})
</select>
}

Reactjs - Select box with varying first option based on passed attribute

I am trying to show the first option different based on an attribute I pass.
In the search page, I want the user to be able to select "Any" option.
In the edit profile page, "Any" option should not be shown because that is only for search.
Edit profile page
<option value="0" disabled selected>
Select Religion
</option>
Search page
<option value="Any" selected>
Any Religion
</option>
Search profile page has this code:
import React, { Component } from 'react'
..
import ReligionInput from '../edit-profile/religion-input'
..
..
<ReligionInput value={religion} change={this.changeReligion} any="Y" />
...
And ReligionInput has a check for any == Y or not but its not working and always has the Any option. What is wrong with the code below ?
import religionOptions from './religion-options'
const InputReligion = ({ value, change, any }) => (
<div className="edit_religion_div">
<Select
placeholder="Select option"
value={value}
valueChange={e => change('religion', e)}
className="edit_religion my2"
>
{any} == 'Y' ?
`<option value="Any" selected>
Any Religion
</option>` :
`<option value="0" disabled selected>
Select Religion
</option>`
{religionOptions.map((e, key) => {
return <option key={key} value={e.value}>{e.name}</option>;
})}
</Select>
</div>
)
InputReligion.propTypes = {
value: PropTypes.string.isRequired,
change: PropTypes.func.isRequired,
}
All other options come from religionOptions.
A dirty way of doing it would be.
<option value={ any=='Y' ? '0' : 'Any' } selected>{ any=='Y' ? 'select' : 'any religion' }</option>
Yeah, not really a fan of those conditions either.
A cleaner and more readable approach would be:
const InputReligion = (props) => {
let defaultOption = null;
if (props.any == 'Y' ) {
defaultOption = <option value='Any' selected>Any religion</option>
} else {
defaultOption = <option value='0' selected disabled>Select Religion</option>
}
return (
<div className="edit_religion_div">
<select placeholder="Select Option"
className="edit_religion my2"
value={ props.value }
valueChange={ e => change('religion', e)}
>
{ defaultOption }
{
religion.map( (e, key) => {
return <option key={ key } value={ e.value }>{ e.name }</option>
})
}
</select>
</div>
)
}

onchange of one select other select option should change and i should get the data in alert of submit

Hi all I am unable to set the value of value1 if I am changing the value from parent select. I am able to render different select on changing the options of parent select, but I am not able to set the value.
import React, { Component } from 'react';
class FlavorForm extends React.Component {
constructor(props) {
super(props);
this.state = {value: 'HR',value1 : '1'};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.handleChange1 = this.handleChange1.bind(this);
}
handleChange(event) {
this.setState({value: event.target.value});
}
handleSubmit(event) {
event.preventDefault();
alert(this.state.value , this.state.value1);
}
getsecondselect = () => {
if(this.state.value === "HR"){
//gethrcontent = () => {
return (
<label>
Pick your HR:
<select value1={this.state.value1} onChange={this.handleChange1}>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</label>
)//};
}
else{
//getslectedenrollment = () => {
return (
<label>
Pick your Enrollment:
<select value1={this.state.value1} onChange={this.handleChange1}>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
</select>
</label>
)//};
}
}
handleChange1(event) {
this.setState({value1: event.target.value1});
alert(this.state.value1);
}
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Pick your favorite flavor:
<select value={this.state.value} onChange={this.handleChange}>
<option value="HR">HR</option>
<option value="enrollment">enrollment</option>
</select>
</label>
{getsecondselect()}
<input type="submit" value="Submit" />
</form>
);
}
}
export default FlavorForm;
I made some changes to the code, but as stackoverfloweth mentioned, you had event.target.value1 instead of event.target.value.
Also, you need this.getsecondselect() in the render function of the code you posted.
Working CodeSandbox here.
import React from "react";
import ReactDOM from "react-dom";
class App extends React.Component {
state = {
value: "HR",
number: "1"
};
handleChangeValue = event => {
this.setState({ value: event.target.value });
};
handleSubmit = event => {
event.preventDefault();
alert(`${this.state.value} --> ${this.state.number}`);
};
getSecondSelect = () => {
if (this.state.value === "HR") {
return (
<label>
Pick your HR:
<select value1={this.state.number} onChange={this.handleChangeNumber}>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
</select>
</label>
); //};
} else {
//getslectedenrollment = () => {
return (
<label>
Pick your Enrollment:
<select value1={this.state.value1} onChange={this.handleChangeNumber}>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
</select>
</label>
); //};
}
};
handleChangeNumber = event => {
this.setState({ number: event.target.value });
};
render() {
return (
<form onSubmit={this.handleSubmit}>
<label>
Pick your favorite flavor:
<select value={this.state.value} onChange={this.handleChangeValue}>
<option value="HR">HR</option>
<option value="enrollment">enrollment</option>
</select>
</label>
{this.getSecondSelect()}
<input type="submit" value="Submit" />
</form>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
It looks like both of your selects are setup to have value={this.state.value1} and onchange they both call this.handleChange1. Not sure if that's an issue.
I also noticed that within handleChange1 you are updating the state with a prop event.target.value1 but the options do not have value1 defined.. perhaps you meant to use event.target.value?
Hope this helps

Resources