0

I have a list that renders some products that are divided into some categories.

It is possible to select these categories through a checkbox. Would you like to know how to create an array with the list of selected values in the checkbox?

Here is my code I put into codesandbox:

I'm getting the value of the last selected filter, I'm not being able to create an array with all the selected values:

enter image description here

import Divider from "@material-ui/core/Divider";
import List from "@material-ui/core/List";
import ListItem from "@material-ui/core/ListItem";
import ListItemText from "@material-ui/core/ListItemText";
import Checkbox from "@material-ui/core/Checkbox";
import React, { useState } from "react";
import data from "../data";

import { useStyles } from "./styles";

const DrawerComponent = () => {
  const classes = useStyles();
  const [activeFilter, setActiveFilter] = useState([]);

  const handleChange = (text) => (event) => {
    setActiveFilter((prev) => ({
      ...prev,
      value: event.target.checked,
      text
    }));
  };

  console.log("activeFilter: ", activeFilter);

  const allCategories = data
    .reduce((p, c) => [...p, ...c.categories], [])
    .filter((elem, index, self) => index === self.indexOf(elem));

  return (
    <div className={classes.root}>
      <div className={classes.toolbar} />
      <Divider />
      <List className={classes.list}>
        {allCategories.sort().map((text, index) => (
          <ListItem className={classes.itemList} button key={text}>
            <Checkbox onChange={handleChange(text)} />
            <ListItemText primary={text} />
          </ListItem>
        ))}
      </List>
    </div>
  );
};

export default DrawerComponent;

Thank you in advance.

6
  • Your question is very unclear. Could you please elaborate a little better and maybe write what do you kind of array do you expect? Like maybe with an example. Commented Oct 12, 2020 at 11:34
  • 1
    Hey Karan, I updated my question, I'm getting the value of the last selected filter, I'm not being able to create an array with all the selected values Commented Oct 12, 2020 at 11:42
  • Its because you are using spread operator(...) with prev value. So the new text overrides the previous text. Commented Oct 12, 2020 at 11:44
  • Do you want an array of objects? Like [{value: foo, text: foo}, {value: bar, text: bar}] Commented Oct 12, 2020 at 11:45
  • Yeap Karan, I would like a array of objects. Because in another feature, I'll compare these selected categories with the categories in a Component that will render all my products according the selection of the checkboxes. Commented Oct 12, 2020 at 11:48

2 Answers 2

2

Et voilà. I've added a callback in your onChange event so as to avoid writing it in the handleChange function. Also, I've made sure the array is properly filtered if you toggle the checkbox status (with your version, a country would be added in double if you clicked twice on it).

 const handleChange = (text) => {
if(activeFilter.some(country=> country.text === text)){
  const updatedList = activeFilter.filter(country=> country.text!==text)
  return setActiveFilter(updatedList)
}
   return setActiveFilter((prev) => ([...prev, {text}]))
  }

//  <Checkbox onChange={()=> handleChange(text)} />

Sign up to request clarification or add additional context in comments.

4 Comments

Hey Done, This worked, but if I select the category Floral for example, and then deselect the categories Floral, my array remains with that object inside it. Do you know how to remove the item when the user deselects the category?
Avoid return statements in event handlers.
@vbernal, no it works, I've just tested it on your updated sandbox. Rohitha: it's easier to write two return rather than an ugly else in my opinion.
Hey Done, I'm sorry to abuse your help and goodwill. Could it be that you could help me in this matter too? stackoverflow.com/questions/64316460/… - Thank you one more time.
0

You can also add or filter array based on checkbox events:

const handleChange = (event, text) => {
  if (event.target.checked) {
    setActiveFilter((prev) => prev.concat({text}));
  } else {
    const filteredData = activeFilter.filter(
      (filterValue) => filterValue.text !== text
    );
    setActiveFilter(filteredData);
  }
};

...

<Checkbox onChange={(event) => handleChange(event, text)} />

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.