John
John

Reputation: 437

Creating generic table

I'm creating a generic and dynamic table where I have columns, rows and an action button at the end of an row. All data is displaying as intended but the header is not displaying over the action button.

enter image description here

Is there a way to display the header underline over the action button?

Data:

[
    {
        "id": "1231",
        "name": "Michael",
        "phone": "11223311",
        "medical": "YES"
    },
    {
        "id": "32123",
        "name": "Johnson",
        "phone": "3311323",
        "medical": "NO"
    }
]
const headCells = [
    {dataIndex: 'id', name: 'ID' },
    {dataIndex: 'name', name: 'Name' },
    {dataIndex: 'phone', name: 'Phone' },
    {dataIndex: 'medical', name: 'Medical' }
];

const Header = ({ cols }) => {
  return cols.map((col) => (
     <TableCell>{col.name}</TableCell>
   ));
}

const Rows = ({ data, cols }) => {
    if (data) {
        return data.map((row) =>
            <TableRow key={row.uuid}>
                {cols.map(col => <TableCell>{row[col.dataIndex]}</TableCell>)}
                    <TableCell >
                            <IconButton>
                                <SearchIcon color="primary"/>
                            </IconButton>
                    </TableCell>
            </TableRow>
       );
    }
    else return [];
};

return(
<TableContainer component={Paper}>
    <Table stickyHeader aria-label="sticky table">
        <TableHead>
           <TableRow>
             <Header cols={headCells} />
           </TableRow>
        </TableHead>
        <TableBody>
            <Rows data={data} cols={headCells} />
        </TableBody>
    </Table>
</TableContainer>
)

Upvotes: 0

Views: 499

Answers (2)

Dana Woodman
Dana Woodman

Reputation: 4522

This is happening because you are maping over your data columns, but you do not have a column for "actions". You could do what @Enchew says above or you could add another data column

const headCells = [
  {dataIndex: 'id', name: 'ID' },
  {dataIndex: 'name', name: 'Name' },
  {dataIndex: 'phone', name: 'Phone' },
  {dataIndex: 'medical', name: 'Medical' },
  {
    Component: () => (
      <IconButton>
        <SearchIcon color="primary"/>
      </IconButton>
    ), 
    name: 'Actions'
  }
];

const Header = ({ cols }) => {
  return cols.map((col) => (
     <TableCell>{col.name}</TableCell>
   ));
}

const Rows = ({ data, cols }) => {
    if (data) {
        return data.map((row) =>
            <TableRow key={row.uuid}>
                {cols.map(col => (
                  <TableCell>
                    {
                      col.Component ?
                        <Component /> :
                        <>row[col.dataIndex]</>
                    }
                  </TableCell>
                )}
            </TableRow>
       );
    }
    else return [];
};

return(
<TableContainer component={Paper}>
    <Table stickyHeader aria-label="sticky table">
        <TableHead>
           <TableRow>
             <Header cols={headCells} />
           </TableRow>
        </TableHead>
        <TableBody>
            <Rows data={data} cols={headCells} />
        </TableBody>
    </Table>
</TableContainer>
)

Just a different way to approach the problem 👍🏻

Upvotes: 1

Enchew
Enchew

Reputation: 1001

Why don't you add it manually?:

const Header = ({ cols }) => {
  return cols.map((col) => (
     <TableCell >{col.name}</TableCell>
   )).concat( <TableCell className='underline-header'>Actions</TableCell>);
}

CSS:

.underline-header {
    text-decoration: underline;
}

Upvotes: 1

Related Questions