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>
);
}
How to focus on specific card from card list React
You can add do one of the following
- Create a component of Dialog and on in card attach an onClick that will set Dialog Open and add the Dialog Data you want
- 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
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>
);
}
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
What Exactly Is Cdata and What Does It Do
After Content Update from Ajax Jquery Not Work Properly
Bootstrap Progress Bar Progression
How to Position Popover Over a Highlighted Portion of Text
Horizontal Swipe Slider with Jquery and Touch Devices Support
Angularjs Bug in Ie with Style VS Ng-Style
Using Class with Angular VS Ng-Class While Using a Mixed Expression
Particles.Js Not Covering Entire Page
Twitter Bootstrap Button Click to Toggle Expand/Collapse Text Section Above Button
Dropdown Checkboxes and Unchecked Parents Element
Adding Custom CSS and Js to Shopify
Position Sticky: Scrollable, When Longer Than Viewport
What's a React.Js-Friendly Way to Animate a List-Reordering
Detect When Scrolling Has Finished When Using 'Scroll-Behavior: Smooth'
Does Animating the Value of a CSS3 Transform with JavaScript Rule Out Hardware Acceleration
How to Copy Multiple Files and Keep the Folder Structure with Gulp