2

I am trying to populate an array based on selected/checked values from checkbox. Let's say we have 3 arrays of strings

const cars = ["Ford", "Chevy", "Honda", "Toyota"];
const phones = ["iPhone", "Samsung", "Nokia", "Sony"];
const laptops = ["Mac", "Dell", "HP", "Acer"];

and another array which includes the checkbox values.

const names = ["cars", "phones", "laptops"];

My goal is to push to an array(let's say selectedProductArray) the array which has the same name as the checked value. Here is what I did so far, which adds only one selected/checked array.

const selectedProductArray = [];
  const selectedProductInfo = nameArr.includes("phones")
    ? selectedProductArray.concat(phones)
    : nameArr.includes("laptops")
    ? selectedProductArray.concat(laptops)
    : selectedProductArray.concat(cars);


I am trying to push to the array multiple arrays based on checkbox selection.
For example, if there are checked cars and phones values in checkbox list, the desired array would look like so

["Ford", "Chevy", "Honda", "Toyota", "iPhone", "Samsung", "Nokia", "Sony];

The whole code and demo sandbox link

import * as React from "react";
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 Select, { SelectChangeEvent } from "@mui/material/Select";
import Checkbox from "@mui/material/Checkbox";

const ITEM_HEIGHT = 48;
const ITEM_PADDING_TOP = 8;
const MenuProps = {
  PaperProps: {
    style: {
      maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP,
      width: 250
    }
  }
};

const cars = ["Ford", "Chevy", "Honda", "Toyota"];
const phones = ["iPhone", "Samsung", "Nokia", "Sony"];
const laptops = ["Mac", "Dell", "HP", "Acer"];

const names = ["cars", "phones", "laptops"];

export default function MultipleSelectCheckmarks() {
  const [nameArr, setNameArr] = React.useState<string[]>([]);

  const handleChange = (event: SelectChangeEvent<typeof nameArr>) => {
    const {
      target: { value }
    } = event;
    setNameArr(typeof value === "string" ? value.split(",") : value);
  };

  const selectedProductArray = [];
  const selectedProductInfo = nameArr.includes("phones")
    ? selectedProductArray.concat(phones)
    : nameArr.includes("laptops")
    ? selectedProductArray.concat(laptops)
    : selectedProductArray.concat(cars);
  console.log("selectedProductInfo", selectedProductInfo);
  console.log("selectedProductArray", selectedProductArray);

  return (
    <div>
      <FormControl sx={{ m: 1, width: 300 }}>
        <InputLabel id="demo-multiple-checkbox-label">Tag</InputLabel>
        <Select
          labelId="demo-multiple-checkbox-label"
          id="demo-multiple-checkbox"
          multiple
          value={nameArr}
          onChange={handleChange}
          input={<OutlinedInput label="Tag" />}
          renderValue={(selected) => selected.join(", ")}
          MenuProps={MenuProps}
        >
          {names.map((name) => (
            <MenuItem key={name} value={name}>
              <Checkbox checked={nameArr.indexOf(name) > -1} />
              <ListItemText primary={name} />
            </MenuItem>
          ))}
        </Select>
      </FormControl>
    </div>
  );
}

Any help will be appreciated

4
  • Highly not-recommended and advised-against way: nameArr.flatMap(x => eval(x)). A better, sane/wise approach would be to reconsider the three arrays cars, phones, laptops & may be put those as key-value pairs in a common object (like: const obj = { cars: ["Audi", "Porsche", ...], phones: ["ROG", "Pixel", ....], ...};). Then, obj.cars will get the cars array. And, nameArr.flatMap(x => obj[x]); Commented Apr 5, 2022 at 9:54
  • Hey @jsN00b, thanks for the recommendation. I'll try it. Commented Apr 5, 2022 at 9:59
  • Please try the approach using the obj object. Please do NOT try the eval one - it is a big no-no. :-) Commented Apr 5, 2022 at 10:00
  • @jsN00b thanks again for the answer. I tried the way you recommended. And here is what I got to. Could you, tell me, please, what I am doing wrong codesandbox.io/s/… Commented Apr 5, 2022 at 10:31

1 Answer 1

1

This answer aims to assist the OP to the below-stated objective,

For example, if there are checked cars and phones values in checkbox list, the desired array would look like so

["Ford", "Chevy", "Honda", "Toyota", "iPhone", "Samsung", "Nokia", "Sony];

To do so, please make the below changes:

First, declare an object like this:

  const nameArrayOfObj = {
      cars: ["Ford", "Chevy", "Honda", "Toyota"],
      phones: ["iPhone", "Samsung", "Nokia", "Sony"],
      laptops: ["Mac", "Dell", "HP", "Acer"]
  };

Next, add the below line just under the outer/top-most <div>:

{JSON.stringify(nameArr.flatMap(name => nameArrayOfObj[name]))} <br/><br/><br/>

Now, when user selects the checkboxes cars, phones, laptops the corresponding items from those arrays will be rendered just above the Select dropdown.

Image from codesandbox demo

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

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.