简体   繁体   中英

Angular indeterminate checkbox feature not working

abc.component.html:

<input class='alignedItem' type="checkbox" value="0" name={{cardProgram.id}}
[indeterminate] ="cardProgram.indeterminate"  [checked] = "cardProgram.selected" [(ngModel)]='cardProgram.selected' [disabled]='(cardProgram.appId && !hasOtherAppsAssigned(cardProgram)) && (cardProgram.appId != getAppId())'
(click)='toggleCardProgram(cardProgram,cardProgram.selected)' />

<label class='fa col-1 showMore expand-indicator' [ngClass]="{'fa-plus': !rowIsExpanded(index), 
'fa-minus': rowIsExpanded(index)}"
for='{{cardProgram.id}}'></label> 

<input #hiddenAnimationInput class='h-0' type="checkbox" id='{{cardProgram.id}}'
(change)='rowClicked(index)' />
<!-- Hidden unless toggled -->

<div class='positionUp25'>
   <ul>
      <li *ngFor="let agentItem of cardProgram.agents">
         <span class='col-12'>
         <label class='offset-1TMP col-5'>
         {{cardProgram.sys}}/{{cardProgram.prin}}/{{agentItem.agent}}
         </label>
         <label *ngIf=agentItem.application class='col-6' [ngClass]="{'text-disabled': agentItem.application && agentApp(agentItem) != getAppId()}">
         {{agentItem.application.subAppName}}
         </label>
         <label *ngIf=!agentItem.application class='col-6'>
         </label>
         <input class='alignedItem ml-3' type="checkbox" name='{{cardProgram.sys}}{{cardProgram.prin}}{{agentItem.agent}}'
         #{{cardProgram.sys}}{{cardProgram.prin}}{{agentItem.agent}}='ngModel'
         [(ngModel)]='agentItem.selected' (click)='toggleAgent(agentItem, cardProgram)'
         [disabled]='agentItem.application && agentApp(agentItem) != getAppId()' />
         </span>
      </li>
   </ul>
</div>

cardPrograms.d.ts:

interface CardProgram {
    .......
    indeterminate:boolean;
    checked:boolean;
    ......

}

indeterminate.directive.ts

import { Directive, ElementRef,Input } from '@angular/core';

@Directive({ selector: '[indeterminate]' })
export class IndeterminateDirective {
   @Input() 
   set indeterminate(value)
   {
     this.elem.nativeElement.indeterminate=value;
   }
    constructor(private elem: ElementRef) {
    }
}

abc.component.ts:

private toggleAgent(agent: Agent, cardProgram: CardProgram) {
    debugger;
    this.dirty = true;

    console.log("selected" + agent.selected)
    this.updateChangeValToObj(agent, cardProgram)
    //agent.selected = !agent.selected;

    if (agent.selected) {
      agent.application = this.currentApplication();
    } else {
      agent.application = null;
      // if we deselected, also unassign the app at the program level so it will reflect as 'Multiple Apps' state 
      cardProgram.application = null;
    }
   // this.togglecheckbox(cardProgram)
   var x = 0;
   cardProgram.agents.forEach(agent => {

      if (agent.selected == true) {
        ++x;
        console.log("inside agent.selected");
      }
    })

    var length = cardProgram.agents.length;

    if (x == 0) {
      console.log("x is 0");
      cardProgram.selected = false;
      cardProgram.indeterminate =false;
    }
    else if (x == length) {
      cardProgram.selected = true;
      cardProgram.indeterminate =false;
      }
    else if (x > 0 && x < length) {

      cardProgram.selected = false;
      cardProgram.indeterminate =true;

    }  
    else{
      cardProgram.indeterminate =false;
      cardProgram.selected = false;
    }

  }

When I select all the child check-boxes(agents), the parent should be checked and this works fine. When all the agents are unchecked, and then I check one of the agents the indeterminate checkbox comes up which is fine. Problem scenario: The problem comes when I check the parent checkbox which checks all the agents which is fine but when I uncheck one of the agents, that time indeterminate option should show which is not happening. It shows unchecked for parent.

In the abc.component.ts , I see the control goes into else if (x > 0 && x < length) and sets the cardProgram.indeterminate =true; but the indeterminate is not shown in the UI for the above mentioned problem scenario most of the times but strangely works sometimes.

edit: Ok i have come to know exactly how to recreate the issue: lets say there are three child check boxes (agents) and all are unchecked which makes the parent unchecked. Now when I check one of child (shows indeterminate) and then check the parent checkbox(checks all the agents) and uncheck one the child then indeterminate should come up which it does not

I have done something like this before, except it was done using a mat-table and mat-checkbox. But the core implementation remains the same.

I believe the requirement is to display a table or a list with checkboxes to select each row and a master checkbox to check/uncheck all of them, and also to display an indeterminate state when some of the rows are checked.

Something like this could be done using <mat-checkbox> which provides the same functionality as native <input type="checkbox"> .

TS file

intialSelection: number[] = [];
allowMultiSelect = true;
selection = new SelectionModel<number>(this.allowMultiSelect, this.intialSelection);

// checks whether the number of selected elements is equal to the total number of elements in the list
isAllSelected() {
  const numSelected = this.selection.selected.length;
  const numRows = this.sourceData.length;
  return numSelected == numRows;
}

// selects all rows if they are not selected; otherwise clears the selection
masterToggle(){
  this.isAllSelected() ?
    this.selection.clear() :
    this.sourceData.forEach(row => this.selection.select(row.Id));
}

HTML File

<!-- The master checkbox -->
<mat-checkbox (change)="$event ? masterToggle() : null" [checked]="selection.hasValue() && isAllSelected()" 
    [indeterminate]="selection.hasValue() && !isAllSelected()">

<!-- Checkbox corresponding to individual rows -->
<mat-checkbox (click)="$event.stopPropagation()" (change)="$event ? selection.toggle(id) : null"
    [checked]="selection.isSelected(id)">

Reference

<input [indeterminate]="true" class="form-check-input" type="checkbox"/>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM