React : display multiple hard coded options in Select component - javascript

How can I display multiple options tag in my Select component ?
Here's my component :
<Select
id='myID'
name='myName'>
{
(
(localStorage.getItem("localStorageKey").includes("John"))
?
<option key=1 value=myFirstValue>Option 1</option>
:
`
"Something else here"
`
)
}
</Select>
So far if I put just one option it's working, but if I add another one, say :
<Select
id='myID'
name='myName'>
{
(
(localStorage.getItem("localStorageKey").includes("John"))
?
<option key=1 value=myFirstValue>Option 1</option>
+
<option key=2 value=mySecondValue>Option 2</option>
:
`
"Something else here"
`
)
}
</Select>
It won't display anything

<>
<option key=1 value=myFirstValue>Option 1</option>
<option key=2 value=mySecondValue>Option 2</option>
</>
Wrap you options like this

In order to have more than one JSX element as sibling, It should be wrapped either in a React Fragment or in an array.
<> is a short hand for <React.Fragment>
<Select
id='myID'
name='myName'>
{
(localStorage.getItem("localStorageKey").includes("John"))
?
<>
<option key={1} value="myFirstValue">Option 1</option>
<option key={2} value="mySecondValue">Option 2</option>
</>
: "Something else here"
}
</Select>
By using array,
[<option key={1} value="myFirstValue">Option 1</option>,
<option key={2} value="mySecondValue">Option 2</option>]

Related

onClick event not working with option tag in React

onClick event not working with <option> tag. How to use onClick event with select option tag. Each option must be given a different parameter.
async function localization(language) {
localStorage.setItem("language", language);
}
useEffect(() => {
localization(localStorage.getItem("language"));
}, []);
return(
<select>
<option onClick={() => localization("ru")}>
<RussinFlagIcon /> Ru
</option>
<option onClick={() => localization("uz")}>
<UzbekistanFlagIcon /> Uz
</option>
<option onClick={() => localization("en")}>
<UKFlagIcon /> En
</option>
</select>
)
Use onChange instead, it's how you should be working when it comes to <select>. You can do something like this:
Notice value attribute on <option>. The selected option's value will be the value of the <select>.
return(
<select onChange = {(e)=> localization(e.target.value)}>
<option value = "ru">
<RussinFlagIcon /> Ru
</option>
<option value= "uz">
<UzbekistanFlagIcon /> Uz
</option>
<option value="en">
<UKFlagIcon /> En
</option>
</select>
)
Normally the select is used with a [form][1], then you should use the onChange callback:
const Select = () => {
const handleChange = (e) => localStorage.setItem("language", e.target.value);
return (
<label>
<select name="languages" onChange={handleChange}>
<option onClick={() => localization("ru")}>
<RussinFlagIcon /> Ru
</option>
<option onClick={() => localization("uz")}>
<UzbekistanFlagIcon /> Uz
</option>
<option onClick={() => localization("en")}>
<UKFlagIcon /> En
</option>
</select>
</label>
);
};
Then some comments about your code:
Your async function localization does not have to be async if you don't have a Promise in it.
And your useEffect does not do much except store the language in the localStorage based on the localStorage value ...
[1]: https://www.w3schools.com/TAGS/att_select_form.asp

OnClick Function does not work on Chrome?

I am trying to use onClick function on react.js HTML select option and it works perfectly on Firefox but not on Chrome. How can I make it work in Chrome? Here is my code so far:
import React, { Component } from "react";
import DateRangePicker from "react-daterange-picker";
import "react-daterange-picker/dist/css/react-calendar.css";
import originalMoment from "moment";
export class Filter extends Component {
constructor(props, context) {
super(props, context);
this.state = {
isOpen: false,};
}
onToggle = () => {
this.setState({ isOpen: !this.state.isOpen });
};
render() {
return (
<div className="filter_range">
<select
class="form-control donn"
name="today"
>
<option selected disabled hidden>
Choose{" "}
</option>
<option value="today">Today</option>
<option value="yesturday">Yesterday</option>
<option>Last Week</option>
<option value="month">Last Month</option>
<option>Last Quarter</option>
<option value="year">Last Year</option>
<option value="">Overall</option>
<option value="" onClick={this.onToggle}>
Custom
</option>
</select>
{this.state.isOpen && (
<DateRangePicker
value={this.props.value}
onSelect={this.props.change}
singleDateRange={true}
isOpen={false}
maximumDate={new Date()}
closeCalendar={true}
numberOfCalendars={2}
showLegend={true}
locale={originalMoment().locale()}
/>
)}
</div>
);
}
}
export default Filter;
Try to use onChange instead of onClick for select element.
<select class="form-control donn" name="today" onChange={handleChange}>
Just add value to your custom option and check for it in the if statement
<option value="custom">
Custom
</option>
export class Filter extends Component {
constructor(props, context) {
super(props, context);
this.state = {
isOpen: false,
};
}
handleChange = (event) => {
if (event.target.value === "custom") {
this.setState({ isOpen: !this.state.isOpen });
}
};
render() {
return (
<div className="filter_range">
<select class="form-control donn" name="today" onChange={handleChange}>
<option selected disabled hidden>
Choose{" "}
</option>
<option value="today">Today</option>
<option value="yesturday">Yesterday</option>
<option>Last Week</option>
<option value="month">Last Month</option>
<option>Last Quarter</option>
<option value="year">Last Year</option>
<option value="">Overall</option>
<option value="custom">
Custom
</option>
</select>
{this.state.isOpen && (
<DateRangePicker
value={this.props.value}
onSelect={this.props.change}
singleDateRange={true}
isOpen={false}
maximumDate={new Date()}
closeCalendar={true}
numberOfCalendars={2}
showLegend={true}
locale={originalMoment().locale()}
/>
)}
</div>
);
}
}
export default Filter;
Option onClick - Unnecessary
You can put onChange in the select tag
The select onChange trigerd when option is clicked (changed).
You can have a child component that only renders the option tag. You actually don't need to add an event handler to the option tag. The select onChange event get called automatically once an option tag is clicked (passing it's value with it).
See the example here: https://codepen.io/gaearon/pen/JbbEzX?editors=0010

JSX: Conditional statement within a map

I'm trying to understand how to incorporate conditional statements within JSX. I have an array of objects that I'm mapping to a select box. I want to exclude items that include the substring "threshold" in indicator.name.
So I can't use a ternary operator, because there's no "or" item. But I can't figure out how to include an if statement within this map. Whatever I try I get an error.
<select
defaultValue={defaultValue}
onChange={e => setIndicator(e.currentTarget.value)}
disabled={loading}
>
<option key='' value=''>
Select
</option>
{indicatorList.map(indicator => (
<option key={indicator.name} value={indicator.name}>
{indicator.label}
</option>
))}
</select>
you can filter then map:
<select
defaultValue={defaultValue}
onChange={e => setIndicator(e.currentTarget.value)}
disabled={loading}
>
<option key='' value=''>
Select
</option>
{indicatorList.filter(indicator=>indicator.name.includes('threshold')).map(indicator => (
<option key={indicator.name} value={indicator.name}>
{indicator.label}
</option>
))}
</select>
Or return null:
<select
defaultValue={defaultValue}
onChange={e => setIndicator(e.currentTarget.value)}
disabled={loading}
>
<option key='' value=''>
Select
</option>
{indicatorList.map(indicator => (
indicator.name.includes('threshold')?<option key={indicator.name} value={indicator.name}>:nul
{indicator.label}
</option>
))}
</select>
I would recommend using the filter method to filter out "threshold". This would return the array you are expecting to have inside JSX

Hiding Nested Data

In my react app I have I'm passing props for a view and two dropdowns. One dropdown is to let the user select an existing post to redirect to, the other is to choose a list from a 3rd party data source.
All of these are under three nested statements.
I don't want both of these dropdowns showing all the time, so I am trying to implement a simple dropdown function to hide the dropdown menu and the refresh list button:
{!this.props.view &&
<div onClick={this.toggleHidden} className="dropdown-wrapper">
{!this.state.isHidden &&
<select
className="dropdown">
<option value="none">
Redirect to an existing Post...
</option>
{this.props.sites
.filter(site => site.site !== undefined)
.map(site => (
<option value={site.site.name} key={site.id}>
{site.site.name}
</option>
))}
</select>
}
{emailProvider &&
<select className="dropdown"
>
<option key={0} value='none'>None</option>
{
emailProvider.length && emailProvider.length > 0 && emailProvider.map((eachData, key) => {
return (
<option key={key+1} value={eachData.id}>{eachData.name}</option>
)
})
}
</select>
}
<button style={{paddingTop: 14}}onClick = {this.handleClick}>Refresh List</button>
</div>
}
The hide function works for the first dropdown, but if I move the closing brace that is under the first</select> to after the </button>, the {emailProvider && code can't find the closing brace which is under the second select option. It returns an error }' expected as if the closing bracket is not there.
How do I encapsulate the two dropdowns and stop this error from occurring?
expression must have at least one parent element
{!this.props.view &&
<div onClick={this.toggleHidden} className="dropdown-wrapper">
{
!this.state.isHidden ?
<> {/*needs to be inside parent component*/}
<select
className="dropdown">
<option value="none">
Redirect to an existing Post...
</option>
{this.props.sites
.filter(site => site.site !== undefined)
.map(site => (
<option value={site.site.name} key={site.id}>
{site.site.name}
</option>
))}
</select>
<> {/*needs to be inside parent component*/}
{emailProvider &&
<select className="dropdown">
<option key={0} value='none'>None</option>
{
emailProvider.length && emailProvider.length > 0 && emailProvider.map((eachData, key) => {
return (
<option key={key + 1} value={eachData.id}>{eachData.name}</option>
)
})
}
</select>
}
</>
<button style={{ paddingTop: 14 }} onClick={this.handleClick}>Refresh List</button>
</>
:
null
}
</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