I want to have a default option in select saying "Select your option". But I want in to be disabled, which means that user should not be able to select it once he choose any value.
Here is an example:
function Select() {
const [option, setOption] = useState();
function handleOnChange(event) {
setOption(event.target.value);
}
return (
<select value={option} onChange={handleOnChange}>
<option disabled>Select your option</option>
{OPTIONS.map(value => (
<option key={value} value={value}>{value}</option>
))}
</select>
);
}
But if I'm adding a disabled prop to option it selects the first option which is not disabled. What should be adjusted to make it work?
Thanks in advance
what you need to do is to provide a default value to your useState and a value for your default option, so it gets selected. Like this:
function Select() {
const [option, setOption] = useState('');
function handleOnChange(event) {
setOption(event.target.value);
}
return (
<select value={option} onChange={handleOnChange}>
<option value='' disabled>Select your option</option>
{OPTIONS.map(value => (
<option key={value} value={value}>{value}</option>
))}
</select>
);
}
Related
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
<select open={false} autoFocus={true} onClick={this.handleClick} size={5}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
I have made a dropdown, but I cannot close it. I do not want close it with display:none
You can initially show 5 items and, after selecting close it(set to 1 using a state)
import React, { useState } from "react";
function App() {
const [defaultSize, setDefaultSize] = useState(5);
const handleClick = () => {
setDefaultSize(1);
// do other stuff
}
return (
<div>
<select open={false} autoFocus={true} onClick={handleClick} size={defaultSize}>
<option value="grapefruit">Grapefruit</option>
<option value="lime">Lime</option>
<option value="coconut">Coconut</option>
<option value="mango">Mango</option>
</select>
</div>
);
}
export default App;
Remove the size attribute. change onClick to onChange add value attribute for select tag
<select value={myCar} onChange={handleChange}>
I have a simple app for displaying data. The state changes from a select. However I want the default select option to be united kingdom. Currently the option defaults to Afghanistan as it's the first in the alphabet.
export default function CountrySelect() {
const [country, setCountry] = useState('GBR');
const countries = useFetch('https://covid19.mathdro.id/api/countries');
if (!countries) return null;
const countryArr = Object.entries(countries.countries).map(([key, value]) => {
return {
name: `${key}`,
code: `${value}`
};
});
return (
<div>
<h2>Showing: {country}</h2>
<select
onChange={(event) => setCountry(event.target.value)}
defaultValue={country}>
{countryArr.map((country) => (
<option value={country.code} key={country.name}>
{country.name}
</option>
))}
</select>
<Info url={`https://covid19.mathdro.id/api/countries/${country}`}></Info>
</div>
);
}
To clarify the country state is 'GBR' and data from 'GBR' or United Kingdom is displayed. It's the tag which I'm having the issue with.
If you can not use defaultValue, just add simple condions
const [countryState, setCountry] = useState('GBR');
{countryArr.map(country => {
if (country.name !== countryState) {
return (
<option
value={country.code}
label={country.name}
key={country.name}
>
{country.name}
</option>
);
} else {
return (
<option
value={country.code}
label={country.name}
key={country.name}
selected="selected"
>
{country.name}
</option>
);
}
})}
From the code, it seems to be HTML select and not react-select. There is no default value attribute to the default select. You can add the selected attribute to the required option here, like:
const [selectedCountry, setCountry] = useState({ code: <Countrycode of UK>});
// ..
// ..
<select
onChange={(event) => setCountry(event.target.value)}
{countryArr.map((country) => (
<option selected={selectedCountry.code === country.code} value={country.code} key={country.name}>
{country.name}
</option>
))}
</select>
Set the object property that you want to be the default option. Since you want the United Kingdom to be selected , set the defaultValue to the code that you get from the API.
Sandbox for reference : https://codesandbox.io/s/react-hooks-t1c2x
export default function CountrySelect() {
const [selectedCountry, setCountry] = useState({
code: "GB"
});
const countries = useFetch("https://covid19.mathdro.id/api/countries", {});
if (!countries) return null;
const countryArr = Object.entries(countries.countries).map(([key, value]) => {
return {
name: `${key}`,
code: `${value}`
};
});
return (
<div>
<select
onChange={event => setCountry(event.target.value)}
defaultValue={selectedCountry.code}
>
{countryArr.map(country => (
<option value={country.code} key={country.name}>
{country.name}
</option>
))}
</select>
</div>
);
}
In my case, I use a select to maintain some search conditions like this:
<select onChange={this.props.onSelectChange}>
<option value="" selected={this.props.searchTerms.condition== ""}>
Select Option
</option>
<option value="opt1" label="opt1" selected={this.props.searchTerms.condition == "opt1"}>
opt1
</option>
<option value="opt2" label="opt2" selected={this.props.searchTerms.condition == "opt2"}>
opt2
</option>
<option value="opt3" label="opt3" selected={this.props.searchTerms.condition == "opt3"}>
opt3
</option>
</select>
You can see I'm using selected property in options to make the selected item is the value I set.
But in this way I will get warning from react said I should use value instead. After I change it like this:
<select onChange={this.props.onSelectChange} value={this.props.searchTerms.condition}>
<option value="" }>
Select Option
</option>
<option value="opt1" label="opt1" >
opt1
</option>
<option value="opt2" label="opt2" >
opt2
</option>
<option value="opt3" label="opt3">
opt3
</option>
</select>
The set value is not reflected to selected item. But the props is changed correctly, I print it some where and the value is right.
I used react-redux in this case, the prop is changed from a action dispatch from some button, in that action the search state will be updated and the search state is bind to prop by using redux.
Here is the redux related code:
Binding:
export const mapDispatchToProps = (dispatch, ownProps) => ({
onSelectChange: event => dispatch(updateSearchTermsAction("condition", event.target.value)),
buttonClick: event => {//this is the issue event
event.preventDefault();
dispatch(updateSearchTermsAction("condition", "opt2"));
return false;
}
});
Action:
export const updateSearchTermsAction = (key, value) => ({ type: UPDATE_SEACHTERMS, key: key, payload: value });
Reducer:
const initialState = fromJS({ panelState: true, searchTerms: { condition: "" }, data: [] });
export default (state = initialState, action) => {
switch (action.type) {
case UPDATE_SEACHTERMS:
console.log(`${action.key} change detect ${action.payload}`);//correct here
return state.setIn(["searchTerms", action.key], action.payload);
default:
return state;
}
And for debug purpose, I output the whole 'searchTerms' to HTML like that:
<pre>{JSON.stringify(this.props.searchTerms, null, 2)}</pre>
After button clicked, the buttonClick is triggered, the action dispatched, from reducer I can see correct value in console, and the output in Pre is changed too, but the select does not change.
Please give me some advises about where might be the reason.
Well, I have not tested but you can try two methods for the same.
assign prop value into state and set it value={this.state.value} in the value attribute.
or
use sanitize for the value value={sanitize(this.props.searchTerms.condition)}
After checking out the relevant react docs, I was creating a minimized version of your select code, it works well for me
const Component = () => {
const [condition, setCondition] = useState("")
return (
<div>
<select
value={condition}
onChange={(evt) => setCondition(evt.target.value)}
>
<option value="">
Select Option
</option>
<option value="opt1" label="opt1" >
opt1
</option>
<option value="opt2" label="opt2" >
opt2
</option>
<option value="opt3" label="opt3">
opt3
</option>
</select>
</div>
)
}
https://stackblitz.com/edit/react-jbugqv
I'm using ant.design select component ("tags" or "multiple" mode) in a page, i want dropdown to be automatically closes after each selection. Now it remains open and i should click on other places in the page to close the dropdown list.
import { Select } from 'antd';
const { Option } = Select;
function handleChange(value) {
console.log(`selected ${value}`);
}
ReactDOM.render(
<Select mode="multiple" placeholder="Select Countries" size="large" onChange={handleChange}>
<Option value="country1">Country1</Option>
<Option value="country2">Country2</Option>
<Option value="country3">Country3</Option>
<Option value="country4">Country4</Option>
<Option value="country5">Country5</Option>
<Option value="country6">Country6</Option>
</Select>,
mountNode,
);
Simply change first "Select" component to this:
<Select
mode="multiple"
placeholder="Select Countries"
size="large"
ref={(select) => this.countrySelect = select}
onChange={()=>{
this.countrySelect.blur()
}}>
<Option value="country1">Country1</Option>
<Option value="country2">Country2</Option>
<Option value="country3">Country3</Option>
<Option value="country4">Country4</Option>
<Option value="country5">Country5</Option>
<Option value="country6">Country6</Option>
</Select>
From the docs:
import { Select } from 'antd';
const Option = Select.Option;
function handleChange( value ) {
console.log( `selected ${value}` );
}
<Select defaultValue="lucy" style={ { width: 120 } } onChange={ handleChange }>
<Option value="jack">Jack</Option>
<Option value="lucy">Lucy</Option>
<Option value="disabled" disabled>Disabled</Option>
<Option value="Yiminghe">yiminghe</Option>
</Select>
<Select defaultValue="lucy" style={ { width: 120 } } disabled>
<Option value="lucy">Lucy</Option>
</Select>
<Select defaultValue="lucy" style={ { width: 120 } } loading>
<Option value="lucy">Lucy</Option>
</Select>
Use it's own <Option>
More info: https://ant.design/components/select/
import React, { useState } from 'react'
import { Select } from 'antd'
const Option = Select.Option
const SelectComponent = () => {
const [open, setOpen] = useState('')
const handleChange = value => {
console.log(`selected ${value}`)
}
return (
<Select
showSearch
mode={'multiple'}
style={{ width: 200 }}
placeholder="Select a person"
optionFilterProp="children"
open={open}
onChange={value => {
handleChange.bind(this, value)
this.setState({ open: false })
}}
onFocus={() => setOpen(true)}
onBlur={() => setOpen(false)}
onSearch={() => setOpen(true)}
>
<Option value="jack">Jack</Option>
<Option value="lucy">Lucy</Option>
<Option value="tom">Tom</Option>
</Select>
)
}
export default SelectComponent