chink
chink

Reputation: 1643

Dynamically disabling/enabling the checkboxes within a row of Angular table

I am working on an Angular project in which I am dynamically adding rows to a table.

My code in html

<table class="table table-sm table-bordered"
    style="width:100%; margin-bottom: 0em">
    <thead>
            <tr class="bg-header">
                    <th>
                            Select
                    </th>
                    <the>
                            Level
                    </th>
                    <th>
                            Config
                    </th>
                    <th>
                            Read
                    </th>
                    <th>
                            Value
                    </th>
            </tr>
    </thead>
    <tbody>
            <tr *ngFor = "let applicableLevel of applicableLevelsConfigList">
                    <td>
                            <mat-checkbox>
                            </mat-checkbox>
                    </td>
                    <td>
                            {{applicableLevel.Nm}}
                    </td>
                    <td>
                            <mat-checkbox [diabled]="true">
                            </mat-checkbox>
                    </td>
                    <td>
                            <mat-checkbox [diabled]="true">
                            </mat-checkbox>
                    </td>
                    <td>
                            <mat-checkbox [diabled]="true">
                            </mat-checkbox>
                    </td>
            </tr>        
    </tbody>
</table>

I have a checkbox at the beginning of row, followed by name of row and then 3 checkboxes for rest of the columns. I would like to the initially disable these checkboxes which come after the name of the row.

If the checkbox under select column (first column) is checked, then I would like to enable the other three checkboxes for that particular row, while these 3 checkboxes for other columns still has to be disabled, since the number of rows is dynamic.

Upvotes: 0

Views: 1819

Answers (1)

Eric Aska
Eric Aska

Reputation: 636

FormGroups and FormControls are a good solution for what you need. you can control them in group or one by one. and subscribe to changes and status.(make sure to unsub after subbing)

https://stackblitz.com/edit/angular-material-starter-qxj6he?file=app%2Fapp.component.ts

export class AppComponent implements OnDestroy {
  unsubscribe$: Subject<void> = new Subject<void>();

  applicableLevelsConfigList: {
    formGroup: FormGroup;
    select: FormControl;
    level: FormControl;
    config: FormControl;
    read: FormControl;
    value: FormControl;
  }[] = [];
  constructor() {
    this.add();
  }
  add() {
    const select = new FormControl({ value: false, disabled: false }, []);
    const level = new FormControl({ value: "", disabled: true }, []);
    const config = new FormControl({ value: false, disabled: true }, []);
    const read = new FormControl({ value: false, disabled: true }, []);
    const value = new FormControl({ value: false, disabled: true }, []);

    const formGroup = new FormGroup({ select, level, config, read, value });

    select.valueChanges.pipe(takeUntil(this.unsubscribe$)).subscribe(selectValue => {
      console.log(selectValue);
      if(!selectValue){
        // you can reset them here if you want to check them as false if they got 
        // disabled.
        // level.setValue('');
        // config.setValue(false);
        // read.setValue(false);
        // value.setValue(false);
      }
      this.toggleControllers(!!selectValue, [config, read, value]);
    });
    this.applicableLevelsConfigList.push({
      formGroup,
      select,
      level,
      config,
      read,
      value
    });
  }
  
  toggleControllers(status: boolean, controllers: FormControl[]) {
    controllers.forEach(c => {
      if (status && c.disabled) {
        c.enable();
      } else if (!status && c.enabled) {
        c.disable();
      }
    });
  }

    ngOnDestroy(): void {
    this.unsubscribe$.next();
    this.unsubscribe$.complete();
  }
}
<button (click)="add()" mat-button color="primary" >ADD</button>

<table class="table table-sm table-bordered" style="width:100%; margin-bottom: 0em">
    <thead>
        <tr class="bg-header">
            <th>
                Select
            </th>
            <th>
                Level
      </th>
      <th>
                    Config
      </th>
      <th>
                    Read
      </th>
      <th>
                    Value
      </th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="let applicableLevel of applicableLevelsConfigList">
            <td>
                <mat-checkbox [formControl]="applicableLevel.select">
                </mat-checkbox>
            </td>
            <td>
                {{applicableLevel.level.value}}
            </td>
            <td>
                <mat-checkbox [formControl]="applicableLevel.config">
                </mat-checkbox>
            </td>
            <td>
                <mat-checkbox [formControl]="applicableLevel.read">
                </mat-checkbox>
            </td>
            <td>
                <mat-checkbox [formControl]="applicableLevel.value">
                </mat-checkbox>
            </td>
        </tr>
    </tbody>
</table>

<style>
  tr, th, td{
    border: 1px solid black;
    padding: 1rem;
  }
  
</style>

<div *ngFor="let applicableLevel of applicableLevelsConfigList">
  <code>
    <pre>
      {{applicableLevel.formGroup.value | json}}
    </pre>
  </code>
</div>

Upvotes: 1

Related Questions