Search code examples
htmlangulartypescriptangular7

Problem with [variable] changing all inputs in a NgFor


I am building a table which has a priority field and a percentage field.

I am working with a webcomponent, which has an input. This input will change according to the "state" priority, which can be "error" or "success". The problem is I am building a table which has a priority field and a percentage field. When the percentage field exceeds 100% it should change to the state "error" else "success"

The problem I am having is that once a percentage field exceeds 100%, it works correctly, but it is also changing the other priorities, I only need to chenge the inputs that belong to the same priority to the "error" state.

As you can see in the example, I have two different priorities (1 and 3), when I exceed 100% of the priority, I should only change the input to priority 1, not priority 3

EXAMPLE: Example Gift

How can i fix this?

html:

          <ds-table-body-row slot="row" *ngFor="let detail of beneficiarios; let i = index">
              <ds-table-body-column slot="column">
                <span slot="element">
                  <ds-paragraph type="p2" family="primary" weight="regular" color="primary">
                    <span slot="text" class=""
                      >{{detail.Priority}}
                    </span>
                  </ds-paragraph>
                </span>
              </ds-table-body-column>
              <ds-table-body-column slot="column">
                <span slot="element">
                  <ds-paragraph id = "tett" type="p2" family="primary" weight="regular" color="primary">
                    <span slot="text" class=""
                      > <ds-input
                      size="s1"
                      value="{{detail.Percent}}"
                      initial-label= ""
                      labelOrientation="start"
                      [state] = "invalidPercent"
                      (focusout)="focusOutPercent(i, $event.target.value)"
                      helperMessage='test'>
                      </ds-input>
                    </span>
                  </ds-paragraph>
                </span>
              </ds-table-body-column>
          </ds-table-body-row>

ts:

invalidPercent:any;
  focusOutPercent(i: number, percentAdded:any){
    this.beneficiarios[i].Percent = percentAdded
    let total = 0;
    let sum =  i + 1;
    this.beneficiarios.forEach(i => {
      if(Number(i.Priority) == sum){
        total += Number(i.Percent)
        if (total > 100) {
          this.invalidPercent = "error";
        }else{
          this.invalidPercent = "success";
        }
      }
    })
  }

Solution

  • Somewhere in your code, preferrably when you get beneficarios, add new property in the loop:

    this.beneficiarios.forEach(item => {
        item.invalidPercent = 'success';
    })
    

    In your focusOutPercent method change:

    if (total > 100) {
         this.invalidPercent = "error";
    } else {
         this.invalidPercent = "success";
    }
    

    To:

    if (total > 100) {
         i.invalidPercent = "error";
    } else {
         i.invalidPercent = "success";
    }
    

    And then in your html template change:

    [state] = "invalidPercent"

    to

    [state] = "detail.invalidPercent"