I want to add a small check/tick icon beside the value eg: Operations ✓ if user selects operations in the TopicList dropdownlist. The TopicList is a class component to get the data from the database which consist of:
Operations, Array, Repetition, Function, Selection. If user selects 2 different values then eg:
Operations ✓
Array ✓
Repetition
Function
Selection.
How can I modify this code to solve this issue?
Here is an image of how I would like it to be if user selects Array.

import axios from "axios";
import React, { useState } from "react";
import TopicList from "../Components/topicList";
import CheckIcon from '@mui/icons-material/Check';
function CreateEvent(success, message) {
const navigate = useNavigate();
const [selectedValues, setSelectedValues] = useState([]); // array to store selected values
const getDataFromTopicList = (val) => {
if (val !== "" && !selectedValues.includes(val)) {
setSelectedValues([...selectedValues, val]);
}
};
const handleSubmit = (event) => {
event.preventDefault();
console.log(selectedValues); // selectedValues array contains all selected values from all TopicList components
axios({
method: "POST",
url: BASE_URL "events/submitEvent",
data: {
topicId: selectedValues,
},
headers: { "Content-Type": "application/json" },
})
.then((response) => {
if (response.status === 200) {
toast.success("Successfully Created", {
position: toast.POSITION.TOP_CENTER,
});
} else {
toast.error(response.data.message, {
position: toast.POSITION.TOP_CENTER,
});
}
})
.catch((err) => {
if (err.response) {
toast.error(err.response.data.message, {
position: toast.POSITION.TOP_CENTER,
});
} else {
toast.error("Failed to Create", {
position: toast.POSITION.TOP_CENTER,
});
}
});
};
return (
<div className="">
<div>
<form
onSubmit={handleSubmit}
>
<h1>
Create an Event
</h1>
<div>
<div>
<TopicList
selectedValues={selectedValues}
getDataFromTopicList={getDataFromTopicList}
/>
</div>
</div>
</form>
</div>
</div>
);
}
export default CreateEvent;
import axios from "axios";
import React from "react";
import CheckIcon from "@mui/icons-material/Check";
const BASE_URL = process.env.REACT_APP_BASE_URL;
export default class TopicList extends React.Component {
state = {
topics: [],
};
componentDidMount() {
axios.get(BASE_URL `events/topic`).then((res) => {
const topics = res.data;
this.setState({ topics });
});
}
render() {
return (
<select required onChange={(val) => this.getCat(val.target.value)}>
{this.state.topics.map((topic) => (
<option value={topic.topicId}>
{topic.topic}
{this.props.selectedValues.includes(topic.topicId) && <CheckIcon style={{ color: "green" }} />}
</option>
))}
</select>
);
}
}
CodePudding user response:
Here you can see an example of a select with checkbox inside it. to see the code just click the link.
CodePudding user response:
It seems that the posted code has MUI but is not using its components in TopicList.
Here is a basic example that makes use of the MUI Select, and with implementation of the needed CheckIcon on multiple selected values.
Minimized demo of below example: stackblitz
The example omitted the data fetching part for simplicity, but it keeps the same topics state and get props for selectedValues in TopicList.
The update function for selectedValues also changed for MUI component but the state value itself remained to be an array of selected topicId, so hopefully it could be wired up for the data fetching without large refectoring of existing code.
Imports for MUI components in TopicList:
import OutlinedInput from '@mui/material/OutlinedInput';
import InputLabel from '@mui/material/InputLabel';
import MenuItem from '@mui/material/MenuItem';
import FormControl from '@mui/material/FormControl';
import ListItemText from '@mui/material/ListItemText';
import ListItemIcon from '@mui/material/ListItemIcon';
import Select from '@mui/material/Select';
import CheckIcon from '@mui/icons-material/Check';
The output of modified TopicList:
<FormControl sx={{ m: 3, width: 300 }}>
<InputLabel id="topic-form-input-label">Topic</InputLabel>
<Select
labelId="topic-form-label"
id="multiple-topic-select"
multiple
value={this.props.selectedValues}
onChange={this.props.onChange}
input={<OutlinedInput label="Topic" />}
renderValue={(selected) =>
selected
.map((topicId) => {
const selectedTopic = this.state.topics.find(
(item) => item.topicId === topicId
);
return selectedTopic ? selectedTopic.topic : topicId;
})
.join(", ")
}
>
{this.state.topics.map((topic) => {
const selected = this.props.selectedValues.includes(topic.topicId);
return (
<MenuItem key={topic.topicId} value={topic.topicId}>
{selected && (
<ListItemIcon>
<CheckIcon style={{ color: "green" }} />
</ListItemIcon>
)}
<ListItemText inset={!selected} primary={topic.topic} />
</MenuItem>
);
})}
</Select>
</FormControl>
Selected values passed from the parent component:
const [selectedValues, setSelectedValues] = useState([]);
const handleChange = (event) => {
const {
target: { value },
} = event;
setSelectedValues(typeof value === "string" ? value.split(",") : value);
};
<TopicList
selectedValues={selectedValues}
onChange={handleChange}
/>
