I need to pass multiple value by using onChange when I select the option, but I can not select single option . it select whole objects .
Here is my code .
const test = [{id:1, name:'test, value:{x:10}}]
<Select
showSearch
style={{ width: 200 }}
placeholder="Select a person"
optionFilterProp="children" >
{test.map(item =>(
<Option value={item.id, item.value}>{item.name}</Option>
))}
</Select>
is there an alternative solution to fix this problem
Use Custom select instead of select.
add multiple values in "eventKey" and on select handler you will find that value array.
import { ButtonToolbar,DropdownButton,MenuItem } from "react-bootstrap";
<ButtonToolbar className="snap-fitness-wrapper">
<DropdownButton
title={this.state.selectedFacilityName}
onSelect={this.onSelectFacility}
id="snap" >
{
this.state.facilities.map(facility => (
<MenuItem
key={facility.facilityId}
eventKey={[facility.facilityId, facility.name]}
value={facility.facilityId}
> {facility.name} - {facility.facilityId}{" "}
</MenuItem>
))
}
</DropdownButton>
</ButtonToolbar>
You can try below code.
const test = [{id:1, name:'test, value:{x:10}}]
<Select
multiple
showSearch
style={{ width: 200 }}
placeholder="Select a person"
optionFilterProp="children" >
{test.map(item =>(
<Option value={item.id, item.value}>{item.name}</Option>
))}
</Select>
If you are using react-select you can add isMulti common props to enable multiple selection for your option , please refer: https://react-select.com/props
BTW, react-select default use value label match, you have to remap for your case
const options = [
{ id: 1, name: 'test1', value:{x:10} },
{ id: 2, name: 'test2', value:{x:20} },
]
<Select
... // other code
isMulti
getOptionValue={option => option.value.x}
/>
It support multiple select , sample link : sandbox
I suppose you are using antd for select and want to get the object properties inside handleChange of select.
A simple method would be to send the id or other parameter and get the object through that.
import React from "react";
import ReactDOM from "react-dom";
import { Select } from "antd";
import "./styles.css";
const { Option } = Select;
const test = [
{ id: 1, name: "test1", value: { x: 10 } },
{ id: 2, name: "test2", value: { x: 11 } },
{ id: 3, name: "test3", value: { x: 12 } }
];
class App extends React.Component {
handleChange = id => {
const clickedOption = test.find(item => item.id === id);
const value = `${clickedOption.id}, ${clickedOption.value.x}`;
console.log(value);
};
render() {
return (
<div className="App">
<Select
onChange={this.handleChange}
style={{ width: 200 }}
placeholder="Select a person"
optionFilterProp="children"
>
{test.map((item, index) => (
<Option value={item.id} key={index}>
{item.name}
</Option>
))}
</Select>
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Hope that helps!!!
The simple way of doing this can be like this:
let options = test.map(item => {
return <option value={item.value} onClick={(item) => this.yourhandlerfunction(item)}>item.name</option>
})
render(){
return(
<Select>
{options}
</Select>
)
}
Hope this helps!
You can just pass a second variable in onChange=((e) => this.handleChange(e, item.value) property
const handleChange = (event, itemValue) => {
console.log(`id: ${event.target.value}, value: ${itemValue}`)
}
const test = [{id:1, name:'test', value:{x:10}}]
<Select
multiple
showSearch
style={{ width: 200 }}
placeholder="Select a person"
optionFilterProp="children"
onChange={(e) => this.handleChange(e, item.value)}
>
{test.map((item) =>(
<Option key={key} value={item.id}>{item.name}</Option>
))}
</Select>
Related
I am new to React. I'm using react-select and I've used the following code. The dropdown is displayed but I'm unable to see names and unable to view after selecting.
<Select
variant="outlined"
margin="normal"
fullWidth
value={this.state.selected}
options={RewardAutomationsList}
name="selected"
onChange={this.handleChange}
placeholder='None'
>
{RewardAutomationsList.map((option) => (
<option key={option.id} value ={option.name} label={option.name}>
{option.name}
</option>
))}
</Select>
handleChange = event => {
this.setState({
selected: event.name
});
};
The RewardAutomationsList looks like this:
RewardAutomationsList:
0:{name: "TEST 1 (INR 100)", id: "123"}
1:{name: "test 2 (INR 250)", id: "456"}
Can someone help with this?
same npm package use like this block code.
import React, { Component } from 'react'
import Select from 'react-select'
const options = [
{ value: 'chocolate', label: 'Chocolate' },
{ value: 'strawberry', label: 'Strawberry' },
{ value: 'vanilla', label: 'Vanilla' }
]
const MyComponent = () => (
<Select options={options} />
)
react-select accepts an array of objects having label and value keys. Your option objects in RewardAutomationsList have id and name keys, so it can't be displayed. You need to change them.
Also, when you subscribe to change events with react-select's onChange prop, the callback function you provide receives the selectedOption, not the event.
The following should work:
const RewardAutomationsList = [
{ label: "TEST 1 (INR 100)", value: "123" },
{ label: "test 2 (INR 250)", value: "456" },
];
class App extends React.Component {
state = {
selected: null,
}
handleChange = (selectedOption) => {
this.setState({
selected: selectedOption,
});
};
render() {
return (
<React.Fragment>
<Select
fullWidth
margin="normal"
name="selected"
onChange={this.handleChange}
options={RewardAutomationsList}
placeholder="None"
value={this.state.selected}
variant="outlined"
/>
{/* It's not necessary and it's only here to show the current state */}
<pre>{JSON.stringify(this.state, null, 2)}</pre>
</React.Fragment>
);
}
}
I created a form with redux-form. It works correctly but if I don't change select (I'll leave the default value), the value won't send, but if I change the value it will be sent in post method.
export const mySelect = (props) => {
const mySelectOptions = (key, index) => {
return (
<option key={props.options[key].id} value={props.options[key].id}>
{props.options[key].name}
</option>
);
};
if (props && props.options) {
return (
<div className="mv3 w-100">
<div className="b sans-serif pv2 w-100">{props.label}</div>
<select
{...props.input}
className="pa2 input-reset ba b--black-40 w-100"
>
{Object.keys(props.options).map(renderSelectOptions)}
</select>
</div>
);
}
return <div></div>;
};
Example
<Field
name="gender"
label="gender"
component={input.mySelect}
options={[
{
id: 1,
name: "male",
},
{
id: 2,
name: "female",
},
]}
/>;
I tried to set a default value in my SQL table but every time it sends null. Do you know how can I solve my problem?
I have a list of chat room channels for people to talk i.e there is a lifestyle channel, shopping channel, pets channel etc.
I am now trying to categorise each channel to make it easier for the user to find what they want. In order to do so, on creation of a chatroom channel I need the user to select which category the channel they are creating best fits into. A bit like YouTube does when you upload a video.
So far I have created a separate component which is a list of checkboxes with the different categories the user can put their channel into:
import React from 'react';
const options = [
{ label: "Lifestyle", value: "lifestyle"},
{ label: "Area", value: "area" },
{ label: "Random", value: "random" },
{ label: "Comedy", value: "comedy" },
{ label: "Entertainment", value: "entertainment" }
];
const ChannelCategory = (props) => {
return (
<div>
{props.title}
<ul>
{options.map((option) => (
<li key={props.key}>
<label>
{option.label}
<input
className={props.className}
name="test"
checked={props.checked}
onChange={() => props.onChange(option.value)}
type="checkbox"
/>
</label>
</li>
))}
</ul>
</div>
)
};
export default ChannelCategory;
I am using the above component on the page below, I would like that when the user selects just ONE of the options only ONE input box is checked, however at the moment when I click ONE input box for instance lifestyle they ALLLL get checked and for every single channel too:( Any ideas why?
const [checked, setCheckBoxChecked] = useState(false);
[...]
const onAddCategory = (value) => {
console.log(value);
if (value === "lifestyle") {
setCheckBoxChecked(checked => !checked);
}
if (value === "area") {
setCheckBoxChecked(checked => !checked);
}
if (value === "random") {
setCheckBoxChecked(checked => !checked);
}
if (value === "comedy") {
setCheckBoxChecked(checked => !checked);
}
};
[...]
const options = [
{ label: "Lifestyle", value: "lifestyle"},
{ label: "Area", value: "area" },
{ label: "Random", value: "random" },
{ label: "Comedy", value: "comedy" },
{ label: "Entertainment", value: "entertainment" }
];
return (
<form noValidate autoComplete='off' onSubmit={onSubmit}>
<Card style={styles.card}>
<CardContent>
<Box padding={3}>
<FormLegend title={`${formTitle} (${channels.length})`} description={formDescription} />
<Box marginTop={3} width='50%'>
<Grid container direction='column' justify='flex-start' alignItems='stretch' spacing={1}>
{channels.map(channel => {
return (
<Grid key={channel.key} item style={styles.gridItem} justify="space-between">
<ChannelListItem
channel={channel}
isSaving={isSaving}
onDeleteChannelClick={onDeleteChannelClick}
key={channel.Key}
onFormControlChange={onFormControlChange}
onUndoChannelClick={onUndoChannelClick}
/>
<ChannelCategory
key={channel.key}
options={options}
onChange={value => onAddCategory(value)}
title="Add your chatroom to a category so that users can find it easily"
checked={checked}
/>
</Grid>
)
})}
[...]
</Grid>
</Grid>
</Box>
</Box>
</CardContent>
</Card>
</form>
);
Instead of storing true or false inside the checked variable, you should store the value inside of checked. Like this:
const onChangeAttribute = (value) => {
console.log(value);
setCheckBoxChecked(value);
};
And now while rendering the checkbox you should check if checked is equal to the name of that checkbox like this:
<input
className={props.className}
name={option.value}
checked={props.checked === option.value}
onChange={() => props.onChange(option.value)}
type="checkbox"
/>
This should resolve your issue.
Use an array to store all checked boxes and in your ChannelCategory check if the current value exists in the checked array then set checked to true for that checkbox. If you want to select only one category use radio buttons
const {useState, useEffect} = React;
const options = [
{ label: "Lifestyle", value: "lifestyle" },
{ label: "Area", value: "area" },
{ label: "Random", value: "random" },
{ label: "Comedy", value: "comedy" },
{ label: "Entertainment", value: "entertainment" }
];
const ChannelCategory = props => {
return (
<div>
{props.title}
<ul>
{props.options.map(option => (
<li key={props.key}>
<label>
{option.label}
<input
className={props.className}
name={option.value}
checked={props.checked.includes(option.value)}
onChange={e => props.onChange(e.target.checked, option.value)}
type="checkbox"
/>
</label>
</li>
))}
</ul>
</div>
);
};
function App() {
const [checked, setCheckBoxChecked] = useState([]);
const onAddCategory = (isChecked, value) => {
const temp = [...checked];
if (isChecked) {
temp.push(value);
setCheckBoxChecked(temp);
return;
}
setCheckBoxChecked(temp.filter(item => item !== value));
};
return (
<div className="App">
<ChannelCategory
key={"channel.key"}
options={options}
onChange={onAddCategory}
title="Add your chatroom to a category so that users can find it easily"
checked={checked}
/>
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Radio buttons example
I want to store select default value if user not touch it in ReactJs. How is that possible?
<select onChange={this.valSelected.bind(this)}>
{currencies.map(function(name, index){
return <option value={name}>{name}</option>;
})}
</select>
and
valSelected(event){
this.setState({
valSelected: event.target.value
});
}
You can just add a value property to the select element, set by your state.
<select value={this.state.valSelected} onChange={this.valSelected.bind(this)}>
{currencies.map(function(name, index){
return <option value={name}>{name}</option>;
})}
</select>
This is described here in the react docs: Doc Link
Then set a default state for the component, either in the constructor or with getInitialState: What is the difference between using constructor vs getInitialState in React / React Native?
Use defaultValue to select the default value.
const statusOptions = [
{ value: 1, label: 'Publish' },
{ value: 0, label: 'Unpublish' }
];
const [statusValue, setStatusValue] = useState('');
const handleStatusChange = e => {
setStatusValue(e.value);
}
return(
<>
<Select options={statusOptions} defaultValue={[{ value: published, label: published == 1 ? 'Publish' : 'Unpublish' }]} onChange={handleStatusChange} value={statusOptions.find(obj => obj.value === statusValue)} required />
</>
)
The example code in the react-bootstrap site shows the following. I need to drive the options using an array, but I'm having trouble finding examples that will compile.
<Input type="select" label="Multiple Select" multiple>
<option value="select">select (multiple)</option>
<option value="other">...</option>
</Input>
You can start with these two functions. The first will create your select options dynamically based on the props passed to the page. If they are mapped to the state then the select will recreate itself.
createSelectItems() {
let items = [];
for (let i = 0; i <= this.props.maxValue; i++) {
items.push(<option key={i} value={i}>{i}</option>);
//here I will be creating my options dynamically based on
//what props are currently passed to the parent component
}
return items;
}
onDropdownSelected(e) {
console.log("THE VAL", e.target.value);
//here you will see the current selected value of the select input
}
Then you will have this block of code inside render. You will pass a function reference to the onChange prop and everytime onChange is called the selected object will bind with that function automatically. And instead of manually writing your options you will just call the createSelectItems() function which will build and return your options based on some constraints (which can change).
<Input type="select" onChange={this.onDropdownSelected} label="Multiple Select" multiple>
{this.createSelectItems()}
</Input>
My working example
this.countryData = [
{ value: 'USA', name: 'USA' },
{ value: 'CANADA', name: 'CANADA' }
];
<select name="country" value={this.state.data.country}>
{this.countryData.map((e, key) => {
return <option key={key} value={e.value}>{e.name}</option>;
})}
</select>
bind dynamic drop using arrow function.
class BindDropDown extends React.Component {
constructor(props) {
super(props);
this.state = {
values: [
{ name: 'One', id: 1 },
{ name: 'Two', id: 2 },
{ name: 'Three', id: 3 },
{ name: 'four', id: 4 }
]
};
}
render() {
let optionTemplate = this.state.values.map(v => (
<option value={v.id}>{v.name}</option>
));
return (
<label>
Pick your favorite Number:
<select value={this.state.value} onChange={this.handleChange}>
{optionTemplate}
</select>
</label>
);
}
}
ReactDOM.render(
<BindDropDown />,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="root">
<!-- This element's contents will be replaced with your component. -->
</div>
// on component load, load this list of values
// or we can get this details from api call also
const animalsList = [
{
id: 1,
value: 'Tiger'
}, {
id: 2,
value: 'Lion'
}, {
id: 3,
value: 'Dog'
}, {
id: 4,
value: 'Cat'
}
];
// generage select dropdown option list dynamically
function Options({ options }) {
return (
options.map(option =>
<option key={option.id} value={option.value}>
{option.value}
</option>)
);
}
<select
name="animal"
className="form-control">
<Options options={animalsList} />
</select>
Basically all you need to do, is to map array. This will return a list of <option> elements, which you can place inside form to render.
array.map((element, index) => <option key={index}>{element}</option>)
Complete function component, that renders <option>s from array saved in component's state. Multiple property let's you CTRL-click many elements to select. Remove it, if you want dropdown menu.
import React, { useState } from "react";
const ExampleComponent = () => {
const [options, setOptions] = useState(["option 1", "option 2", "option 3"]);
return (
<form>
<select multiple>
{ options.map((element, index) => <option key={index}>{element}</option>) }
</select>
<button>Add</button>
</form>
);
}
component with multiple select
Working example: https://codesandbox.io/s/blue-moon-rt6k6?file=/src/App.js
A 1 liner would be:
import * as YourTypes from 'Constants/YourTypes';
....
<Input ...>
{Object.keys(YourTypes).map((t,i) => <option key={i} value={t}>{t}</option>)}
</Input>
Assuming you store the list constants in a separate file (and you should, unless they're downloaded from a web service):
# YourTypes.js
export const MY_TYPE_1="My Type 1"
....
You need to add key for mapping otherwise it throws warning because each props should have a unique key. Code revised below:
let optionTemplate = this.state.values.map(
(v, index) => (<option key={index} value={v.id}>{v.name}</option>)
);
You can create dynamic select options by map()
Example code
return (
<select className="form-control"
value={this.state.value}
onChange={event => this.setState({selectedMsgTemplate: event.target.value})}>
{
templates.map(msgTemplate => {
return (
<option key={msgTemplate.id} value={msgTemplate.text}>
Select one...
</option>
)
})
}
</select>
)
</label>
);
I was able to do this using Typeahead. It looks bit lengthy for a simple scenario but I'm posting this as it will be helpful for someone.
First I have created a component so that it is reusable.
interface DynamicSelectProps {
readonly id: string
readonly options: any[]
readonly defaultValue: string | null
readonly disabled: boolean
onSelectItem(item: any): any
children?:React.ReactNode
}
export default function DynamicSelect({id, options, defaultValue, onSelectItem, disabled}: DynamicSelectProps) {
const [selection, setSelection] = useState<any[]>([]);
return <>
<Typeahead
labelKey={option => `${option.key}`}
id={id}
onChange={selected => {
setSelection(selected)
onSelectItem(selected)
}}
options={options}
defaultInputValue={defaultValue || ""}
placeholder="Search"
selected={selection}
disabled={disabled}
/>
</>
}
Callback function
function onSelection(selection: any) {
console.log(selection)
//handle selection
}
Usage
<div className="form-group">
<DynamicSelect
options={array.map(item => <option key={item} value={item}>{item}</option>)}
id="search-typeahead"
defaultValue={<default-value>}
disabled={false}
onSelectItem={onSelection}>
</DynamicSelect>
</div>