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 />
</>
)
Related
I have a reuseable component i created and the value is undefined. I console logged the currentTarget in the Select.tsx and it returns the value correctly. However, the actual component using the select is the one that returns an undefined value. What am i missing here?
This is the code in the select.Tsx
export const Select = (props: any) => {
const [data] = useState(props.data);
const [selectedData, updateSelectedData] = useState('');
function handleChange(event: any) {
updateSelectedData(event.currentTarget.value);
console.log(event.currentTarget.value, 'in select.tsx line 10');
if (props.onSelectChange) props.onSelectChange(selectedData);
}
let options = data.map((data: any) => (
<option key={data.id} value={data.id}>
{data.label}
</option>
));
return (
<>
<select
className={props.className ? props.className : 'float-right rounded-lg w-[50%] '}
onChange={handleChange}>
<option>Select Item</option>
{options}
</select>
</>
);
};
This is the code being used in the actual component...
...
const actionSelectOptions = [
{ id: 1, label: 'Pricing Revised', value: 'Pricing Revised' },
{ id: 2, label: 'Cost Build-up Posted', value: 'Cost Build-up Posted' },
{ id: 3, label: 'Pricing Created', value: 'Pricing Created' },
];
function onSelectChange(event: any) {
console.log(event.currentTarget.value);
}
return (
...
<Select
className="flex justify-center items-center rounded-lg"
data={actionSelectOptions}
onSelectChange={onSelectChange}
/>
...
)
I tried changing between target and currenTarget in the main component. It both get undefined.. the console works in the select component it seems as if the data is not passing on as its suppose to.
I also tried writing an arrow function within the actual called component for example:
<Select
...
onSelectChange={(e)=> console.log(event.currentTarget)}
I have a set of select menus and I need to find out the values for all of them when I reset them using reset buttons.
The problem is this only works on change event for options and I can't make it work on reset buttons on the first click as it doesn't detect the change.
Code sample here:
https://stackblitz.com/edit/react-rmp8kf
import React from 'react';
import { useState } from 'react';
import uuid from 'react-uuid';
export default function Select() {
const [value, setValue] = useState({
select1: '',
select2: '',
});
const selectOptions = [
{
options: [
{
text: 'All',
value: '0',
},
{
text: 'Blue',
value: '1',
},
{
text: 'Yellow',
value: '2',
},
{
text: 'Green',
value: '3',
},
],
},
{
options: [
{
text: 'All',
value: '0',
},
{
text: 'Black',
value: '1',
},
{
text: 'White',
value: '2',
},
],
},
];
const handleOnChange = (e) => {
const valueSelected = e.target.value;
setValue({
...value,
[e.target.name]: valueSelected,
});
printAllSelectValues();
};
const resetAllSelections = (e) => {
e.preventDefault();
setValue({
select1: '',
select2: '',
});
printAllSelectValues();
};
const resetSelection = (e) => {
e.preventDefault();
setValue({
...value,
[e.target.dataset.selectName]: '',
});
printAllSelectValues();
};
const printAllSelectValues = () => {
const selectMenus = document.querySelectorAll('select');
selectMenus.forEach((select) =>
console.log(select.name + '=' + select.value)
);
};
return (
<form>
<div>
<label>
<select
name="select1"
value={value.select1}
onChange={handleOnChange}
>
{selectOptions[0].options.map((option) => (
<option value={option.value} key={uuid()}>
{option.text}
</option>
))}
</select>
</label>
<button data-select-name="select1" onClick={resetSelection}>
Reset
</button>
</div>
<div>
<label>
<select
name="select2"
value={value.select2}
onChange={handleOnChange}
>
{selectOptions[1].options.map((option) => (
<option value={option.value} key={uuid()}>
{option.text}
</option>
))}
</select>
</label>
<button data-select-name="select2" onClick={resetSelection}>
Reset
</button>
</div>
<button onClick={resetAllSelections}>Reset All</button>
</form>
);
}
The stackblitz sandbox you linked seems to do exactly what you need to. You are getting both values correctly when:
You select any value in any of the 2 select elements
You reset any of the select values individually by using the reset button on the side of each select element
You reset both values at once by using the "Reset All" button
What is the problem? Do you want to get the updated values ?
UPDATE
Okey. So react has the nature that every state update is async, meaning that you need to wait for a state update to happen to use its updated values. Now, you cannot use promises or async/await to do this because react is built intentionally this way and gives you the tools to do so. So you need to use the useEffect hook for this.
https://stackblitz.com/edit/react-bekzpz
Note: worth mentioning that you don't need to grab the data from the HTML elements but in case you want to manipulate DOM elements in react, you are not supposed to do it using the document but by using the useRef hook
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'm having issues disabling certain options within a large list within a React Select element. I have around 6,500 options that get loaded into the select. At first I was having issues with the search functionality lagging but then I started using react-select-fast-filter-options which took care of that problem. Now the issue is that I need to disable certain options depending on the propType "picks". Here is the code:
import React, {Component} from 'react'
import PropTypes from 'prop-types';
import 'react-select/dist/react-select.css'
import 'react-virtualized/styles.css'
import 'react-virtualized-select/styles.css'
import Select from 'react-virtualized-select'
import createFilterOptions from 'react-select-fast-filter-options';
let options = [];
if(typeof stockSearchStocks !== 'undefined') {
//loads in all available options from backend by laying down a static js var
options = stockSearchStocks
}
const filterOptions = createFilterOptions({options});
class StockSearch extends Component {
static propTypes = {
exchanges: PropTypes.array.isRequired,
onSelectChange: PropTypes.func.isRequired,
searchDisabled: PropTypes.bool.isRequired,
picks: PropTypes.array.isRequired,
stock_edit_to_show: PropTypes.number
}
/**
* Component Bridge Function
* #param stock_id stocks id in the database
*/
stockSearchChange = (stock_id) => {
this.props.onSelectChange(stock_id);
}
//this is my current attempt to at least
//disable options on component mount but this doesn't seem to be working
componentWillMount = () => {
console.log('picks!: ' + JSON.stringify(this.props.picks));
let pickIDs = this.props.picks.map((p) => p.stock_id);
options = options.map((o) => {
// console.log(pickIDs.indexOf(o.value));
if(pickIDs.indexOf(o.value)) {
// console.log('here is the option: ' + JSON.stringify(o));
// console.log('here is the option: ' + o.disabled);
o.disabled = true;
}
})
}
/**
* handles selected option from the stock select
* #param selectedOption
*/
handleSelect = (selectedOption) => {
this.stockSearchChange(selectedOption.value);
}
render() {
return (
<div className="stock-search-container">
<Select
name="stock-search"
options={options}
placeholder="Type or select a stock here..."
onChange={this.handleSelect}
disabled={this.props.searchDisabled}
value={this.props.stock_edit_to_show}
filterOptions={filterOptions}
/>
</div>
)
}
}
export default StockSearch;
I have tried filtering through the picks props and changing that options variable to include disabled:true but this lags the application and I'm not sure if that will work now that I'm using react-select-fast-filter-options as it seems to be doing some sort of indexing. Is there a way to filter through the options var to find all instances of the picks prop and disable those options quickly?
isDisabled={this.props.disabled}
You are passing a wrong prop.. For v2, the prop is isDisabled.
https://github.com/JedWatson/react-select/issues/145
In react-select v2:
add to your array of options a property 'disabled': 'yes' (or any other pair to identify disabled options)
use isOptionDisabled props of react-select component to filter options based on 'disabled' property
Here's an example:
import Select from 'react-select';
const options = [
{label: "one", value: 1, disabled: true},
{label: "two", value: 2}
]
render() {
<Select id={'dropdown'}
options={options}
isOptionDisabled={(option) => option.disabled}>
</Select>
}
More information about react-select props is in the docs and here's an example they reference.
use the following to disable an option.
import Select from 'react-select';
render() {
const options = [
{label: "a", value: "a", isDisabled: true},
{label: "b", value: "b"}
];
return (
<Select
name="myselect"
options={options}
</Select>
)
}
People are making it a JavaScript issue. I say make it a CSS one and simplify.
Use this
style={{display: month === '2' ? 'none' : 'block'}}
Like so...
There are only 28 days in February
const ComponentName =() => {
const [month, setMonth] = useState("")
const [day, setDay] = useState("")
return (
<>
<select
onChange={(e) => {
const selectedMonth = e.target.value;
setMonth(selectedMonth)>
<option selected disabled>Month</option>
<option value= '1'>January</option>
<option value= '2'>February</option>
</select>
<select
onChange={(e) => {
const selectedDay = e.target.value;
setDay(selectedDay)>
<option selected disabled>Day</option>
<option value= '28'>28</option>
<option value= '29' style={{display: month === '2' ? 'none' : 'block'}}>29</option>
<option value= '30'>30</option>
</select>
</>
)
}
export default ComponentName;
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>