Hedi Zitouni
Hedi Zitouni

Reputation: 179

Angular 10 click event propagation


I want to manually modify the value of an input checkbox by clicking everywhere on its html parent.

Here is my HTML:

<div (click)="onChange($event)" class="option" *ngFor = "let option of answerForm.options">
    <input type="checkbox" name="{{answerForm.type}}{{answerForm.id}}" value="{{option}}">
    <label>{{option}}</label>
</div>

Here is my typescript:

onChange($event): void {
    if ($event.target !== $event.currentTarget) {return;}
    $event.target.children[0].checked = !$event.target.children[0].checked;
}

The event works correctly when I click on the div.
When I click on the label, the event is trigger, with the label as a target and doesn't pass the condition as expected.
I expect the event propagation to automatically trigger the event for the parent, but it doesn't. It seems to be the default behavior of Angular but I am not really sure.

Do you have any solution to only trigger the click event for the div wherever the click is made on it ?

Upvotes: 0

Views: 3207

Answers (4)

Eliezer Veras Vargas
Eliezer Veras Vargas

Reputation: 224

Since what you are trying to do is always have the parent as the target of the click event instead of the children. You can use the css property pointer-events setted to none.

In the following way,

<div (click)="onChange($event)" class="option" *ngFor = "let option of answerForm.options">
<input type="checkbox" style="pointer-events: none" name="{{answerForm.type}}{{answerForm.id}}" value="{{option}}">
<label style="pointer-events: none">{{option}}</label>

Why does this work?

As it's said in Mozilla MDN Web Docs, the pointer events sets under what circumstances (if any) a particular graphic element can become the target of pointer events. In the case of the value none,

The element is never the target of pointer events; however, pointer events may target its descendant elements if those descendants have pointer-events set to some other value. In these circumstances, pointer events will trigger event listeners on this parent element as appropriate on their way to/from the descendant during the event capture/bubble phases

For more information you can visit https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events

Upvotes: 2

Filip
Filip

Reputation: 143

You should use <input type="checkbox" name="{{answerForm.type}}{{answerForm.id}}" value="{{option}}" style="pointer-events: none">

Upvotes: 0

Kavinda Senarathne
Kavinda Senarathne

Reputation: 2014

Try this :

import {Directive, HostListener} from "@angular/core";
    
@Directive({
    selector: "[click-stop-propagation]"
})
export class ClickStopPropagation
{
    @HostListener("click", ["$event"])
    public onClick(event: any): void
    {
        event.stopPropagation();
    }
}

Then just add it to the element you want it on:

<div click-stop-propagation>Stop Propagation</div>

Upvotes: 0

Oleksii Pavlenko
Oleksii Pavlenko

Reputation: 1333

As I understood, You can prevent any triggered events with css, for example add input and label style - pointer-events : none

<div (click)="onChange($event)" class="option" *ngFor = "let option of answerForm.options">
    <input type="checkbox" style="opinter-events: none" name="{{answerForm.type}}{{answerForm.id}}" value="{{option}}">
    <label style="opinter-events: none">{{option}}</label>
</div>

Upvotes: 0

Related Questions