0

I have 3 tables being pinned to each other, the reason I did that is the middle table will have at least 15 columns and I need to put it in the middle and that so people could just horizontally scroll the other columns.

Now , I wanted to implement a sticky header even with just the vertical global scroll but since it is 3 tables it is hard to find a solution to it.

I have a sandbox if anyone has an idea how to implement the sticky header , would be much appreciated. Thanks.

https://codesandbox.io/s/relaxed-frost-13y5td?file=/src/PortfolioPage/PortfolioPage.jsx

enter image description here

#snippet

export const StyledDataGrid = styled(DataGrid)`
        .MuiDataGrid-row: nth-of-type(odd) {
          background: #E3E0E0
        }
        .MuiDataGrid-cell {
          border-right: 1px solid #C4C4C4;
        }
        .MuiDataGrid-columnHeader  {
          border-right: 1px solid #C4C4C4;
        }
        .MuiDataGrid-columnSeparator--sideRight {
          display: none
        }
        .MuiDataGrid-columnHeaderTitleContainer {
          justify-content: space-between;
        }
        .MuiDataGrid-iconButtonContainer  {
          visibility: visible;
          width: auto;
        }
    `;
    
    const Page: FC = () => {
      
    
      const columns: GridColDef[] = [
        {
          field: "associateDirectorofConstructionOps",
          headerName: "Associate Director of Construction Ops",
          minWidth: 300,
          flex: 0.16,
          disableColumnMenu: true,
          renderCell: (params: GridRenderCellParams<string>) => (
            <>
               {
                 params.row.associateDirectorofConstructionOps ? params.row.associateDirectorofConstructionOps.map((prop: IEmail) => renderList(prop))
                  : null
               }
            </>
          ),
        },
      ];
      const fixedColumnLeft: GridColDef[] = [
        {
          field: "regionName",
          headerName: "Region Division",
          flex: 0.08,
          minWidth: 100,
          disableColumnMenu: true,
        },
        {
          field: "subRegionName",
          headerName: "Sub-Region",
          flex: 0.15,
          minWidth: 50,
          disableColumnMenu: true,
        },
        {
          field: "marketName",
          headerName: "Market",
          flex: 0.08,
          minWidth: 50,
          disableColumnMenu: true,
        },
      ];
      const fixedColumnRight: GridColDef[] = [
        {
          field: "action",
          disableColumnMenu: true,
          sortable: false,
          renderHeader: () => <></>,
          renderCell: (params: GridRenderCellParams<string>) => (
            <div
              style={{
                color: "rgb(110 110 110)",
                display: "flex",
                justifyContent: "space-between",
              }}
            >
              <EditIcon onClick={() => handleClickOpen(params)} />
            </div>
          ),
        },
      ];
      const [open, setOpen] = React.useState<boolean>(false);
      const handleClickOpen = (data: any) => {
        setSelectedRow(data.row);
        setOpen(true);
      };
    
      const handleClose = () => {
        setOpen(false);
      };
      return (
        <Box sx={{ height: "100vh", background: "#EEEAEA" }}>
          <Snackbar
            open={snackbarOpen}
            autoHideDuration={3000}
            onClose={() => setSnackbarOpen(false)}>
            <Alert onClose={() => setSnackbarOpen(false)} severity="success" sx={{ width: '100%' }}>
                  Successfully saved!
            </Alert>
          </Snackbar>
          <EditProperties open={open} handleClose={handleClose} selectedRow={selectedRow} />
          <DashboardWrapper seoProps={{
            title: "PIM | Regions",
            }}
            title="Properties"
            mainClass="properties-page">
            {isError ? <div>Error Loading Regions!</div> : ""}
            {isPending ? <>Loading Regions...</> : ""}
            {isSuccess ? (
            <>
                <div
                  style={{
                    display: "flex",
                    justifyContent: "space-between",
                    width: "636px",
                    height: "56px",
                    background: "rgba(37, 36, 41, 0.9)",
                    padding: "8px 16px 8px 8px",
                    borderBottomRightRadius: "30px",
                  }}
                >
                  <Input
                    size="small"
                    style={{
                      width: "461px",
                      height: "40px",
                      background: "#FFFFFF",
                      borderRadius: "4px",
                      outline: "none",
                    }}
                    placeholder="Search  by typing property name or address"
                    startAdornment={
                      <InputAdornment position="start">
                        <SearchIcon />
                      </InputAdornment>
                    }
                  />
                  <Button
                    variant="contained"
                    style={{ textTransform: "capitalize" }}
                  >
                    Search
                  </Button>
                  <div
                    style={{
                      display: "flex",
                      color: "#FFFFFF",
                      flexDirection: "column",
                      justifyContent: "space-between",
                      alignItems: "center",
                      marginRight: "10px",
                    }}
                  >
                    <TuneIcon style={{ fontSize: "32px" }} />
                    <span style={{ fontSize: "10px", marginTop: "-5px" }}>
                      Filters
                    </span>
                  </div>
                </div>
                <TableContainer component={Paper} style={{ marginTop: "24px" }}>
                  <div
                    style={{
                      borderBottom: "1px solid #C4C4C4",
                      padding: "16px",
                      display: "flex",
                      justifyContent: "space-between",
                      background: "#FFFFFF",
                      height: "72px",
                    }}
                  >
                    <label
                      style={{
                        fontWeight: "600",
                        fontSize: "24px",
                        color: "#252429",
                        alignSelf: "center",
                      }}
                    >
                      {" "}
                      Regions{" "}
                    </label>
                    <div
                      style={{
                        alignSelf: "center",
                        color: "#C4C4C4",
                        display: "flex",
                        fontSize: "16px",
                      }}
                    >
                      <IosShareIcon style={{ marginRight: "14px" }} />
                      Export
                    </div>
                  </div>
                  {/* Table container */}
                  <div style={{position: "relative", display: 'flex', justifyContent: 'space-between'}}>
                      {/* Left table */}
                      <Box
                        sx={{ boxShadow: 5 }}
                        style={{
                          width: "20%",
                       
                          zIndex: 99,
                          overflow: "hidden",
                          background: "#FFFFFF",
                        }}
                      >
                        <StyledDataGrid
                          autoHeight 
                          getRowId={(row) => row.accountId}
                          hideFooterPagination={true}
                          components={{
                            ColumnSortedAscendingIcon: UnfoldMoreIcon,
                            ColumnSortedDescendingIcon: UnfoldMoreIcon,
                          }}
                          rows={rows}
                          columns={fixedColumnLeft}
                          disableSelectionOnClick
                          experimentalFeatures={{ newEditingApi: true }}
                        />
                      </Box>
    
                      {/* Center table */}
                    <div style={{overflow: 'hidden', width: '70%'}}>
                      <div style={{ width: '2000px', margin: 'auto', overflow: "hidden"}} >
                        <StyledDataGrid
                          autoHeight 
                          getRowId={(row) => row.accountId}
                          components={{
                            ColumnSortedAscendingIcon: UnfoldMoreIcon,
                            ColumnSortedDescendingIcon: UnfoldMoreIcon,
                          }}
                          rows={rows}
                          columns={columns}
                          pageSize={100}
                          rowsPerPageOptions={[10, 20, 50, 100]}
                          disableSelectionOnClick
                          experimentalFeatures={{ newEditingApi: true }}
                        />
                      </div>
                    </div>
    
                      {/* Right table */}
                      <Box
                        sx={{ boxShadow: 5 }}
                        style={{
                          width: "10%",
                          zIndex: 99,
                          overflow: "hidden",
                          background: "#FFFFFF",
                        }}
                      >
                        <StyledDataGrid
                          autoHeight 
                          getRowId={(row) => row.accountId}
                          hideFooterPagination={true}
                          components={{
                            ColumnSortedAscendingIcon: UnfoldMoreIcon,
                            ColumnSortedDescendingIcon: UnfoldMoreIcon,
                          }}
                          rows={rows}
                          columns={fixedColumnRight}
                          disableSelectionOnClick
                          experimentalFeatures={{ newEditingApi: true }}
                        />
                      </Box>
                  </div>
                </TableContainer>
                {/* <ActionButtonContainer
                  btnNameOne="Property"
                  btnNameTwo="Properties"
                  btnIconOne={<UploadFileIcon />}
                  btnIconTwo={<AddIcon />}
                /> */}
              </>
            ) : (
              ""
            )}
          </DashboardWrapper>
        </Box>
5
  • 1
    By sticky header did you mean the SearchBox component is one you would like to stick to the top? Commented Nov 12, 2022 at 4:25
  • yes for example the table has 100 rows when I croll below the header should be sticky so even though I am at the bottom I could still see the headers Commented Nov 12, 2022 at 4:44
  • what I mean Sir is the table headers Commented Nov 12, 2022 at 6:34
  • In this case, I think forcing this behavior will create more issue for MUI than it solves. But I'm curious too to see if this could be possible without breaking styles in DataGrid. Commented Nov 12, 2022 at 9:26
  • What do you mean by sticky header? MUI datagrid tables headers are sticky by default Commented Nov 14, 2022 at 22:25

1 Answer 1

1

What do you mean by sticky header? MUI data grid tables headers are sticky by default, you need however to set a parent for the data grid with a fixed height in order to get the benefit of this feature. Logical and you must get rid of the autoHeight prop as well. ex:

<Box sx={{ height: 400 }}>
  <DataGrid ...props />
<Box>

The DataGrid extends to the height of its parent by default.

Setting the autoHeight prop will make the table stretch based on the number of rows it has inside.

Having it to stretch based on the number of the rows inside will prevent you from seeing the sticky header feature.

here's a working version of your sandbox

https://codesandbox.io/s/relaxed-frost-13y5td?file=/src/PortfolioPage/PortfolioPage.jsx:2525-2528

And I actually I have to tell you something I should have told you about from the last time, but I did not like to annoy you. Having three separate tables like that is an awful practice. If someone wanted to sort the table A descending instead of ascending, the data showing in the table B and C will be indicating something totally wrong, and If someone filtered the table B for a column that contains the character "H" for example, the order of the entire table would change, which will keep the other tables in the same state, which gives false information to the reader. You either have to build up your own data grid, purchase for MUI X premium, or use another datagrid component on NPM. Or, you'll have to manage all these odds and take the risk for any unpredicted bug afterwards. If you think about it, there's no need for the table splitting that way, keep it clean and simple, life is too short for this kind of stuff, people don't care about the designs, people care about the functionalities it serves.

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.