How to trigger checkbox checked event on parent click

I have a number of boxes, each of them contains one checkbox. I needed to update the array if the checkbox is checked, which I achieved by this code:

<div class="col-xs-6 col-md-4 sampleWrapper" *ngFor="let sample of samplesInfo | matchSelectedType:selectedSampleTypeForModal; let i=index">
                    <div (click)="testAlert(sample, $event)" class="sample">
                        <img src="{{ imagesFolder + sample.image }}" class="b1 img-responsive">
                        <div class="checkbox">
                            <label>
                                <input type="checkbox" name="{{ sample.name }}" [value]="sample" [checked]="sample.checked" id="{{i}}" (change)="updateSelectedSamplesArray(sample, $event); sample.checked = !sample.checked;"> {{ sample.name }}
                            </label>
                        </div>
                    </div>
                </div>
// put all selected samples into array
    updateSelectedSamplesArray(obj, event) {
        let index = this.selectedSamplesArray.indexOf(obj);
        if (index === -1) {
            if (event.target.checked) {
                return this.selectedSamplesArray.push(obj);
            }
        } else {
            if (!event.target.checked) {
                return this.selectedSamplesArray.splice(index, 1);
            }
        }
    }

But now I need to do the same thing when the parent div is clicked (the one with the classname of “sample”). How can I do this? Obviously, the $event differs in parent div click and on checkbox change, so I can’t reuse my updateSelectedSamplesArray function.

Regards,
Olga

Hi Olga,

There are a few problems with your code.

  1. you use input when you should be using ion-checkbox

  2. you don’t close your input tag; see this page to copy and paste working code

  3. your code relies on both [checked] and [value], but it should only use [checked]

  4. your (change) code does 2 actions: it calls a function as well as executes in-line code; for simplicity’s sake & for the readability of the code, only do one or the other (in this case, only make a call to a function & do all work there)

  5. when creating ID values, stick to the same standards used when creating variable names (don’t call them 1, 2, 3, etc)

Here’s my *.TS file

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';

@Component({
    selector: 'page-home',
    templateUrl: 'home.html'
})
export class HomePage {

    public _fish:any[];
    public _bears:any[];

    constructor(public navCtrl: NavController) {
        this._fish = [
                    {
                        'species' : 'Rainbow Trout',
                        'imageSrc':'../assets/images/fish/rainbow.png',
                        'currentValue' : true
                    },
                    {
                        'species' : 'Brown Trout',
                        'imageSrc':'../assets/images/fish/brown.png',
                        'currentValue' : false
                    }
        ];

        this._bears = [
                    {
                        'species' : 'Polar',
                        'imageSrc':'../assets/images/bears/polar.png',
                        'currentValue' : true
                    },
                    {
                        'species' : 'Black',
                        'imageSrc':'../assets/images/bears/black.png',
                        'currentValue' : false
                    }
        ];
    }

    CheckboxClicked(item: any, $event) {
        console.log('CheckboxClicked for ' + item.species);
    }

    ParentElementClicked(zoneName: string) {
        console.log('ParentElementClicked for ' + zoneName);
    }
}

And my *.HTML file

<ion-header>
    <ion-navbar>
        <ion-title>Home</ion-title>
    </ion-navbar>
</ion-header>

<ion-content padding>

    <ion-card (click)="ParentElementClicked('fishZone')">
        <ion-card-header>
            Fish
        </ion-card-header>
        <ion-card-content>
                <ion-item *ngFor="let fish of _fish; let i = index">
                    <ion-label> {{ fish.species }} </ion-label>
                    <ion-checkbox [checked]="fish.currentValue" (click)="CheckboxClicked(fish, $event)"></ion-checkbox>
                </ion-item>
        </ion-card-content>
    </ion-card>

    <ion-card (click)="ParentElementClicked('bearZone')">
        <ion-card-header>
            Bears
        </ion-card-header>
        <ion-card-content>
                <ion-item *ngFor="let bear of _bears; let i = index">
                    <ion-label> {{ bear.species }} </ion-label>
                    <ion-checkbox [checked]="bear.currentValue" (click)="CheckboxClicked(bear, $event)"></ion-checkbox>
                </ion-item>
        </ion-card-content>
    </ion-card>

</ion-content>

Good luck,
Ryan

Leading underscores are conventionally reserved for private properties, not public. This is also abuse of any; create an interface.

@Smirnova, if you have any questions with my code, let me know. I’m not certain if my 2 separate objects (fish and bears) replicate the issue you’re having with your sample items.

Thanks,
Ryan

Oh, that’s lot of things to consider! Thanks a lot for your detailed answer.

Hmm, good point, I didn’t know about underscore convention for private vars. Yep, in my real code I’m using interface. Thanks hips!

The advice about not using any, ever, is probably the single most helpful piece of advice I’ve received on this forum. I was kindof abusing it. It saves you a ridiculous amount of time in the long run. It’s just a pain for a hot minute.

1 Like