Chukwuma Kingsley
Chukwuma Kingsley

Reputation: 527

How to make Material-UI GridListTitleBar and Image a Link in ReactJS

I am using Material UI GridList to display a list of Events in React. Everything is working fine except that I am not able to make Title or Image a Link. Does anyone know how to make Title and Image a Link?

Here is my Component.

<div className={classes.root}>
  <GridListTile key="Subheader" style={{ height: "auto" }}>
    <ListSubheader component="div">This is List of Events</ListSubheader>
  </GridListTile>
  <GridList
    cellHeight={330}
    cols={matches ? 1 : 3}
    className={classes.gridList}
    spacing={12}
  >
    {tileData.length > 0 &&
      tileData.map((tile, index) => {
        return (
          <GridListTile
            key={Math.floor(Math.random() * new Date().getTime())}
          >
            <img src={tile.eventImage} alt={tile.title} />
            <GridListTileBar
              title={tile.title}
              subtitle={<span>by: {tile.description}</span>}
              actionIcon={<IconButton title={tile.title} />}
            />
          </GridListTile>
        );
      })}
  </GridList>
</div>
);

Update

This is an update to the answer that was given below. The first image is now smaller than the rest of the images after update the code with the solution given below.

The first image is now smaller than the rest of the images

Here is the new code that I am trying:

<div className={classes.root}>
  <GridListTile key="Subheader" style={{ height: "auto" }}>
    <ListSubheader component="div">This is List of Events</ListSubheader>
  </GridListTile>
  <GridList
    cellHeight={330}
    cols={matches ? 1 : 3}
    className={classes.gridList}
    spacing={12}
  >
    {tileData.length > 0 &&
      tileData.map((tile, index) => {
        return (
          <GridListTile
            key={Math.floor(Math.random() * new Date().getTime())}
          >
            <a href={"events/" + tile._id + "/eventcomments"}>
              <img
                src={tile.eventImage}
                alt={tile.title}
                className="MuiGridListTile-imgFullHeight"
              />
              <GridListTileBar title={tile.title} />
            </a>
          </GridListTile>
        );
      })}
  </GridList>
</div>

Upvotes: 0

Views: 2685

Answers (4)

Cory Siebler
Cory Siebler

Reputation: 1

You can change the type of underlying component rendered by the GridListTime Material-UI component. Just add the component="a" to have it render as an anchor tag. Then you may specify an href prop to pass in your route. See below:

<GridList cellHeight={160} className={classes.gridList} cols={3}>
  {tileData.map((tile) => (
    <GridListTile key={tile.img} cols={tile.cols || 1} component="a" href="/">
      <img src={tile.img} alt={tile.title} />
    </GridListTile>
  ))}
</GridList>

Upvotes: 0

emeeery
emeeery

Reputation: 1145

const Gallery = () => {
  const classes = useStyles();
  return (
    <Fragment>
    <div style={{background: "black"}}>
    <Toolbar/>
    <Grid container spacing={0}>
    <Grid item xs={12}>
    <Paper className={classes.paper}>GALERIA</Paper>
    <div className={classes.root}>
    <GridList cellHeight={280} className={classes.gridList} cols={1}>
        {tileData.map((tile) => (
          <GridListTile style={{ width: "100%" }}  key={tile.img} cols={tile.cols || 1}>
            <img  src={tile.img} alt={tile.title} />
          </GridListTile>
        ))}
    </GridList>
    </div>
    </Grid>
    </Grid>
    </div>
    </Fragment>
  )
}
export default Gallery;

Upvotes: 0

Chukwuma Kingsley
Chukwuma Kingsley

Reputation: 527

I eventually managed to get it to work without breaking or stretching my images, and here is what I did.

<div className={classes.root}>
  <GridListTile key="Subheader" style={{ height: "auto" }}>
    <ListSubheader component="div">This is List of Events</ListSubheader>
  </GridListTile>
  <GridList
    cellHeight={330}
    cols={matches ? 1 : 3}
    className={classes.gridList}
    spacing={12}
  >
    {tileData.length > 0 &&
      tileData.map((tile, index) => {
        return (
          <GridListTile
            component={Link}
            to={"/events/" + tile._id + "/eventcomments"}
            key={Math.floor(Math.random() * new Date().getTime())}
          >
            <img src={tile.eventImage} alt={tile.title} />
            <GridListTileBar title={tile.title} />
          </GridListTile>
        );
      })}
  </GridList>
</div>

Upvotes: 0

bas
bas

Reputation: 15462

Try wrapping the image with an anchor tag like this:

// ...
<GridListTile key={Math.floor(Math.random() * new Date().getTime())}>
  <a href="https://www.google.com/">
    <img src={tile.eventImage} alt={tile.title} className="MuiGridListTile-imgFullHeight" />
  </a>
  <GridListTileBar
    title={tile.title}
    subtitle={<span>by: {tile.description}</span>}
    actionIcon={<IconButton title={tile.title} />}
  />
</GridListTile>
// ...

It is important, after wrapping the image inside an anchor tag to add the class MuiGridListTile-imgFullHeight to the image to keep the same styling of the grid. Normally this class is added automatically, but if you wrap it inside an anchor tag it isn't. So you need to add it manually.

Update

The image shows expected behavior, because your first image is not wide enough to cover the whole tile and you only added the class to scale the img to full height. There is also a class to scale to full width: MuiGridListTile-imgFullWidth, but you can't use both of these classes together for your use case as the styles conflict (see the style definition here: https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/GridListTile/GridListTile.js).

You can try to set the width to 100% in the image style prop:

<img
  // ...
  style={{ width: "100%" }}
  className="MuiGridListTile-imgFullHeight"
/>

Upvotes: 1

Related Questions