0

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 ?

1
  • If you're trying to prevent the default behavior, you could try putting '$event.preventDefault()' as the first line of the onChange method. Commented Nov 15, 2020 at 0:14

4 Answers 4

2

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

Sign up to request clarification or add additional context in comments.

4 Comments

Welcome to stackoverflow, your answer is only contains about code and it needed to add more detail in it. for more information about good answers in StackOverflow please see stackoverflow.com/help/how-to-answer .
Is it better this way? Thanks so much for the feedback.
yes it is, I voted up your answer because it has a good quality ,thanks for your cooperation, good luck ...
Thank you ! It works for me :). I didn't knew this css property
0

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>

1 Comment

Same thing that I said to Philip, this is the solution I choose but you have a miss spelling of pointer-events
0

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>

Comments

0

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

1 Comment

This is what i decided to use, on input and label. You should edit you answer to write pointer-events instead of opinter-events. But thank you for your response

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.