I have a div which is wrapped in a Link tag in NextJS. Within the div I have a row of components which are buttons. When I click one of these buttons, they do what they should do, but the Link tag also gets fired from the parent div and we navigate to another page. I have added e.stopPropagation() to the event handlers of the buttons, but it's not making any difference. Can anyone see what I'm doing wrong, please?
The parent component:
<Link href={{
pathname: `/...`,
query: {
var:var
},
}}>
<div>
...
<div className="flex flex-row">
<Button1/>
<Button2/>
</div>
</div>
</Link>
A child button component:
async function handleClick(e) {
e.stopPropagation()
...
}
<button onClick={handleClick}>
...
</button>
I have also tried adding adding the stopPropagation to the onClick as such:
<button onClick={(e) => e.stopPropagation(), handleClick}>
...
</button>
Why is the click still bubbling up to the parent Link, please?
here is the culprit:
<button onClick={(e) => e.stopPropagation(), handleClick}>
try:
<button onClick={(e) => { e.stopPropagation(); handleClick(); }>
live demo on these two different versions:
https://codepen.io/remyho427/pen/NWamxvG
Related
Here what I am trying is I have dynamic data and displaying it in section and section is clickable and under that, I have 2 buttons called edit, del after clicking those buttons also it should trigger some action.
The problem I am facing is even though I am clicking edit action but the section button click also getting triggered and I tried putting #click.prevent still facing the issue.
what I need is whenever I click on edit or del the section action should not trigger below is my code sandbox URL
https://codesandbox.io/s/vuejs-with-import-json-example-forked-tjn45?fontsize=14&hidenavigation=1&theme=dark
code
<template>
<div>
<section
style="border-style: dotted"
v-for="(name, index) in names"
:key="index"
#click.prevent="methodOne"
>
<div>
<button #click.prevent="edit">Edit</button>
<button #click="del">Del</button>
</div>
<div>
{{ name }}
</div>
</section>
</div>
</template>
<script>
import states from "../assets/data.json";
export default {
name: "HelloWorld",
computed: {
names() {
return states.accounts.map((item) => {
return item.name;
});
},
},
methods: {
methodOne() {
alert("Method One");
},
edit() {
alert("Edit");
},
del() {
alert("DELETE");
},
},
};
</script>
This is event propagation issue, .prevent don't stop the propagation, Use .stop instead of .prevent. Update example here
<div>
<button #click.stop="edit">Edit</button>
<button #click.stop="del">Del</button>
</div>
My jsx:
return (
<div onClick={this.clickondiv}>
<i className="zmdi zmdi.." onClick={this.clickonicon} />
</div>
)
How do I prevent the onClick event on the div when I click on the icon?
You can stop the event from propegating up the DOM tree. In your clickonicon do this.
clickonicon(e){
e.stopPropagation();
//Rest of the clickonicon code
}
I currently have a a parent div and a child div in the middle of the parent div. I want to be able to close the parent div only on clicking outside of the child div. How would I go about doing this? I have my code currently set up as below, with the triggerParentUpdate to set true or false whether to show div.
<div onClick={this.props.triggerParentUpdate} className="signupModalContainer">
<div className="embed-responsive embed-responsive-16by9">
<form action="action_page.php">
<div className="container">
<button onClick={this.props.triggerParentUpdate} type="button" className="closebtn">X</button>
</div>
</form>
</div>
</div>
the onclick function in the first div (className="signupModalContainer") makes it so that when I click that div or any of the child divs, all the divs close. if I take that onclick function out, then the divs close via the closebtn.
Thank you!
Create a handler for the child div's onClick event handler, which stops the propagation/bubbling up of the event to the parent.
Refer to Event.stopPropagation method for more info.
class SomeComponent extends Component {
handleCloseButton = e => {
// This stops the event from bubbling up.
// So it won't trigger the parent div's "onClick" to fire.
e.stopPropagation();
this.props.triggerParentUpdate(e);
}
render () {
// ...
return (
<div onClick={this.props.triggerParentUpdate} className="signupModalContainer">
<div className="embed-responsive embed-responsive-16by9">
<form action="action_page.php">
<div className="container">
<button onClick={this.handleCloseButton} type="button" className="closebtn">X</button>
</div>
</form>
</div>
</div>
);
}
)
I have the following render method inside my main component. I have attached a onClick event to an img element nested inside another component and calling the main component's function. This works using Chrome and Edge but not from Firefox or IE11. I need it work for all.
How do I set it up so I can have my onIconClick event wired up for all?
class LookupFieldItem extends React.Component {
constructor(props) {
super(props);
this.onIconClick = this.onIconClick.bind(this);
}
onIconClick(e) {
......
}
return (
<div>
<div>
<TextInput field={field} className={_className} inputRef={inputRef} fieldMetadata={fieldMetadata} value={value} onChange={onChange} onKeyDown={this.onKeyDown}>
<div className="input-group-btn">
<button type="button" className="btn btn-default">
<img src='/Content/images/LookupIcon.png' onClick={this.onIconClick} />
</button>
</div>
</TextInput>
</div>
</div>
);
}
Update with transpiled code block
_react2.default.createElement(
'button',
{ type: 'button', className: 'btn btn-default' },
_react2.default.createElement('img', { src: '/Content/images/LookupIcon.png', onClick: function onClick() {
return console.log('lookup icon');
} })
)
I was having the same issue, I found that the onClick was not being passed to the image (using react-dev-tools I could trigger it programatically) so the problem was where it was defined, so change from this:
<button type="button" className="btn btn-default">
<img src='/Content/images/LookupIcon.png' onClick={this.onIconClick} />
</button>
to this:
<button type="button" className="btn btn-default" onClick={this.onIconClick}>
<img src='/Content/images/LookupIcon.png' />
</button>
it is not a binding issue, it looks like some predefined prop is being sent down from the button if it is not defined.
my issue was the same, the difference was that I was wrapping a Glyphicon
Let's start with the simplest thing we can do first.
onClick={this.onIconClick.bind(this)}
Does it work now?
I have a simple modal component:
function Modal(props) {
return (
<div className={cx(styles.overlay, { show: props.show })} onClick={props.onClose}>
<div className={styles.modal}>
<span className={styles.closeBtn} onClick={props.onClose} />
{props.children}
</div>
</div>
)
}
the onClose prop triggers closing the modal, hence I attach it to styles.overlay (dark overlay that you typically see on modals that when clicked dissmises it) and to styles.closeBtn (a close button for modal).
The whole flow works besides the fact that anything inside styles.overlay when clicked on also dismisses the modal, which is not functionality I was after, hence I need to only dismiss it if that specific element is clicked not its children.
function Modal(props) {
return (
<div className={cx(styles.overlay, { show: props.show })} onClick= {props.onClose}>
<div className={styles.modal} onClick={e => e.preventDefault()}>
<span className={styles.closeBtn} onClick={props.onClose} />
{props.children}
</div>
</div>
)
}
I think, the best way is to have your overlay and your modal in two separate div, but this should work.
Add onClick(e)={e.stopPropagation();} to the modal dialog's click handler; this should prevent it from propagating to the overlay.
Hope it works! Good luck!