1

I need to achieve something like this in the picture. I need to create a table with three rows, where the third row is below the first and second rows, and the width of the third row is the combined width of the first and second rows.enter image description here

CODESANDBOX: CLICK HERE FOR CODESANDBOX

CODE

const CustomTable = () => {
  const handleSubmit = () => {};

  return (
    <TableContainer component={Paper}>
      <Formik
        initialValues={[
          {
            id: 1,
            attribute: "",
            thirdRow: ""
          }
        ]}
        onSubmit={handleSubmit}
      >
        {({ values }) => (
          <Form>
            <FieldArray
              name="rows"
              render={(arrayHelpers) => (
                <React.Fragment>
                  <Box>
                    <Button
                      variant="contained"
                      type="submit"
                      startIcon={<AddIcon />}
                      onClick={() =>
                        arrayHelpers.unshift({
                          id: Date.now(),
                          attribute: "",
                          ruleId: "",
                          thirdRow: ""
                        })
                      }
                    >
                      Add New
                    </Button>
                  </Box>
                  <Table sx={{ minWidth: 650 }} aria-label="simple table">
                    <TableHead>
                      <TableRow>
                        <TableCell>Attribute</TableCell>
                        <TableCell>
                          <span />
                          Rule ID
                        </TableCell>
                        <TableCell colSpan={2}>Third Row</TableCell>
                      </TableRow>
                    </TableHead>
                    <TableBody>
                      {values.rows?.map((row, index) => (
                        <CustomTableRow
                          key={row.id}
                          row={row}
                          index={index}
                          arrayHelpers={arrayHelpers}
                        />
                      ))}
                    </TableBody>
                  </Table>
                </React.Fragment>
              )}
            />
          </Form>
        )}
      </Formik>
    </TableContainer>
  );
};

export default CustomTable;
2
  • just use grid layout for that Commented Jan 25, 2023 at 4:02
  • @SangeetAgarwal. Can you fork my codesandbox?
    – Joseph
    Commented Jan 25, 2023 at 4:52

2 Answers 2

1

You could tweak each "row" to really render 2 rows where the second row's column spans 2 column widths.

demo.js

<Table sx={{ minWidth: 650 }} aria-label="simple table">
  <TableHead>
    <TableRow
      sx={{
        "th": { border: 0 }
      }}
    >
      <TableCell>Attribute</TableCell>
      <TableCell>Rule ID</TableCell>
    </TableRow>
    <TableRow>
      <TableCell colSpan={2}>Third Row</TableCell>
    </TableRow>
  </TableHead>
  <TableBody>
    {values.rows?.map((row, index) => (
      <CustomTableRow
        key={row.id}
        row={row}
        index={index}
        arrayHelpers={arrayHelpers}
      />
    ))}
  </TableBody>
</Table>

CustomTableRow

const CustomTableRow = ({ row, index }) => {
  return (
    <>
      <TableRow
        sx={{
          "th, td": { border: 0 }
        }}
      >
        <TableCell component="th" scope="row">
          <FastField
            name={`rows.${index}.attribute`}
            component={TextField}
            fullWidth
          />
        </TableCell>
        <TableCell>
          <FastField
            name={`rows.${index}.ruleId`}
            component={TextField}
            fullWidth
          />
        </TableCell>
      </TableRow>
      <TableRow>
        <TableCell colSpan={2}>
          <FastField
            name={`rows.${index}.thirdRow`}
            component={TextField}
            fullWidth
          />
        </TableCell>
      </TableRow>
    </>
  );
};

Edit three-rows-table-using-material-ui-and-react

enter image description here

4
  • @Joseph Probably something along the lines of either this or this answer.
    – Drew Reese
    Commented Jan 25, 2023 at 9:30
  • Hi Drew. Can you check on this? I followed your code and having an issue because i upgraded react router dom. stackoverflow.com/questions/75233649/…
    – Joseph
    Commented Jan 25, 2023 at 16:44
  • @Joseph Oh, sorry. I totally forgot to mention those solutions might not work in [email protected]+, so if you installed the latest (6.7.0 as of right now) you'll see that error/warning. If you don't need the newer Data APIs that were introduced in 6.4 then I suspect you could roll back to any RRDv6.3.x version. Looks like I have some editing of answers to do.
    – Drew Reese
    Commented Jan 25, 2023 at 17:04
  • @Joseph You might find this comment on a tracked github issue helpful. I'll take a look at your other post and sandbox.
    – Drew Reese
    Commented Jan 25, 2023 at 17:07
1

I prefer to use grid layout. You won't then use Table elements but will then want to give the role attribute for accessibility.

The nice thing about using grid layout is that you get a lot of flexibility so you can then say check for [theme.breakpoints.down("md")] and adjust your gridTemplateAreas accordingly.

So, you would do something like the following to get all the 3 rows stacked one over the other.

[theme.breakpoints.down("md")]: {
    gridTemplateColumns: "1fr",
    gridTemplateAreas: `"upper1" 
                        "upper2"
                        "bottom"`,
    gap: "0px",
  }

The other benefit of using gridArea is that the display is visual so it is easy to see as you are designing your layout

I forked your codesanbox and the link and it is at https://codesandbox.io/s/dry-tdd-vv6z1s?file=/demo.js

The complete code is given below.

import React from "react";
import Table from "@mui/material/Table";
import TableBody from "@mui/material/TableBody";
import TableCell from "@mui/material/TableCell";
import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import Paper from "@mui/material/Paper";
import { Box, Button } from "@mui/material";
import AddIcon from "@mui/icons-material/Add";
import { FieldArray, Form, Formik } from "formik";
import CustomTableRow from "./CustomTableRow";
import { styled } from "@mui/material/styles";

const Wrapper = styled(Box)(({ theme }) => ({
  display: "grid",
  gridTemplateColumns: "1fr 1fr",
  gridTemplateAreas: `"upper1 upper2 " 
                      "bottom bottom"`,
  gap: "0px"
}));

const Upper1 = styled(Box)(({ theme }) => ({
  gridArea: "upper1"
}));
const Upper2 = styled(Box)(({ theme }) => ({
  gridArea: "upper2"
}));
const Bottom = styled(Box)(({ theme }) => ({
  gridArea: "bottom"
}));
const CustomTable = () => {
  const handleSubmit = () => {};

  return (
    <TableContainer component={Paper}>
      <Formik
        initialValues={[
          {
            id: 1,
            attribute: "",
            ruleId: "",
            thirdRow: ""
          }
        ]}
        onSubmit={handleSubmit}
      >
        {({ values }) => (
          <Form>
            <FieldArray
              name="rows"
              render={(arrayHelpers) => (
                <React.Fragment>
                  <Box>
                    <Button
                      variant="contained"
                      type="submit"
                      startIcon={<AddIcon />}
                      onClick={() =>
                        arrayHelpers.unshift({
                          id: Date.now(),
                          attribute: "",
                          ruleId: "",
                          thirdRow: ""
                        })
                      }
                    >
                      Add New
                    </Button>
                  </Box>
                  <Box aria-label="simple table">
                    <Wrapper>
                      <Upper1 style={{ border: "2px blue solid" }}>
                        Attribute
                      </Upper1>
                      <Upper2 style={{ border: "2px blue solid" }}>
                        Rule ID
                      </Upper2>
                      <Bottom style={{ border: "2px blue solid" }}>
                        Third Row
                      </Bottom>
                    </Wrapper>
                    <Box>
                      {values.rows?.map((row, index) => (
                        <CustomTableRow
                          key={row.id}
                          row={row}
                          index={index}
                          arrayHelpers={arrayHelpers}
                        />
                      ))}
                    </Box>
                  </Box>
                </React.Fragment>
              )}
            />
          </Form>
        )}
      </Formik>
    </TableContainer>
  );
};

export default CustomTable;
0

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.