Home > Mobile >  How to make collapsible work only for the row clicked
How to make collapsible work only for the row clicked

Time:06-22

I want to make the row icon I click collapsible and display data. Presently if any of the row in table is clicked, it displays the collapsible content for all the rows.

              {data.map((dataRow) => (
                <TableRow
                  key={dataRow.id}
                  title="tableRow"
                  className={classes.tableRow}
                >
                  <TableCell className={classes.tableCell}>
                    <IconButton size="small" onClick={() => setOpen(!open)}>
                      {open ? <ArrowDropDownIcon /> : <ArrowDropUpIcon />}
                    </IconButton>
                    {dataRow.id}
                    <Collapse in={open} timeout="auto" unmountOnExit>
                      <Box margin={1}>
                        <Typography variant="h6" gutterBottom component="div">
                          History
                        </Typography>
                      </Box>
                    </Collapse>
                  </TableCell>
                  <TableCell className={classes.tableCell}>
                    {dataRow.name}
                  </TableCell>
                  <TableCell align="left" className={classes.tableCell}>
                    {dataRow.lastName}
                  </TableCell>
                </TableRow>
              ))}
            </TableBody>

CodePudding user response:

You have one state variable "open" that is used in every row to determine if it is collapsed or not. So, all the rows are collapsed or all of them are open.

To open them one by one you need a separate state variable for each of the rows. You can create something like this:

const [openRows, setOpenRows] = useState({});

the keys in this object will be dataRow.id, and the values - boolean

So, when you need to open a specific row you call setOpenRows like this:

setOpenRows((prevState) => {
  return { ...prevState, [dataRow.id]: true }
});

or with [dataRow.id]: false when you need to close it

And you pass the new value to Collapse component

<Collapse in={openRows[dataRow.id]} timeout="auto" unmountOnExit>

CodePudding user response:

You can change the state variable open from a boolean value to an object that keeps track of the open/closed state of all rows:

const [openRows, setOpenRows] = useState({});

const toggleRow = (rowId) =>
  setOpenRows((previous) => ({
    ...previous,
    [rowId]: !(previous[rowId] ?? false),
  }));

return (
  <TableBody>
    {data.map((dataRow) => (
      <TableRow key={dataRow.id} title="tableRow" className={classes.tableRow}>
        <TableCell className={classes.tableCell}>
          <IconButton size="small" onClick={() => toggleRow(dataRow.id)}>
            {open ? <ArrowDropDownIcon /> : <ArrowDropUpIcon />}
          </IconButton>
          {dataRow.id}
          <Collapse in={openRows[dataRow.id] ?? false} timeout="auto" unmountOnExit>
            <Box margin={1}>
              <Typography variant="h6" gutterBottom component="div">
                History
              </Typography>
            </Box>
          </Collapse>
        </TableCell>
        <TableCell className={classes.tableCell}>{dataRow.name}</TableCell>
        <TableCell align="left" className={classes.tableCell}>
          {dataRow.lastName}
        </TableCell>
      </TableRow>
    ))}
  </TableBody>
);
  • Related