javascriptangularangular-reactive-formsinline-editing

How to make 4 rows non editable based on type and enable Add button if the editable fields are added with 1st 3 column using angular12


i am working on Angular12, here i have got table with inline editable with reactive forms. in this, i am making editable rows based on index values, but i want to make rows editable if the type doesnt include, ['Per Chase MRR', 'Per Chase IRR', 'Mileage Reimbursement' ,'Up-Charge'], rest fields to appear as editable, and columns 'Unit Cost' and 'Total' wont be editable at any point. when i click on 'Add' button, i am disabling the Add button if charge type is not added, but here type, description and quantity are also mandatory fields.

HTML:

<div class="page__container my-3">
  <h4 class="page__title">Other Charges</h4>
  <button
    type="button"
    class="btn btn-primary page__button"
    (click)="addNewCharge()"
    [disabled]="disableAdd()"
  >
    Add
  </button>
</div>
<form [formGroup]="chargesForm">
  <table class="table align-middle mb-0 table-hover">
    <thead>
      <tr>
        <th
          scope="col"
          *ngFor="let field of headerColumn"
          class="{{ field.class }}"
        >
          {{ field.displayName }}
          <i class="{{ field.icon }}" aria-hidden="true"></i>
        </th>
        <th scope="col"></th>
      </tr>
    </thead>
    <tbody>
      <ng-container
        formArrayName="users"
        *ngFor="let group of getFormData.controls; let i = index"
      >
        <tr [formGroupName]="i">
          <td>
            <ng-container *ngIf="i <= 3">{{
              getFormData.controls[i].value.type
            }}</ng-container>
            <select
              *ngIf="i > 3"
              class="custom-select drop form-control"
              formControlName="type"
              id="competitorId"
              #device
              (change)="onChange($event, i)"
            >
              <option disabled="" value="">Choose Charge</option>
              <option
                *ngFor="let charge of dropdownList"
                [value]="charge.name"
                title="charge.name"
              >
                {{ charge.name }}
              </option>
            </select>
          </td>
          <td class="width-textrestarea">
            <ng-container *ngIf="i <= 3">{{
              getFormData.controls[i].value.description
            }}</ng-container>
            <input
              type="text"
              class="form-control"
              formControlName="description"
              placeholder="description"
              *ngIf="i > 3"
              (focusout)="addTotal(i)"
            />
          </td>
          <td class="w-60">
            <ng-container *ngIf="i <= 3">{{
              getFormData.controls[i].value.quantity
            }}</ng-container>
            <input
              type="text"
              class="form-control"
              formControlName="quantity"
              placeholder="quantity"
              *ngIf="i > 3"
              (focusout)="addTotal(i)"
            />
          </td>
          <td class="w-10">
            <ng-container>{{
              getFormData.controls[i].value.unitCost
            }}</ng-container>
          </td>
          <td class="w-5">
            <ng-container>{{
              getFormData.controls[i].value.totalCost
                | currency: 'USD':'symbol':'1.2-2'
            }}</ng-container>
          </td>
          <td class="width-textrestarea pointer text-end">
            <span title="Delete" class="delete-icon" *ngIf="i > 3">
              <i
                class="fa-regular fa-trash-can text-danger"
                (click)="deleteItem(group, i)"
              ></i>
            </span>
          </td>
        </tr>
      </ng-container>
      <tr>
        <td>Total</td>
        <td></td>
        <td></td>
        <td></td>
        <td>$0.00</td>
      </tr>
    </tbody>
  </table>
</form>

TS:

disableAdd() {
    let disable = false;
    for (let i = 0; i < this.getFormData.controls.length; i++) {
      if (!this.getFormData.controls[i].value.type) {
        disable = true;
        return disable;
      }
    }
    return disable;
  }

Demo


Solution

  • What I have understood from your question is that once add button is clicked it should stay disabled until user add charge, descrption and quantity. To achieve this you just need to mark all the 3 fields as required using Validators.required and in html you just need to change the check on add button to [disabled]=this.chargeForm.invalid this should work then

    Here is stackblitz demo for the same.

    Note: Also it is not recommended to call functions from disabled tag or ngIf in html because it can cause performance issues has these functions get called continuously. You can check this by adding a console.log() in the function that you have used (disableAdd())