How to Make the Whole Card Component Clickable in Material UI Using React Js

How to make the whole Card component clickable in Material UI using React JS?

Update for v3 — 29 of August 2018

A specific CardActionArea component has been added to cover specifically this case in version 3.0.0 of Material UI.

Please use the following solution only if you are stuck with v1.

What you probably want to achieve is a Card Action (see specification) on the top part of the card.

The Material Components for Web library has this as its first usage example for the Card Component.

You can easily reproduce that exact behaviour by composing MUI Card* components with the mighty ButtonBase component. A running example can be found here on CodeSandbox: https://codesandbox.io/s/q9wnzv7684.

The relevant code is this:

import Card from '@material-ui/core/Card';
import CardActions from '@material-ui/core/CardActions';
import CardContent from '@material-ui/core/CardContent';
import CardMedia from '@material-ui/core/CardMedia';
import Typography from '@material-ui/core/Typography';
import ButtonBase from '@material-ui/core/ButtonBase';

const styles = {
cardAction: {
display: 'block',
textAlign: 'initial'
}
}

function MyCard(props) {
return (
<Card>
<ButtonBase
className={props.classes.cardAction}
onClick={event => { ... }}
>
<CardMedia ... />
<CardContent>...</CardContent>
</ButtonBase>
</Card>
);
}

export default withStyles(styles)(MyCard)

Also I strongly suggest to keep the CardActions component outside of the ButtonBase.

How to make Card component clickable?

Notice that what you are attaching to the div's onClick listener is the value returned by alert and not actually a function that should be run whenever the div is clicked.

Try changing this:

<div onClick={alert("Hello from here")}>

To this:

<div onClick={() => alert("Hello from here")}>

Material-UI: Button in CardActionArea

You need to call event.stopPropagation() in the Button's onClick and onMouseDown events in order to prevent those events from propagating to the CardActionArea. Stopping propagation of the click event is the most important aspect, but stopping propagation of the mouse-down event prevents the ripple effect from occurring on the CardActionArea (so the ripple only occurs on the Button).

Also if the CardActionArea component is overridden in such a manner as to make it an a tag, you may also need to call event.preventDefault() in the Button's click event to prevent the default browser behavior of navigating to the href specified by the a tag.

Here's a working example (based on one of the demos):

import React from "react";
import { makeStyles } from "@material-ui/core/styles";
import Card from "@material-ui/core/Card";
import CardActionArea from "@material-ui/core/CardActionArea";
import CardContent from "@material-ui/core/CardContent";
import CardMedia from "@material-ui/core/CardMedia";
import Button from "@material-ui/core/Button";
import Typography from "@material-ui/core/Typography";

const useStyles = makeStyles({
root: {
maxWidth: 345
},
media: {
height: 140
}
});

export default function MediaCard() {
const classes = useStyles();

return (
<Card className={classes.root}>
<CardActionArea
component="a"
href="https://material-ui.com"
onClick={() => console.log("CardActionArea clicked")}
>
<CardMedia
className={classes.media}
image="https://material-ui.com/static/images/cards/contemplative-reptile.jpg"
title="Contemplative Reptile"
/>
<CardContent>
<Typography gutterBottom variant="h5" component="h2">
Lizard
</Typography>
<Typography variant="body2" color="textSecondary" component="p">
Lizards are a widespread group of squamate reptiles, with over 6,000
species, ranging across all continents except Antarctica
</Typography>
<Button
size="small"
variant="contained"
color="primary"
onMouseDown={event => event.stopPropagation()}
onClick={event => {
event.stopPropagation();
event.preventDefault();
console.log("Button clicked");
}}
>
Learn More
</Button>
</CardContent>
</CardActionArea>
</Card>
);
}

Edit Button in CardActionArea

How to focus on specific card from card list React

You can add do one of the following

  1. Create a component of Dialog and on in card attach an onClick that will set Dialog Open and add the Dialog Data you want
  2. Create a Component that contain the dialog and the card and inside of it when you click you open the card and in this way you need to control only the open in each card by itself

Personally I use option number 2 cause like this I control one component and not all of them and do a re render of the parent component everytime

Click icon button in the card component without clicking the whole card

If you want the click event of the child component fires and not propagate to the parent component use e.stopPropagation().

Also if you want the propagation applied to ripple effect, make sure to attach the handler to the onMouseDown event instead of onClick. onClick event fires after the ripple effect is triggered so it doesn't work.

<IconButton>
<AddBoxIcon onMouseDown={e => e.stopPropagation()} />
</IconButton>

Live Demo

Edit Material-UI Card Ripple

How to create two onclick events on a clickable cards in react

When an event happens on an element, it first runs the handlers on it,
then on its parent, then all the way up on other ancestors.

This process is called event bubbling, learn more here.

To fix your issue, you have to call event.stopPropagation() inside your button's event handler.

export default function App() {
function handleClick(event) {
console.log("cards click");
}

function handleSubmit(event) {
event.stopPropagation(); // notice this
console.log("button inside card click");
}

return (
<div className="card" onClick={handleClick}>
<button onClick={handleSubmit}>BUTTON INSIDE CARD</button>
</div>
);
}

Edit affectionate-field-mjq9c

How to call a function when a Card is Clicked - MERN Stack

You can pass the onClick function as a prop to the child (ClientCard) from the calling (parent) component..

const ClientCard = (props) => {
return (
<Card className="text-center card-mine" onClick={props.onClick}>
<Card.Header>
Header
</Card.Header>
<Card.Body>
Body
</Card.Body>
</Card>
)
};

const Example = (props) => {
return (
<div>
<ClientCard onClick={()=>{alert('clicked!')}} />
</div>
);
}

ReactDOM.render(
<Example />,
document.getElementById('root')
)

react-bootstrap on Codeply



Related Topics



Leave a reply



Submit