1

I am looping through an array of key values to create a list of checkboxes each with a sibling disabled input. On check of each checkbox, the sibling input text field becomes enabled and is required. In this view there is a 'previous' and 'next' button and the 'next' button should be disabled if a user selects a checkbox and then does not enter anything in it's required sibling input. I almost have this working, however the 'next' button should become disabled as soon as a user checks the box as this would mean they have not entered anything in the required text input. Right now the 'next' button only becomes disabled if a user checks the checkbox, focuses on the sibling input and then leaves without entering.

My HTML...

<div *ngFor="let promotion of promotionOptions; let i = index">
    <div class="col-md-6 input-container radio-label">
        <mat-checkbox [checked]="!promotion.key" (change)="promotion.key = !promotion.key">
            {{ promotion.name }}
        </mat-checkbox>
    </div>
    <mat-input-container>
        <input matInput [disabled]="promotion.key" placeholder="Cost" name="promotionCost{{i}}" #promotionCost="ngModel" [ngModel]="" (keyup)="promotionCostInput($event.target.value)"
            [required]="!promotion.key" type="number">
        <div *ngIf="promotionCost.errors && (promotionCost.dirty || promotionCost.touched)" class="alert alert-danger cost-alert">
            <div [hidden]="!promotionCost.errors.required">Please enter the checked promotion's cost</div>
        </div>
    </mat-input-container>
</div>

<div class="clearfix"></div>

<div class="button-container">
    <button class="main-btn dark icon-left" (click)="updateStep(1)"><i class="fa fa-angle-left"></i>Previous</button>
    <button class="main-btn icon-right" (click)="updateStep(3)" [disabled]="!promotionCostValid">Next<i class="fa fa-angle-right"></i></button>
</div>

And the method I'm using in my .ts file for disabling the 'next' button:

promotionCostInput(value) {
    if (!value) {
      this.promotionCostValid = false;
    } else {
      this.promotionCostValid = true;
    }
  }

How can I validate the sibling input when a user checks the checkbox?

2
  • try this: [disabled]="!promotionCostValid || promotionCost.errors" Commented Nov 14, 2017 at 15:57
  • Thanks for the comment Fateh, however I don't think I can use that outside of the ngFor loop Commented Nov 14, 2017 at 16:13

1 Answer 1

1

Your problem is that the state of your next button is only updated when the keyup event is fired on any of your inputs. Besides, it is updated with only the value of one input but according to what you say, youwant to check that every inputs of your ngFor is filled.

I suggest you to store the value of your inputs in your model and to check that promotion cost is valid for all promotions any time the input change or a checkbox is checked.

<div *ngFor="let promotion of promotionOptions; let i = index">
  <div class="col-md-6 input-container radio-label">
    <mat-checkbox [checked]="!promotion.key" (change)="promotion.key = !promotion.key; checkPromotionCost();">
      {{ promotion.name }}
    </mat-checkbox>
  </div>
  <mat-input-container>
    <input
      matInput
      [disabled]="promotion.key"
      placeholder="Cost"
      name="promotionCost{{i}}"
      (keyup)="promotion.cost = $event.target.value; checkPromotionCost();"
      [required]="!promotion.key" type="number"
    >
    <div *ngIf="promotionCost.errors && (promotionCost.dirty || promotionCost.touched)" class="alert alert-danger cost-alert">
      <div [hidden]="!promotionCost.errors.required">
        Please enter the checked promotion's cost</div>
      </div>
  </mat-input-container>
</div>

<div class="clearfix"></div>

<div class="button-container">
  <button class="main-btn dark icon-left" (click)="updateStep(1)"><i class="fa fa-angle-left"></i>Previous</button>
  <button class="main-btn icon-right" (click)="updateStep(3)" [disabled]="!promotionCostValid">Next<i class="fa fa-angle-right"></i></button>
</div>

And in the controller:

checkPromotionCost() {
  this.promotionCostValid = true;
  this.promotionOptions.forEach(promotion => {
    if (promotion.key && promotion.cost === '') {
      this.promotionCostValid = false;
    }
  });
}
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, etiennecrb. But I don't understand where 'promostion.cost' comes from. It is throwing an error from the Angular Cli that it does not exist and I have note declared it anywher.
I have just added it to your model, you can do something different if you prefer but it has to be stored somewhere.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.