How do I add onClick() on a Select Dropdown via React - javascript

I'm trying to apply reactI18next on a project, normally you to toggle the language change you would create a button that would call the "changelanguage" function like this:
const changeLanguage = (lng) => {
i18n.changeLanguage(lng);
}
<button onClick={() => changeLanguage('en')}>en</button>
However, I was wondering if it's possible to make something similar but In a dropdown fashion.
Is there a way to trigger an onClick via select or other means?
Thanks and I hope to hear you guys soon!

Yes this is possible, you can add onChange event handler on Select tag such as
import { useState } from "react";
export default function App() {
const [lang , setLang] = useState('en')
function changeLanguage(event){
// i18n.changeLanguage(event.target.value)
setLang(event.target.value)
}
return (
<div className="App">
<h1>Hello CodeSandbox</h1>
<p>{lang}</p>
<select value={lang} onChange={changeLanguage}>
<option value="en">English</option>
<option value="fr">French</option>
</select>
</div>
);
}
you can test on working sandbox here

You can just use the onChange prop on the <select> element.
import { useState } from "react";
const languages = {
en: "English",
ta: "Tagalog",
es: "Español"
};
export default function App() {
const [selectedValue, setSelectedValue] = useState("en");
function onChange(e) {
il18n.changeLanguage(e.target.value); // Use your library here
setSelectedValue(e.target.value);
}
return (
<div className="App">
<label for="lang">Choose a language: </label>
<select name="lang" id="lang" onChange={onChange}>
{Object.keys(languages).map((languageKey) => (
<option key={languageKey} value={languageKey}>
{languages[languageKey]}
</option>
))}
</select>
<br />
<br />
<p>Currently selected:</p>
<p>Key: {selectedValue}</p>
<p>Value: {languages[selectedValue]}</p>
</div>
);
}

Please try this one
const [value, setValue] = React.useState('');
const changeLanguage = (event) => {
i18n.changeLanguage(event.target.value);
}
<select value={value} onChange={changeLanguage}>
<option value="en">English</option>
</select>

Related

Antd Select - how to show different value in the dropdown and Input field

Current UI
Expected Behaviour
How can I do it?
App.tsx
import React from "react";
import "./index.css";
import { Select } from "antd";
const { Option } = Select;
const countryNames = [
{
name: "Japan",
code: "+987"
},
{
name: "aVeryVeryVeryVeryLongCountryName",
code: "+123"
}
];
const handleChange = (value: string) => {
console.log(`selected ${value}`);
};
const App: React.FC = () => (
<>
<Select defaultValue="Japan" onChange={handleChange}>
{countryNames.map((country) => (
<Option key={country.name} value={country.name}>
{`${country.code} ${country.name}`}
</Option>
))}
</Select>
</>
);
export default App;
Codesandbox
https://codesandbox.io/s/basic-usage-antd-5-1-5-forked-mfw8fj?file=/demo.tsx
According to antd document, Select can specify a label value from a Option props with optionLabelProp, which in this use case can get value from country.code.
For extending size of Option based on its content, dropdownMatchSelectWidth can be set false, so that the Option is not limited to the size of Select.
Modified demo on: codesandbox
<Select
defaultValue="Japan"
onChange={handleChange}
// 👇 Specify label prop here
optionLabelProp="label"
// 👇 Set Option to be extendable by content here
dropdownMatchSelectWidth={false}
>
{countryNames.map((country) => (
<Option
key={country.name}
value={country.name}
// 👇 Give label value for Select here
label={country.code}
>
{`${country.code} ${country.name}`}
</Option>
))}
</Select>

How to filter an array on click in react?

So, basically, I'm making a website where you can search for Minecraft hacked clients. There is a search bar on the website, but you have to search in exact terms (different topic lol). Basically on the click of a button (search button) I then want to filter using the search term, (not automatically as I have it now) I've been searching but cant find a way to do it.
Code ->
import CountUp from 'react-countup';
import { Link } from 'react-router-dom';
import '../App.css';
/*Components ->*/
import Client from '../components/client.js'
function App() {
const [search, setSearch] = React.useState({
searchname: ''
});
**Array containing client data ->** const [client, setClient] = React.useState([
{ safestatus: 'safe-status-green', safe: 'Safe (Verified)', name: 'Impact', price: 'Free', mcversion: '1.11.2 - 1.16.5', type: 'Injected', compat: 'None (Stand alone client)', desc: 'The Impact client is an advanced utility mod for Minecraft, it is packaged with Baritone and includes a large number of useful mods.', screen: 'https://impactclient.net/', download: 'https://impactclient.net/'},
{ safestatus: 'safe-status-green', safe: 'Safe (Verified)', name: 'Future', price: '15€', mcversion: '1.8.9 - 1.14.4', type: 'Injected', compat: 'None (Stand alone client)', desc: 'Vanilla, OptiFine, Forge and Liteloader support, Easy to use account manager, Auto-reconnect mod.', screen: 'https://www.futureclient.net/', download: 'https://www.futureclient.net/'}
]);
const updateSearch = (event) => {
event.persist();
setSearch((prev) => ({
...prev,
[event.target.name]: event.target.value
}));
};
return (
<body>
<div className='header'><Link to='/'>Hacked Hub</Link><div className='header-links'><Link to='/about-us'>About Us</Link> | <Link to='/faq'>FAQ</Link></div></div>
<div className='counter'><CountUp end={16} duration={0.5}></CountUp>+</div>
<div className='counter-desc'><div className='code'>hacked clients</div> and counting...</div>
<div className='nxt-tab'>
<input name='searchname' value={search.searchname} onChange={updateSearch} placeholder='Search'></input>
<select name='price'>
<option value='Free'>Free</option>
<option value='Paid'>Paid</option>
</select>
<select name='safe'>
<option value='Safe'>Safe</option>
<option value='Probably Safe'>Probably Safe</option>
<option value='Not Safe'>Not Safe (BE CAREFUL!)</option>
</select>
<select name='mcver'>
<option value='1.8.9'>1.8.9</option>
<option value='1.12.2'>1.12.2</option>
<option value='1.16.5'>1.16.5</option>
<option value='1.17+'>1.17+</option>
</select>
<select name='type'>
<option value='Main'>Injected</option>
<option value='Side'>Mod</option>
</select>
<select name='compatibility'>
<option value='With Most Other Clients'>With Most Other Clients</option>
<option value='Stand Alone'>Stand Alone</option>
</select>
<div className='client-warning'><div className='safe-status-red'><div className='code'>⚠ WARNING ⚠</div></div> Only download clients you know are <div className='code'>100%</div> safe! If we do find a client that is a <div className='code'>rat / virus / BTC miner</div> we will tag it as <div className='safe-status-red'><div className='code'>UNSAFE IMMEDIATELY</div></div>. The saftey warnings for clients are <div className='code'>MERE RECCOMENDATIONS</div>, please do thorough research before downloading any hacked client that you are not <div className='code'>100%</div> sure is safe. This page is also in <div className='code'>development</div>, meaning features are prone to break! So be careful!!!</div>
<div className='code'>Sponsored clients</div>
<h1>None XD</h1>
<div className='code'>Submitted clients</div>
{client
**Filtering the array then mapping it -> (This i want to do onClick)** .filter((client) => client.name === search.searchname)
.map((client, index) => {
return (
<Client
safestatus={client.safestatus}
safe={client.safe}
name={client.name}
price={client.price}
mcversion={client.mcversion}
type={client.type}
compat={client.compat}
desc={client.desc}
screen={client.screen}
download={client.download}
/>
);
})}
</div>
</body>
);
}
export default App;
Anyone know how I could do this onClick?
Use two pieces of state; one to track the value in your text field and the other to store the search term for filtering. Only set the latter when you click your button
const [ searchValue, setSearchValue ] = React.useState("")
const [ searchTerm, setSearchTerm ] = React.useState("")
const filteredClient = React.useMemo(() => {
if (searchTerm.length > 0) {
return client.filter(({ name }) => name === searchTerm)
}
return client
}, [ searchTerm, client ])
and in your JSX
<input
name="searchname"
placeholder="Search"
value={searchValue}
onChange={e => setSearchValue(e.target.value)}
/>
<!-- snip -->
<button
type="button"
onClick={() => setSearchTerm(searchValue)}
>Search</button>
<!-- snip -->
{filteredClient.map((client, index) => (
<Client .../>
))}

How can I bind the event to the function callback or any alternative solution?

I'm creating a library web app with React, the idea of the app is to categorize books into shelves (Want to Read ,Currently Reading shelf, Read shelf, none) using a select button on each book component, there are two issues so far, first: can't bind the event to the function callback and can't store the book element in a useState hook array to use its props such as id in categorizing books into shelves.
The Error I get
import React, { useState, useEffect } from "react";
import { getAll, search, get, update, api } from "./../BooksAPI";
function Book(props) {
const [currState, setCurrState] = useState({
shelf: [],
book: [],
});
const updatingBooks = async function (event) {
const shelf = event.target.value;
const book = event.target.closest(".book");
const { id } = book;
setCurrState(() => {
return currState.shelf.push(shelf);
});
setCurrState(() => {
return currState.book.push(book);
});
await update(currState.shelf, currState.book);
};
useEffect(() => {
updatingBooks();
console.log(currState.shelf, currState.book);
}, []);
useEffect(() => {
console.log(currState.shelf, currState.book);
}, [currState.shelf, currState.book]);
return (
<div className="book" id={props.id}>
<div className="book-top">
<div
className="book-cover"
style={{
width: 128,
height: 193,
backgroundImage: `url(${props.url})`,
}}
/>
<div className="book-shelf-changer">
<select onChange={updatingBooks}>
<option value="move" disabled>
Move to...
</option>
<option value="wantToRead">Want to Read</option>
<option value="currentlyReading">Currently Reading</option>
<option value="read">Read</option>
<option value="none">None</option>
</select>
</div>
</div>
<div className="book-title">{props.title}</div>
<div className="book-authors">{props.authors}</div>
<div></div>
</div>
);
}
export default Book;

React <select>'s <option> is not working at onClick

I need a function at every here is it.
i want to access option value.
const region = ['Africa','America','Asia','Europe','Oceania'];
<div className="options">
<select>
<option>Select a Region</option>
{region.map((nameOfRegion) => {
return <option onClick={() => requestRegion(nameOfRegion)}>
{nameOfRegion}
</option>
})}
</select>
this function is not logging options
const requestRegion = (region) => {
console.log(region)
}
Use onChange event on the <select>:
const requestRegion = (event) => {
console.log(event.target.value);
};
return (
<div className="options">
<select onChange={requestRegion}>
<option>Select a Region</option>
{
region.map((nameOfRegion) => (<option>{nameOfRegion}</option>))
}
</select>
</div>
Because neither the onSelect() nor onClick() events are supported by the option tag. So you can use onChange in select tag in this case:
const onChange =(e) => {
console.log(e.target.value);
}
<select name="select" onChange = {onChange}>
<option>Select a Region</option>
{region.map((nameOfRegion, i) => {
return (
<option key={i}>
{nameOfRegion}
</option>
);
})}
</select>
Note: you need add key in child tag when using map
You should use an onChange handler on the select element, and get the value from the change event:
const Demo = ({ regions }) => {
const requestRegion = e => {
console.log(e.target.value)
}
return (
<select onChange={requestRegion}>
<option>Select a Region</option>
{regions.map(region => (
<option key={region}>{region}</option>
))}
</select>
)
}
const regions = ['Africa','America','Asia','Europe','Oceania']
ReactDOM.render(
<Demo regions={regions} />,
root
)
<script crossorigin src="https://unpkg.com/react#17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom#17/umd/react-dom.development.js"></script>
<div id="root"></div>

OnChange event using React JS for drop down

var MySelect = React.createClass({
change: function(){
return document.querySelector('#lang').value;
},
render: function(){
return(
<div>
<select id="lang">
<option value="select" onChange={this.change}>Select</option>
<option value="Java" onChange={this.change}>Java</option>
<option value="C++" onChange={this.change}>C++</option>
</select>
<p></p>
<p value={this.change}></p>
</div>
);
}
});
React.render(<MySelect />, document.body);
The onChange event does not work.
The change event is triggered on the <select> element, not the <option> element. However, that's not the only problem. The way you defined the change function won't cause a rerender of the component. It seems like you might not have fully grasped the concept of React yet, so maybe "Thinking in React" helps.
You have to store the selected value as state and update the state when the value changes. Updating the state will trigger a rerender of the component.
var MySelect = React.createClass({
getInitialState: function() {
return {
value: 'select'
}
},
change: function(event){
this.setState({value: event.target.value});
},
render: function(){
return(
<div>
<select id="lang" onChange={this.change} value={this.state.value}>
<option value="select">Select</option>
<option value="Java">Java</option>
<option value="C++">C++</option>
</select>
<p></p>
<p>{this.state.value}</p>
</div>
);
}
});
React.render(<MySelect />, document.body);
Also note that <p> elements don't have a value attribute. React/JSX simply replicates the well-known HTML syntax, it doesn't introduce custom attributes (with the exception of key and ref). If you want the selected value to be the content of the <p> element then simply put inside of it, like you would do with any static content.
Learn more about event handling, state and form controls:
http://facebook.github.io/react/docs/interactivity-and-dynamic-uis.html
http://facebook.github.io/react/docs/forms.html
React Hooks (16.8+):
const Dropdown = ({
options
}) => {
const [selectedOption, setSelectedOption] = useState(options[0].value);
return (
<select
value={selectedOption}
onChange={e => setSelectedOption(e.target.value)}>
{options.map(o => (
<option key={o.value} value={o.value}>{o.label}</option>
))}
</select>
);
};
import React, { PureComponent, Fragment } from 'react';
import ReactDOM from 'react-dom';
class Select extends PureComponent {
state = {
options: [
{
name: 'Select…',
value: null,
},
{
name: 'A',
value: 'a',
},
{
name: 'B',
value: 'b',
},
{
name: 'C',
value: 'c',
},
],
value: '?',
};
handleChange = (event) => {
this.setState({ value: event.target.value });
};
render() {
const { options, value } = this.state;
return (
<Fragment>
<select onChange={this.handleChange} value={value}>
{options.map(item => (
<option key={item.value} value={item.value}>
{item.name}
</option>
))}
</select>
<h1>Favorite letter: {value}</h1>
</Fragment>
);
}
}
ReactDOM.render(<Select />, window.document.body);
handleChange(value, selectOptionSetter) => {
selectOptionSetter(value)
// handle other stuff like persisting to store etc
}
const Dropdown = (props) => {
const { options } = props;
const [selectedOption, setSelectedOption] = useState(options[0].value);
return (
<select
value={selectedOption}
onChange={e => handleChange(e.target.value, setSelectedOption)}>
{options.map(o => (
<option key={o.value} value={o.value}>{o.label}</option>
))}
</select>
);
};
If you are using select as inline to other component, then you can also use like given below.
<select onChange={(val) => this.handlePeriodChange(val.target.value)} className="btn btn-sm btn-outline-secondary dropdown-toggle">
<option value="TODAY">Today</option>
<option value="THIS_WEEK" >This Week</option>
<option value="THIS_MONTH">This Month</option>
<option value="THIS_YEAR">This Year</option>
<option selected value="LAST_AVAILABLE_DAY">Last Availabe NAV Day</option>
</select>
And on the component where select is used, define the function to handle onChange like below:
handlePeriodChange(selVal) {
this.props.handlePeriodChange(selVal);
}
I'll add this here, in case it helps someone because this was the solution that helped me.
This is to get the SELECTED INDEX. Not for the value.
(Worked for me because my options list was a list of numbers)
const [selectedOption, setSelectedOption] = useState(0)
<select onChange={event => setSelectedOption(event.target.options.selectedIndex)}>
Thank you Felix Kling, but his answer need a little change:
var MySelect = React.createClass({
getInitialState: function() {
return {
value: 'select'
}
},
change: function(event){
this.setState({value: event.target.value});
},
render: function(){
return(
<div>
<select id="lang" onChange={this.change.bind(this)} value={this.state.value}>
<option value="select">Select</option>
<option value="Java">Java</option>
<option value="C++">C++</option>
</select>
<p></p>
<p>{this.state.value}</p>
</div>
);
}
});
React.render(<MySelect />, document.body);
var MySelect = React.createClass({
getInitialState: function() {
var MySelect = React.createClass({
getInitialState: function() {
return {
value: 'select'
}
},
change: function(event){
event.persist(); //THE MAIN LINE THAT WILL SET THE VALUE
this.setState({value: event.target.value});
},
render: function(){
return(
<div>
<select id="lang" onChange={this.change.bind(this)} value={this.state.value}>
<option value="select">Select</option>
<option value="Java">Java</option>
<option value="C++">C++</option>
</select>
<p></p>
<p>{this.state.value}</p>
</div>
);
}
});
React.render(<MySelect />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>

Categories

Resources