Search code examples
javascripthtmlangularcheckboxngmodel

store selected checkbox value. where the checkbox<div>is inside an accordion class.This value need to be calculated for every item of accordion


isChecked(name){
    let tempI = this.chekcbOxValueArray.findIndex((x)=> x == name)
    return tempI>=0 ?true :false;
}

selectedWorker(name, checked){
    if(checked == true){
        this.a.push(name)
    }
}

onClickOkay(){
    item.workerNamesSelected = a.toString()
}
<div class="accordion-content">

    <div *ngFor="let item of accordianFields; let i = index">

        <!-- This is 1st item of accordian (chekcbox input) -->
        <div>
            worker Names
            <ng-template #checkBoxPopup>
                <div *ngFor="let worker of workerdataList">

                    <input type="chekcbox" [checked]="isChecked(worker.name)"
                        (click)="selectedWorker(worker.name, $event.target.checked)"
                        [(ngModel)]="item.workerNamesSelected" />
                </div>
                <div>
                    <button (click)="onClickOkay"></button>
                </div>
            </ng-template>
            <span ngbPopover="checkBoxPopup"></span>

        </div>\


        <!-- 2nd item  -->
        <!-- nth -->

    </div>
</div>

I am unable to get value for each item of accordion. The value remains same for all the accordion item -worker name.

Expected result:

for 1st item : some selected worker

for second accordion item : some other selected worker


Solution

  • A input type checkbox only can have two values: false or true. So, a serie of checkboxes only can store an array of booleans

    If we want in a variable store an array of values instead of a serie of booleans and we are using template driven form (ngModel) we need to have

    1. An array with the list of values: workerdataList

    2. A Variable: item.workerNamesSelected

    3. Two functions:

      isChecked(name:string,item:any)
      {
         return (item.workerNamesSelected || []).indexOf(name)>=0
      }
      
      checked(checked:boolean,name:string,item:any)
      {
        const oldValue = item.workerNamesSelected || [];
        if (!checked)
            item.workerNamesSelected =item.workerNamesSelected.filter((x:string)=>x!=name)
        else
            item.workerNamesSelected=this.workerdataList.map(x=>x.name).filter(
                    x=>x==name || oldValue.indexOf(x) >= 0)
      }
      

    Now we can split the [(ngModel)] in [ngModel] and (ngModelChange)

      <div *ngFor="let item of accordianFields; let i = index">
        <div>
          worker Names
          <div *ngFor="let worker of workerdataList">
            <input
              type="checkbox"
              [ngModel]="isChecked(worker.name,item)"
              (ngModelChange)="checked($event,worker.name,item)"
            />{{worker.name}}
          </div>
        </div>
      </div>
    

    See that in input type checkbox in angular not use [checked]. All is mannaged by the [ngModel]

    A stackblitz

    NOTE: In the stackblitz I not use an accordeon, but it's indiferent.