Multiple time slots for Week days using ReactJS - javascript

If anyone can help me to optimize the following code. I am trying to create a registration page where users can select their time availability for selected days. Users have option to select multiple rows for the same day.. The link for codesandbox is https://codesandbox.io/s/react-hook-helper-availability-0r6bd?file=/src/Second.js. Though i have achieved this but it can be further be optimized as i am using the same code for different days. I am reusing the same code. I have added for just Monday and Tuesday, in case i have to use Monday to Saturday, then i will have to repeat the same codes with changes in few fields.
const [monday, setMonday] = useState([{ FROM: "", TO: "" }]);
const [tuesday, setTuesday] = useState([{ FROM: "", TO: "" }]);
const [time, setTime] = useState([
{ Id: "00:30", value: "00:30" },
{ Id: "01:00", value: "01:00" },
{ Id: "01:30", value: "01:30" },
{ Id: "02:00", value: "02:00" },
......
let timeList =
time.length > 0 &&
time.map((item, i) => {
return (
<>
<option key={item.Id} value={item.id}>
{item.value}
</option>
</>
);
}, this);
On add, remove actions
const handleInputChangeForMonday = (e, index) => {
const { name, value } = e.target;
const list = [...monday];
list[index][name] = value;
setMonday(list);
};
// handle click event of the Remove button
const handleRemoveClickForMonday = (index) => {
const list = [...monday];
list.splice(index, 1);
setMonday(list);
};
// handle click event of the Add button
const handleAddClickForMonday = () => {
setMonday([...monday, { FROM: "", TO: "" }]);
};
// handle input change
const handleInputChangeForTuesday = (e, index) => {
const { name, value } = e.target;
const list = [...tuesday];
list[index][name] = value;
setTuesday(list);
};
// handle click event of the Remove button
const handleRemoveClickForTuesday = (index) => {
const list = [...tuesday];
list.splice(index, 1);
setTuesday(list);
};
// handle click event of the Add button
const handleAddClickForTuesday = () => {
setTuesday([...tuesday, { FROM: "", TO: "" }]);
};
Now this is the repeated code.
<form onSubmit={onSubmit}>
{monday.map((x, i) => {
return (
<React.Fragment>
<select
name="FROM"
value={x.FROM}
onChange={(e) => handleInputChangeForMonday(e, i)}
>
<option selected hidden>
From
</option>
{timeList}
</select>
<select
name="TO"
value={x.TO}
onChange={(e) => handleInputChangeForMonday(e, i)}
placeholder="select your Institute"
>
<option selected hidden>
TO
</option>
{timeList}
</select>
<div style={{ textAlign: "left", width: "84%" }}>
{monday.length !== 1 && (
<label
as="a"
onClick={() => handleRemoveClickForMonday(i)}
style={{ marginRight: "10px" }}
>
remove
</label>
)}
{monday.length - 1 === i && (
<button
type="button"
as="a"
onClick={handleAddClickForMonday}
style={{ marginRight: "10px" }}
>
add
</button>
)}
</div>
</React.Fragment>
);
})}
<br />
<br />
{tuesday.map((x, i) => {
return (
<React.Fragment>
<select
name="FROM"
value={x.FROM}
onChange={(e) => handleInputChangeForTuesday(e, i)}
>
<option selected hidden>
From
</option>
{timeList}
</select>
<select
name="TO"
value={x.TO}
onChange={(e) => handleInputChangeForTuesday(e, i)}
placeholder="select your Institute"
>
<option selected hidden>
TO
</option>
{timeList}
</select>
<div style={{ textAlign: "left", width: "84%" }}>
{tuesday.length !== 1 && (
<label
as="a"
onClick={() => handleRemoveClickForTuesday(i)}
style={{ marginRight: "10px" }}
>
remove
</label>
)}
{tuesday.length - 1 === i && (
<button
type="button"
as="a"
onClick={handleAddClickForTuesday}
style={{ marginRight: "10px" }}
>
add
</button>
)}

To reduce redundancy you can look at what code is repeated and think of it more abstractly.
For example, the following code abstractly copies the entries for a day, removes an element, and updates state with new array for that day
// handle click event of the Remove button
const handleRemoveClickForMonday = (index) => {
const list = [...monday];
list.splice(index, 1);
setMonday(list);
};
Now that you can abstractly operate on any day, think of a data structure that lends itself to looking up a specific day to operate on, like a map. In javascript it is common to use an object ({}) as a map of key-value pairs.
Convert state to object with day keys
const [days, setDays] = useState({
monday: [{ FROM: "", TO: "" }],
tuesday: [{ FROM: "", TO: "" }],
wednesday: [{ FROM: "", TO: "" }],
thursday: [{ FROM: "", TO: "" }],
friday: [{ FROM: "", TO: "" }],
saturday: [{ FROM: "", TO: "" }],
sunday: [{ FROM: "", TO: "" }],
});
Update mounting effect hook (probably room for improvement here as well since just initializing data really; I didn't dig in on what the AVAILABILITY_XXX's were)
useEffect(() => {
if (AVAILABILITY_MONDAY.length > 0)
setDays((days) => ({
...days,
monday: AVAILABILITY_MONDAY
}));
if (AVAILABILITY_TUESDAY.length > 0)
setDays((days) => ({
...days,
tuesday: AVAILABILITY_TUESDAY
}));
// etc for each day of the week
}, []);
Convert submit handler to access new state shape
const onSubmit = (data) => {
const e = {
target: {
name: "AVAILABILITY_MONDAY",
value: days.monday
}
};
const f = {
target: {
name: "AVAILABILITY_TUESDAY",
value: days.tuesday
}
};
// etc for each day
setForm(e);
setForm(f);
// etc
navigation.next();
};
Convert handlers to take a day key
// handle input change
const handleInputChangeForDay = (e, day, index) => {
const { name, value } = e.target;
const list = [...days[day]];
list[index][name] = value;
setDays((days) => ({
...days,
[day]: list
}));
};
// handle click event of the Remove button
const handleRemoveClickForDay = (day, index) => {
const list = [...days[day]];
list.splice(index, 1);
setDays((days) => ({
...days,
[day]: list
}));
};
// handle click event of the Add button
const handleAddClickForDay = (day) => () => {
setDays((days) => ({
...days,
[day]: [...days[day], { FROM: "", TO: "" }]
}));
};
Create an array of key-value pairs from state and map each day
{Object.entries(days).map(([dayKey, day]) => {
return day.map((x, i) => {
return (
<React.Fragment>
Day: {dayKey}
<select
name="FROM"
value={x.FROM}
onChange={(e) => handleInputChangeForDay(e, dayKey, i)}
>
<option selected hidden>
From
</option>
{timeList}
</select>
<select
name="TO"
value={x.TO}
onChange={(e) => handleInputChangeForDay(e, dayKey, i)}
placeholder="select your Institute"
>
<option selected hidden>
TO
</option>
{timeList}
</select>
<div style={{ textAlign: "left", width: "84%" }}>
{day.length !== 1 && (
<label
as="a"
onClick={() => handleRemoveClickForDay(dayKey, i)}
style={{ marginRight: "10px" }}
>
remove
</label>
)}
{day.length - 1 === i && (
<button
type="button"
as="a"
onClick={handleAddClickForDay(dayKey)}
style={{ marginRight: "10px" }}
>
add
</button>
)}
</div>
</React.Fragment>
);
});
})}

Related

How to change select options based on other selection ( Javascript)

I have an 4 Select component with the same list options. If I choose an option, that one will be remove from the list of other Select components so that no 2 Select have identical result. Here is the code:
listStaff = [
{id: 1, name: 'John Doe'},
{id: 2, name: 'Walter White},
{id: 3, name: 'Jesse Pinkman}
{id: 4, name: 'Saul Goodman}
{id: 5, name: 'Gus Fring}
{id: 6, name: 'Skyler White}
]
const [staff, setStaff] = useState([])
<Select
allowClear
placeholder="Choose staff #1"
onChange={(e) => onChangeStaff(e, 0)}
value={staff[0]}
>
{listStaff?.map((item) => {
return (
<Select.Option key={item?.id} value={item?.id}>
{item?.name}
</Select.Option>
);
})}
</Select>
<Select
allowClear
placeholder="Choose staff #2"
onChange={(e) => onChangeStaff(e, 1)}
value={staff[1]}
>
{listStaff?.map((item) => {
return (
<Select.Option key={item?.id} value={item?.id}>
{item?.name}
</Select.Option>
);
})}
</Select>
<Select
allowClear
placeholder="Choose staff #3"
onChange={(e) => onChangeStaff(e, 2)}
value={staff[2]}
>
{listStaff?.map((item) => {
return (
<Select.Option key={item?.id} value={item?.id}>
{item?.name}
</Select.Option>
);
})}
</Select>
<Select
allowClear
placeholder="Choose staff #4"
onChange={(e) => onChangeStaff(e, 3)}
value={staff[3]}
>
{listStaff?.map((item) => {
return (
<Select.Option key={item?.id} value={item?.id}>
{item?.name}
</Select.Option>
);
})}
</Select>
Here is what I try:
const onChangeStaff = (id, index) => {
let arrTemp = [...listStaff]
const i = arrTemp.findIndex(r => r.id == id)
if(i > -1 ){
arrTemp.splice(i, 1)
} else {
return arrTemp
}
setListStaff(arrTemp)
};
I can remove the chosen option from the list but when a clear the Select or choose another option, the previous one do not revert but lost permanently. So how can I remove one option when choosing but revert that one back when deselect? Thank you.
Demo:
https://codesandbox.io/s/holy-dew-h6qxc4?file=/src/App.js
i messing around with your code a bit. try this
import "./styles.css";
import { Select } from "antd";
import { useState } from "react";
export default function App() {
const [listStaff, setListStaff] = useState([
{ id: 1, name: "Walter White" },
{ id: 2, name: "Jesse Pinkman" },
{ id: 3, name: "Gus Fring" },
{ id: 4, name: "Saul Goodman" },
{ id: 5, name: "John Doe" },
{ id: 6, name: "Skyler White" }
]);
const [selectedStaff, setSelectedStaff] = useState(new Array(4).fill(null));
const handleChangeStaff = (id, i) => {
setSelectedStaff(p => {
const newSelectedStaff = [...p];
newSelectedStaff[i] = id === undefined ? null : listStaff.find(ls => ls.id === id);
return newSelectedStaff;
});
};
return (
<div className="App">
{new Array(4).fill("").map((_, i) => (
<Select
allowClear
placeholder={`Choose staff #${i+1}`}
onChange={(id) => handleChangeStaff(id, i)}
key={i}
>
{listStaff.filter(ls => selectedStaff.find(ss => ss !== null && ss.id === ls.id) === undefined).map(ls => (
<Select.Option key={ls.id} value={ls.id}>
{ls.name}
</Select.Option>
))}
</Select>
))}
</div>
);
}

can't use recursive map in react component

i stumbled into an issue i cant solve, i have an object 'customerDraft' which has nested object in it. i want to render every field plus the fields which are inside of 'customerDraft.metadata'.
my component looks like this:
const CustomerDetailEditModal = (props) => {
const {
open,
setOpen,
customerDraft,
customerProfileDraft,
setDraftCustomer,
setDraftProfile,
onUpdate
} = props;
const classes = useStyles();
const dispatch = useDispatch();
const [isPasswordHidden, setIsPasswordHidden] = useState(true);
// const [attributes, setAttributes] = useState({});
const projectId = useSelector(({ project }) => project.currentProject._id);
const generatedPassword = useSelector(({ customer }) => customer.password);
const isCurrentProjectCapstone = projectId === '4387564328756435';
const onModalCancel = () => {
setOpen(false);
if (isCurrentProjectCapstone) {
dispatch(removeItemFromCustomerDraftAction('password'));
}
};
const generatePassword = () => {
dispatch(getGeneratedPassword());
};
useEffect(() => {
if (!generatedPassword) return;
setDraftCustomer({
...customerDraft,
password: generatedPassword
});
// eslint-disable-next-line
}, [generatedPassword]);
console.log(customerDraft);
return (
<div>
<Modal
bodyStyle={{
fontSize: '12px',
height: 500,
margin: '0 auto'
}}
centered
footer={
<div
style={{
display: 'flex',
justifyContent: 'flex-end'
}}>
<CButton
htmlType="submit"
onClick={(e) => {
setOpen(false);
e.preventDefault();
}}
size="large"
type="secondary">
Cancel
</CButton>
<CButton
htmlType="submit"
onClick={onUpdate}
size="large"
type="primary"
// disabled={!isSaveEnabled}
>
Save
</CButton>
</div>
}
onCancel={onModalCancel}
title={
<span
style={{
fontSize: '24px',
fontWeight: 700,
lineHeight: '24px'
}}>
Edit User
</span>
}
visible={open}
width={customerProfileDraft ? 770 : 385}>
<form className={classes.form} id="customer-edit-form">
<div className={classes.wrapperDiv}>
{Object.entries(customerDraft).map((item, i) => {
if (customerDraft.fullName) {
if (restrictedData.includes(item[0] || item[0].toLowerCase().includes('id'))) {
return false;
}
}
if (restrictedData.includes(item[0]) || item[0].toLowerCase().includes('id')) {
return false;
}
return (
<CStandardInput
key={i}
allowClear
defaultValue={item[1]}
disableUnderline
formclasses={{ root: classes.root }}
htmlFor={`standard-customer-edit-${item[0]}`}
id={`standard-customer-edit-${item[0]}`}
label={item[0]}
onChange={(event) => {
setDraftCustomer({
...customerDraft,
fullName: event.target.value
});
setDraftProfile({
...customerProfileDraft,
fullName: event.target.value
});
}}
size="large"
/>
);
})}
{isCurrentProjectCapstone && (
<div className={classes.passwordWrapper}>
<CStandardInput
adornment={
<>
<button
className={classes.buttonSvg}
onClick={() => {
navigator.clipboard.writeText(customerDraft.password || '');
}}
style={{
marginRight: '5px'
}}
type="button">
<img alt="copy password" src={copyIcon} />
</button>
<button
className={classes.buttonSvg}
onClick={() => setIsPasswordHidden(!isPasswordHidden)}
type="button">
<img
alt="toggle password visibility"
src={isPasswordHidden ? crossedEyeIcon : eyeIcon}
/>
</button>
</>
}
disableUnderline
formclasses={{ root: classes.root }}
htmlFor="standard-input-user-password"
id="standard-input-user-password"
label="Password"
onChange={(e) => setDraftCustomer({ ...customerDraft, password: e.target.value })}
size="large"
type={isPasswordHidden ? 'password' : 'text'}
value={customerDraft.password || ''}
width="true"
/>
<CButton
onClick={generatePassword}
type="primary"
xstyle={{
borderRadius: '12px',
margin: '16px 0px 0px 16px'
}}>
Generate
</CButton>
</div>
)}
</div>
</form>
</Modal>
</div>
);
};
export default CustomerDetailEditModal;
notice how metdata field is rendered? i want to use recursion to output every field which metadata contains,
i know recursion but what i cant seem to figure out is where should this component call itself to do it.
any help with explanation so that i can understand the answer would be much appreciated!
this is the object im iterating on:
const customerData = {
createdAt: "2022-10-28T08:42:08.015Z",
email: "company#gmail.com",
firstName: "$$$$$$$",
fullName: "$$$$$$",
idNumber: "2813921321",
isEmailVerified: true,
isPhoneVerified: true,
lastName: "$$$$$",
metadata: {
birthDate: "2000-08-19 00:00:00.000",
gender: "Male",,
region: "",
status: "Adult",
statusExtra: "Student",
},
phone: "######",
project: "hlkjhkljhkjhk",
updatedAt: "2022-11-01T10:26:32.677Z",
username: null,
_id: "hlkjhlkjhlkjhlkjhlkjh",
};
see metadata? currently im outputting only the fields of the main(parent) object, but i also want to output the data which is contained in the 'metadata' key using recursion.
A solution to this could be to check if the key item[0] is "metadata". Then you could do the same as you did with the customerDraft object. Get the entries an map over them.
Note that I destructured the array you get from the .entries to make it more explicit what the variables are.
if (item[0] === "metadata") {
const inputs = Object.entries(item[1]).map(([metaKey, metaValue]) => (
<CStandardInput
key={metaKey}
allowClear
defaultValue={metaValue}
disableUnderline
formclasses={{ root: classes.root }}
htmlFor={`standard-customer-edit-${metaKey}`}
id={`standard-customer-edit-${metaKey}`}
label={metaKey}
onChange={(event) => {
setDraftCustomer({
...customerDraft,
fullName: event.target.value,
});
setDraftProfile({
...customerProfileDraft,
fullName: event.target.value,
});
}}
size="large"
/>
));
return <>{inputs}</>;
}
return (
<CStandardInput
...
EDIT:
To support the nested data with recursion, I've created a function with returns an input for every key, value pair in the data.
You can add your extra if statements as desired
const renderInputs = (data) => {
const inputs = Object.entries(data).map(([key, value]) => {
if (
typeof value === "object" &&
!Array.isArray(value) &&
value !== null
) {
return renderInputs(value);
}
return (
<CStandardInput
key={key}
allowClear
defaultValue={value}
disableUnderline
formclasses={{ root: classes.root }}
htmlFor={`standard-customer-edit-${key}`}
id={`standard-customer-edit-${key}`}
label={key}
onChange={(event) => {
setDraftCustomer({
...customerDraft,
fullName: event.target.value,
});
setDraftProfile({
...customerProfileDraft,
fullName: event.target.value,
});
}}
size="large"
/>
);
});
return inputs;
};
return <>{renderInputs(customerData)}</>;
Hope this helps you with your project!

React-select multiple selects on one page

I am a bit confused, here is an example with a couple of select inputs that have the same state, please check here: https://stackblitz.com/edit/get-selected-by-value-multi-select-react-agamk4?file=src/App.js so please:
How can I make it so when I select an option the value does not apply to the rest of the select inputs?
How would you put the values in the store for each of the selects?
Do I need multiple stores?
For more clarity, here is a screenshot: https://www.awesomescreenshot.com/image/19798040?key=bb839c650c93b436066e03d33d5515b0 I hope this makes sense? What would be the best approach? Thank you.
I have shared the code in case of only a single state. You can use this method if you want only a single state but having multiple states for different select inputs also won't be bad as you have only 3 inputs. Having single state method would be useful if number of select inputs would have more.
import React, { useState } from 'react';
import Select from 'react-select';
function App() {
const data = [
{
value: 1,
label: 'cerulean',
},
{
value: 2,
label: 'fuchsia rose',
},
{
value: 3,
label: 'true red',
},
{
value: 4,
label: 'aqua sky',
},
{
value: 5,
label: 'tigerlily',
},
{
value: 6,
label: 'blue turquoise',
},
];
// set value for default selection
const [selectedValue, setSelectedValue] = useState([
{ value: [] },
{ value: [] },
{ value: [] },
]);
// handle onChange event of the dropdown
const handleChange = (e, no) => {
setSelectedValue(
selectedValue.map((item) => {
return selectedValue.indexOf(item) === no
? { value: Array.isArray(e) ? e.map((x) => x.value) : [] }
: item;
})
);
};
return (
<div className="App">
<Select
className="dropdown"
placeholder="Select Option"
value={data.filter((obj) => selectedValue[0].value.includes(obj.value))} // set selected values
options={data} // set list of the data
onChange={(event) => handleChange(event, 0)} // assign onChange function
isMulti
isClearable
/>
<br />
<Select
className="dropdown"
placeholder="Select Option"
value={data.filter((obj) => selectedValue[1].value.includes(obj.value))} // set selected values
options={data} // set list of the data
onChange={(event) => handleChange(event, 1)} // assign onChange function
isMulti
isClearable
/>
<br />
<Select
className="dropdown"
placeholder="Select Option"
value={data.filter((obj) => selectedValue[2].value.includes(obj.value))} // set selected values
options={data} // set list of the data
onChange={(event) => handleChange(event, 2)} // assign onChange function
isMulti
isClearable
/>
{selectedValue && (
<div style={{ marginTop: 20, lineHeight: '25px' }}>
<div>
<b>Selected Value: </b> {JSON.stringify(selectedValue, null, 2)}
</div>
</div>
)}
</div>
);
}
export default App;
{selectedValue && (
<div style={{ marginTop: 20, lineHeight: '25px' }}>
<div>
<b>Selected Values: </b>
<span>{
selectedValue.map(item => item.value.length !== 0 ?
<li>{data.filter(data => data.value === item.value[0])[0].label}</li> :
<li>No value selected</li>
)
}</span>
</div>
</div>
)}

How to use selected attribute of select tag in a loop in React

It is easy when we have individual options like this:
<select name="phone_type" id="phone_type">
<option value="mobile" selected>Mobile</option>
<option value="home">Home</option>
<option value="office">Office</option>
</select>
But in my case I'm doing this using a loop:
phoneTypes = ['Mobile', 'Home', 'Office'];
...
<select onChange={(e) => this.handleChangePhonetype(e, index)}>
{this.phoneTypes.map((phoneType, index) => {
return (
<option key={index} value={phoneType} name="type">
{phoneType}
</option>);
})}
</select>
I searched the internet but couldn't get a proper answer for React. I want 'Mobile' to be selected already when the page loads. I don't know how to do this in React. Please pitch in.
Here is the stackblitz.
You should simply use the type of each phone object as the value to the select element.
Here's the updated stackblitz.
const PhoneTypes = ['Mobile', 'Home', 'Office'];
class Questionnaire extends Component {
state = {
phones: [{ type: 'Mobile', number: '' }],
};
addContact() {
this.setState((prevState) => ({
phones: [...prevState.phones, { type: 'Mobile', number: '' }],
}));
}
handleChange({ target: { name, value } }, phoneIndex) {
this.setState((prevState) => ({
phones: prevState.phones.map((phone, index) =>
phoneIndex === index ? { ...phone, [name]: value } : phone
),
}));
}
handleRemove(phoneIndex) {
this.setState((prevState) => ({
phones: prevState.phones.filter((_, index) => phoneIndex !== index),
}));
}
handleSubmit(e) {
console.log(this.state, '$$$');
}
render() {
return (
<div>
<h1>The Form</h1>
<label>Contact</label>
{this.state.phones.map((phone, index) => {
return (
<div key={index}>
<input
onChange={(e) => this.handleChange(e, index)}
value={phone.number}
name="number"
/>
<select
name="type"
value={phone.type}
onChange={(e) => this.handleChange(e, index)}
>
{PhoneTypes.map((phoneType, index) => {
return (
<option key={index} value={phoneType}>
{phoneType}
</option>
);
})}
</select>
<button onClick={(e) => this.handleRemove(index)}>Remove </button>
</div>
);
})}
<hr />
<button onClick={(e) => this.addContact(e)}>Add contact</button>
<hr />
<button onClick={(e) => this.handleSubmit(e)}>Submit</button>
</div>
);
}
}
I also fixed some other issues like mutating the state, incorrect arg to remove function etc.

If any option from a Group is selected, then all options in other group should get disabled using Ant design (OptGroup, Option) - React.js

How i can implement multiple select behavior If i start selected from one section, the another section will get disabled from selection. I tried many methods for do it but, i faced problem in logic how can implement it.
Code here. Stackblitz.com
Image - How should it look
export default function App() {
const [datas, setDatas] = React.useState(initialState);
const [selectedItems, setSelectedItems] = React.useState([]);
const onChange = option => {
setSelectedItems(option);
// code here
};
function tagRender(props) {
const { value, closable, onClose } = props;
return (
<Tag
color="blue"
closable={closable}
onClose={onClose}
style={{ marginRight: 3 }}
>
{value}
</Tag>
);
}
return (
<Select
mode="multiple"
value={selectedItems}
tagRender={tagRender}
style={{ width: "100%" }}
onChange={onChange}
menuItemSelectedIcon={null}
>
{datas.map(data => (
<OptGroup label={data.groupName} key={data.groupName}>
{data.options.map(option => (
<Option value={option.value} key={option.value}>
<Checkbox
style={{ pointerEvents: "none" }}
type="checkbox"
checked={selectedItems.indexOf(option.value) !== -1}
>
{option.value}
</Checkbox>
</Option>
))}
</OptGroup>
))}
</Select>
);
}
Try append disabled option to data upon selected items changed.
This is full code
export default function App() {
const [datas, setDatas] = React.useState(initialState);
const [selectedItems, setSelectedItems] = React.useState([]);
const onChange = option => {
setSelectedItems(option);
// code here
const newData = datas.map((data) => {
if (!data.options.map(each => each.value).includes(option[0])) {
return {
groupName: data.groupName,
options: data.options.map(each => {
return { value: each.value, disabled: true }
})
};
}
return data;
})
if (option.length > 0) {
setDatas(newData);
} else {
setDatas(initialState);
}
// code here
};
function tagRender(props) {
const { value, closable, onClose } = props;
return (
<Tag
color="blue"
closable={closable}
onClose={onClose}
style={{ marginRight: 3 }}
>
{value}
</Tag>
);
}
return (
<Select
mode="multiple"
value={selectedItems}
tagRender={tagRender}
style={{ width: "100%" }}
onChange={onChange}
menuItemSelectedIcon={null}
>
{datas.map(data => (
// added disabled for both option and checkbox
<OptGroup label={data.groupName} key={data.groupName}>
{data.options.map(option => (
<Option value={option.value} key={option.value} disabled={option?.disabled ?? false}>
<Checkbox
style={{ pointerEvents: "none" }}
type="checkbox"
checked={selectedItems.indexOf(option.value) !== -1}
disabled={option?.disabled ?? false}
>
{option.value}
</Checkbox>
</Option>
))}
</OptGroup>
))}
</Select>
);
}

Categories

Resources