Angular 2 prevent click on parent when clicked on child

AngularAngular2 Template

Angular Problem Overview


I have a click event nested one level. When i click on the child the expected function is called but the parent's function is also called. Here is the code

<li class="task-item" *ngFor="let task of tasks" (click)="showTask(task.name)">
    <input type="checkbox" [ngModel]="task.taskStatus" (ngModelChange)="changeTaskStatus($event)" />
</li>

So when the checkbox changes changeTaskStatus() and the showTask() called together. I want the parent to keep quiet when checkbox changes. How do I achieve this? It was easy to handle this in Angular 1

Things I've tried that failed

Used $event.stopPropagation() in the checkbox's click event that changed nothing

<input type="checkbox" [ngModel]="task.taskStatus" (click)="$event.stopPropagation()" (ngModelChange)="changeTaskStatus($event)" />

Angular Solutions


Solution 1 - Angular

You need to use stopPropagation() for checkbox event:

<input type="checkbox" [ngModel]="task.taskStatus" (ngModelChange)="changeTaskStatus($event);$event.stopPropagation()" />

It prevents further propagation of the current event in the capturing and bubbling phases. You can read more here. Also, you probably need to add stopPropagation() to click event of checkbox, but I'm not 100% sure:

<input type="checkbox" [ngModel]="task.taskStatus" (click)="$event.stopPropagation()" (ngModelChange)="changeTaskStatus($event)" />

Solution 2 - Angular

Just you need to add $event.stopPropagation() code on Child div on click event

 <input  (click)="onChildClickFunction();$event.stopPropagation()"/>

Solution 3 - Angular

This is known as Event Bubbling. Events are first handled by the innermost element and then propagate to the outer elements until they reach the root.

<div *ngFor="let item of userList">
  <div (click)="setUserData(item)">
    <a (click)="getUserDetails(item.user.id)">Name - {{item.user.name}}</a>
  </div>
</div>

In this case, when you click on username or tag, it will first call inner element i.e. getUserDetails() and the root element i.e. setUserData().

So, to prevent this event bubbling, just add

> event.preventDefault();

in defination of getUserDetails($event) or

<a (click)="getUserDetails(item.user.id); $event.stopPropagation();">Name - {{item.user.name}}</a>

That's all you need to you.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAshik BasheerView Question on Stackoverflow
Solution 1 - AngularStefan SvrkotaView Answer on Stackoverflow
Solution 2 - AngularGomtesh HatgineView Answer on Stackoverflow
Solution 3 - AngularSheena SinglaView Answer on Stackoverflow