React Material-UI Autocomplete. How to get value of deleted option? - reactjs

I have a Autocomplete multiple select element. When I click on cross, to delete some option, I want to get this value. I tried to use ChipProps = {{onDelete: some function}} but it did not work :( I get undefined, and more over, delete function stops to work at all.
Here is my code
const top100Films = [
{ title: 'The Shawshank Redemption', year: 1994 },
{ title: 'The Godfather', year: 1972 },
{ title: 'The Godfather: Part II', year: 1974 },
{ title: 'The Dark Knight', year: 2008 },
{ title: '12 Angry Men', year: 1957 },
{ title: "Schindler's List", year: 1993 },
];
<Autocomplete
multiple
id="tags-standard1"
options={top100Films}
getOptionLabel={(option) => option.title}
//ChipProps = {{onDelete: (option) => {console.log(option.title)}}}
renderInput={(params) => (
<TextField
{...params}
size="small"
variant="outlined"
label="Films"
/>
)}
/>
So could anybody tell me how to get Id, or value, of deleted option?

As from this MR: https://github.com/mui-org/material-ui/pull/19959/files, if you need the whole removed object you can use the fourth argument. For example:
onChange={(event, list, reason, detail) => {
if (reason === 'remove-option') {
console.log(detail.option);
};
})

I can confirm the deletion stops working if you add onDelete handler in ChipProps. I believe that it's a bug from Material-UI side. In the meantime you probably want to use the following hack to get the value of the chip when deleted:
<Autocomplete
multiple
options={top100Films}
fullWidth
getOptionLabel={(option) => option.title}
onChange={(e, option, reason) => {
if (reason === "remove-option") {
console.log("delete", e.currentTarget.parentElement.innerText);
}
if (reason === "clear") {
console.log("clear all");
}
}}
{...}
/>
Live Demo

onChange={(e, value, situation, option) => {
if (situation === "removeOption") {
//write your code here
console.log("--->", e, value, situation, option);
}
setReceivers((state) => value);
}}
now it's removeOption not remove-option

Related

How customize material ui select

I'm trying to customize material-ui dropdown, to make it something like this,
here is the link https://codesandbox.io/s/busy-black-2fgdn?file=/src/App.js,
if I write 1 in the input (from) it selects the option that starts with 1 instead of writing in input, if none of the options starts with the number entered in the input then it writes in the input,
Use Autocomplete with freeSolo as a prop.
check the docs here => https://mui.com/components/autocomplete/#free-solo
const dataList = [
{ title: "10-100", value: "10-100" },
{ title: "100-200", value: "100-200" },
{ title: "200-300", value: "200-300" },
{ title: "300-400", value: "300-400" }
];
...
<Autocomplete
id="free-solo-demo"
freeSolo
options={dataList.map(option => option.title)}
renderInput={params => <TextField {...params} label="select or type" />}
/>
code sandbox => https://codesandbox.io/s/winter-cloud-y401t?file=/src/App.js

Disable options based on currently selected option with Material UI Autocomplete component

I am creating an Autocomplete element using Material UI, React Hook Form, and Yup that allows a user to choose multiple inputs for the days of the week.
If a user chooses the "Every day" option, I want to disable being able to choose Sunday, Monday, Tues... etc. How would I do that using getOptionDisabled?
Here is my current code...
const daysOfWeekSuggestions = [
{label: "Every day"},
{label: "Sunday"},
{label: "Monday"},
{label: "Tuesday"},
{label: "Wednesday"},
{label: "Thursday"},
{label: "Friday"},
{label: "Saturday"}
];
<Autocomplete
disableClearable
disablePortal
filterSelectedOptions
multiple
getOptionLabel={(option) => option.label}
id="days-autocomplete"
options={daysOfWeekSuggestions}
renderInput={(params) => <TextField
required
error={errors.daysOfWeek ? true : false}
id="daysOfWeek"
label="Days of the week"
name="daysOfWeek"
type="search"
{...params}
{...register("daysOfWeek")}
/>}
/>
What you need to do is use the getOptionDisabled prop and then check to see if the user has already selected Every Day. Im guessing you are saving it into state similar to how I am using it here so you can then just use the .some function to see if the Every day object is in the values array.
const daysOfWeekSuggestions = [
{ label: "Every day" },
{ label: "Sunday" },
{ label: "Monday" },
{ label: "Tuesday" },
{ label: "Wednesday" },
{ label: "Thursday" },
{ label: "Friday" },
{ label: "Saturday" }
];
export default function DaysOfTheWeekSelect() {
const [value, setValue] = React.useState([]);
const handleOnChange = (e, value) => {
setValue(value);
};
return (
<Autocomplete
disableClearable
disablePortal
multiple
getOptionLabel={(option) => option.label}
id="days-autocomplete"
onChange={handleOnChange}
options={daysOfWeekSuggestions}
getOptionDisabled={(option) => {
if (value.some((day) => day.label === "Every day")) {
return true;
}
if (value.some((day) => day.label === option.label)) {
return true;
}
return false;
}}
value={value}
renderInput={(params) => (
<TextField
required
error={errors.daysOfWeek ? true : false}
id="daysOfWeek"
label="Days of the week"
name="daysOfWeek"
type="search"
{...params}
{...register("daysOfWeek")}
/>
)}
/>
);
}
I also made it that if you have already selected a value then it would be disabled as well. Just seems a little bit better than just filtering out the selected values
I think you need more than just getOptionDisabled option.
I have done similar thing in my prev app, for that you need to add one more property called disabled to each option and onChange to Every day, manually disable remaining options.
You can check working demo here - https://codesandbox.io/s/disable-mui-autocomplete-options-on-condition-gurzb
Try using the isOptionEqualToValue instead
<Autocomplete
...
isOptionEqualToValue={(option, value) => option.id === value.id}
...
/>
supply the identifying property, in this case 'id'

material ui always return 0 onchange

when i try to change the value in autocomplete of material-ui, i always get its value 0, here i have uploaded my whole code, can anyone please check my code and help me to resolve this issue ?
any help will be really appreciated.
export default function CreatePIC() {
const classes = useStyles();
const Department_list = [
{ label: 'Department1', id: 1 },
{ label: 'Department2', id: 2 },
{ label: 'Department3', id: 3 },
{ label: 'Department4', id: 4},
{ label: 'Department5', id: 5 }
]
const [department, setDepartment] = React.useState('');
const handleChangeDepartment = (event) => {
console.log(event.target.value);
setDepartment(event.target.value);
};
return (
<Autocomplete
id="Department"
value={department}
helperText={error.department}
options={Department_list}
getOptionLabel={option => typeof option === 'string' ? option : option.label}
onChange = {handleChangeDepartment}
renderInput={(params) => <TextField {...params} label="Search Department" variant="outlined" placeholder="Add Department" />}
/>
)
}
Ciao, in Autocomplete component event.target.value will be always 0. If you want to get the selected department you could use value in handleChangeDepartment. So your code becomes:
const handleChangeDepartment = (event, values) => {
console.log(event.target.value); // print always 0
console.log(values); // print values selected like { label: 'Department1', id: 1 }
setDepartment(values.label); // set department with values.label
};
Here a codesandbox example.
Rather than using:
event.target.value
try using:
event.target.innerText
or, to find the option index, use:
event.target.dataset.optionIndex

How to change name and Icon of Action Column in Material-Table React

I'm using Material Table and I need change the Action column name but this column is automatic generated because I'm using editable function from material table.
<MaterialTable
title=""
localization={{
body: {
editRow: {
saveTooltip: "Salvar",
cancelTooltip: "Cancelar",
deleteText: "Tem certeza que deseja deletar este registro?"
},
addTooltip: "Adicionar",
deleteTooltip: "Deletar",
editTooltip: "Editar"
}
}}
columns={state.columns}
data={state.data}
editable={{
onRowAdd: newData => createInstructor(newData),
onRowUpdate: async (newData, oldData) =>
updateInstructor(newData, oldData),
onRowDelete: oldData => deleteInstructor(oldData)
}}
/>
How can I change these icons and column name ?
As you've rightfully assumed, the title of the that column, as well as all the text strings in the material table are customizable via localization property.
<MaterialTable
// other props
localization={{
pagination: {
labelDisplayedRows: '{from}-{to} of {count}'
},
toolbar: {
nRowsSelected: '{0} row(s) selected'
},
header: {
actions: 'Actions'
},
body: {
emptyDataSourceMessage: 'No records to display',
filterRow: {
filterTooltip: 'Filter'
}
}
}}
/>
Notice header.actions item. That's the one for you.

react-select change name of option fields from ({ value: '', label:''}) to ({ id: '', name:''})

Is there a way to change the fields of an option object?
From my BE API i get:
const items = [{ id: 1, name:'dropdown1'}, { id: 2, name:'dropdown2'}];
So now i have to remap the fields to value and label, it would have been nice if i could set those fields dynamically, maybe something like:
<Select
optionRemapping={{value: 'id', label: 'name'}}
options={items}
/>
Or maybe i have missed a pattern on how people do this?
Doing the below feels a bit wrong.
items.map((item) => {
return { value: item.id, label: item.name };
});
Use getOptionLabel and getOptionValue props.
<Select
getOptionLabel={option => option.name}
getOptionValue={option => option.id}
options={items}
/>
example : https://codesandbox.io/s/kmoyw8q667
You could achieve your mapping by doing the following and deconstructing your items :
<Select
options={items.map(({ id, name }) => ({ value: id, label: name}))}
/>

Resources