Hello guys I'm using React Material UI select. When I change option I trigger onChange method and add attr on selected value so how can I set fisrt option of items as selected.
value={} **// I want to display first option to selected without trigger on Change method**
onChange={(e) => {
data.forEach(a => {
if (a.Id === e.target.value) {
a.selected = true
} else {
a.selected = false
}
});
}}
>
<MenuItem disabled value=""><em>Please Select</em></MenuItem>
{data.map((item) => {
return (
<MenuItem key={item.Id} value={item.Id} >
{item.Ad}
</MenuItem>
);
})}
</Select>
You need 2 states on your component, data and active. Where data is the items you want to display on the dropdown, and active which indicates what item is currently selected. Commonly, we use useEffect hook to initialize states.
Also, wehave to re-implement your onChange function. I suggest you review the docs on how to update states on functional component https://reactjs.org/docs/hooks-reference.html#usestate.
Anyway, you can change your code to this
export default function App() {
const [data, setData] = React.useState(DATA);
// select the first option by default
const [active, setActive] = React.useState(DATA[0].Id);
function onChange(event) {
setActive(event.target.value);
}
return (
<Select value={active} onChange={onChange} fullWidth>
<MenuItem disabled value="">
<em>Please Select</em>
</MenuItem>
{data.map((item) => (
<MenuItem key={item.Id} value={item.Id}>
{item.Ad}
</MenuItem>
))}
</Select>
);
}
...and I created a codesandbox for you to try it out.
Related
I have a list of users and a Select dropdown from material UI with some values. I am able to console.log the values of the select but how can I know to which user in the List they refer to?
<List>
{userList.map((user:any) => (
<ListItem key={user.key}>
<ListItemAvatar>
<Avatar>
<PersonIcon />
</Avatar>
</ListItemAvatar>
<ListItemText primary={user.name} />
<Select
value={userValue}
onChange={handleChange}
>
{dropdownvalues.map(
(g: { value: string}) => (
<MenuItem key={g.value} value={g.value}>
{g.value}
</MenuItem>
)
)}
</Select>
</ListItem>
))}
</List>
const handleChange=(e:any,index:any) => {
console.log(e.target.value)//here I am able to console log just the value how can I bind the user too given the fact that this funciton doesnt accept another parameter
}
Just add index as value as it is uniquely identifiable in the following code -
{dropdownvalues.map(
(g: { value: string},index:number) => (
<MenuItem key={g.value} value={index}>
{g.value}
</MenuItem>
)
)}
After that just access your selected user as -
const handleChange = (e:any) => {
const selectedInd = e.target.value;
console.log('index->',selectedInd);
console.log(dropdownvalues[e.target.value]);
}
Simplest way is to extend your handleChange function and call like this:
// ...
onChange={(evt) => handleChange(user)}
// ... And then extend the function:
const handleChange=(user:any) => {
console.log(user)
}
The Material UI documentation includes an example of a multiple select where the selected options are rendered with the Chip component by using the renderValue prop on the Select. The standard behavior for the Select component is that clicking on the current value opens the list of options.
I am trying to tweak this so that the Chips show the X button, and clicking on the X should instantly remove that item from the selections rather than opening the options list.
That seems easy, but I can't get the onDelete event of the Chip to fire. Clicking the X still just opens the Select.
How can I get the onDelete event to take priority? From what I know about event bubbling, it seems like the Chip should handle the event first.
Code Sandbox Demo
Code:
const MultipleSelectDemo = () => {
const [personName, setPersonName] = React.useState<string[]>(initialSelected);
const handleChange = (event: React.ChangeEvent<{ value: unknown }>) => {
setPersonName(event.target.value as string[]);
};
// this never gets called
const handleDelete = (e: React.MouseEvent, value: string) => {
e.preventDefault();
console.log("clicked delete");
setPersonName((current) => _without(current, value));
};
return (
<div>
<FormControl>
<InputLabel id="demo-mutiple-chip-checkbox-label">
Chip + Check
</InputLabel>
<Select
labelId="demo-mutiple-chip-checkbox-label"
id="demo-mutiple-chip-checkbox"
multiple
value={personName}
onChange={handleChange}
onOpen={() => console.log("select opened")}
IconComponent={KeyboardArrowDownIcon}
renderValue={(selected) => (
<div>
{(selected as string[]).map((value) => (
<Chip
key={value}
label={value}
clickable
className={classes.chip}
onDelete={(e) => handleDelete(e, value)}
onClick={() => console.log("clicked chip")}
/>
))}
</div>
)}
>
{names.map((name) => (
<MenuItem key={name} value={name}>
<Checkbox checked={personName.includes(name)} />
<ListItemText primary={name} />
</MenuItem>
))}
</Select>
</FormControl>
</div>
);
}
The opening of the Select is triggered by the mouse-down event -- not the click event.
You can get your desired behavior by stopping propagation of the mouse-down event when it occurs on the delete icon of the Chip:
<Chip
key={value}
label={value}
clickable
deleteIcon={
<CancelIcon
onMouseDown={(event) => event.stopPropagation()}
/>
}
className={classes.chip}
onDelete={(e) => handleDelete(e, value)}
onClick={() => console.log("clicked chip")}
/>
For people who still find answer for this question, MUI has a component does exactly what you want: Autocomplete, you can find it here: https://mui.com/material-ui/react-autocomplete/
Here is the code example from MUI documents: Code Sandbox Demo
I have a dropdown and I'm using react-native picker component. Everything is working fine, the problem is that I need to close the dropdown when the user presses on any picker items
this.state.list.map((obj, index) => {
return (
<Picker.Item key={index} label={obj.label} value={obj.value} />
);
the picker gives us only onValueChange prop, but I need onPress functionality for any picker items individually to close the dropdown.
I have also tried this
this.state.list.map((obj, index) => {
return (
<TouchableWithoutFeedback onPress={this.itemPressHandler}>
<Picker.Item key={index} label={obj.label} value={obj.value} />
</TouchableWithoutFeedback>
);
but it doesn't render the dropdown.
Is there any way to get this functionality?
According to docs.
<Picker
selectedValue={this.state.valueSelected}
onValueChange={(itemValue, itemIndex) => {
this.handlePickerValueChange(itemValue, itemIndex)
}
mode={'dialog'} // optional
>
this.state.list.map((obj, index) => {
return (
<Picker.Item key={index} label={obj.label} value={obj.value} />
);
});
</Picker>
Set the default selected value in state
state={
valueSelected: "Choose a value"
}
Handle change when user selects a different option
handlePickerValueChange = (itemValue, itemIndex) => {
//do your stuff
}
How can I display the default value in the drop-down list using material-ui? I tried to add displayEmpty="true", but nothing changed.
I would like to have the first option A selected by default, so that a user can see it in UI. Currently, a user should click on the drop-down menu in order to select an item from the list. No item is selected by default (the selected item is blank by default).
const options = [
{label:"A",value:483.93},
{label:"B",value:8033.86},
{label:"C",value:1246.3}
]
<Grid item xs={true}>
<FormControl
className={this.props.styles.formControl}
margin="normal">
<InputLabel shrink htmlFor="distanceTarget-label-placeholder">
Target:
</InputLabel>
<Select
onChange={(event) => this.props.handleChange("distanceTarget", event)}
value={this.props.state.distanceTarget}
input={<Input name="distanceTarget" id="distanceTarget-label-placeholder" />}
displayEmpty="true"
name="distanceTarget"
>
{options && options.length && options.map((option, i) => {
return <MenuItem value={option.value} key={i}>{option.label}</MenuItem>
})}
</Select>
</FormControl>
</Grid>
UPDATE:
This is what I tried as suggested in comments, however I still have the same issue:
{options && options && options((option, i) => {
if (i===0) {
return <MenuItem value={option.value} key={i} selected={true}>{option.label}</MenuItem>
}
else {
return <MenuItem value={option.value} key={i}>{option.label}</MenuItem>
}
})}
Try this one. Add displayEmpty not displayEmpty="true".
<Select
onChange={(event) => this.props.handleChange("distanceTarget", event)}
value={this.props.state.distanceTarget}
input={<Input name="distanceTarget" id="distanceTarget-label-placeholder" />}
renderValue={value => ${value}`} // you should add your default value here
name="distanceTarget"
Render the selected value. You can only use it when the native prop is false (default). (material-ui docs)
In order to have a particular item selected by default, you should initialize the state that control's the Select's value to have that item's value. For instance, in my modified version of your code, I am initializing the Select's value to options[0].value.
import React from "react";
import ReactDOM from "react-dom";
import {
FormControl,
Input,
InputLabel,
Select,
MenuItem
} from "#material-ui/core";
const options = [
{ label: "A", value: 483.93 },
{ label: "B", value: 8033.86 },
{ label: "C", value: 1246.3 }
];
function App() {
const [distanceTarget, setDistanceTarget] = React.useState(options[0].value);
return (
<FormControl margin="normal">
<InputLabel shrink htmlFor="distanceTarget-label-placeholder">
Target:
</InputLabel>
<Select
onChange={event => setDistanceTarget(event.target.value)}
value={distanceTarget}
input={
<Input name="distanceTarget" id="distanceTarget-label-placeholder" />
}
name="distanceTarget"
>
{options &&
options.length &&
options.map((option, i) => {
return (
<MenuItem value={option.value} key={i}>
{option.label}
</MenuItem>
);
})}
</Select>
</FormControl>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
I am trying to set the selected prop with react mui menu item. I have a multiple select menu list, where I have a field allValues, that on clicking it, toggles the selection of all menu items. And that part works just fine. The code looks like this:
<Select
multiple
value={selectedValues.map(klasse => klasse.id)}
onChange={(event) => handleChange(event.target.value, onChange, idToValues)}
input={<Input id="select-multiple-chip"/>}
classes={{root: classes.select}}
renderValue={selectedIds => (
<div className={classes.chips}>
{selectedIds.map(classId => (
<Chip
key={classId}
label={idToValues[classId] && idToValues[classId].classCode}
className={classes.chip}
onDelete={(event) => onChange(selectedValues.filter(class => class.id !== classId))}/>
))}
</div>
)}
MenuProps={MenuProps}
>
{!!allValues.length &&
<MenuItem value="allValues" selected={allValues.length === selectedValues.length}>
All classes
</MenuItem>
}
{allValues.map(class => (
<MenuItem key={class.id} value={class.id}>
{class.classCode}
</MenuItem>
))}
</Select>
I can see in the dev tools that allValues and selectedValues are of the equal length, but the selected prop is still false. How is that possible, and how can I fix this?
Try adding () brackets like:
selected={(allValues.length === selectedValues.length)}