Reputation: 1995
I have these form inputs that I generate with *ngFor
after clicking a button.
in these inputs, I put the required
attribute but it seems like it doesn't affect the form.invalid
I got other required inputs
that aren't generated dynamically and when they're not filled with values the submit button is disabled
as I want it to be, so I guess the issue is that the dynamic inputs doesn't exist until I click the button.
In addition I didn't manage to bind these inputs since they're dynamic, and I want to get they're values and send to a service when submitting the form. any suggestions how to do such a thing?
EDIT
I've added to my model object in component.ts
this this.model.players = Array(this.model.numOfTeams*this.model.numOfPlayers).fill(new Result())
and to my html i added ngModel
2way binding. now the validation is working fine, but all of the fields with same name (for example firstName) are changed together when I type in one of them.
here is my component.html
:
<div class="container">
<form #newSearch="ngForm" class="form" ngNativeValidate>
<div class="form-group pl-3">
<fieldset name="generatePlayerCards">
<legend>generatePlayerCards</legend>
<p>Please choose <b>number of teams</b> and <b>number of players for each team</b>:</p>
<input class="form-control mt-3" type="number" name="numOfTeams" id="numOfTeams" min="1" max="5" placeholder="Number of teams" [(ngModel)]="model.numOfTeams" required>
<input class="form-control mt-3" type="number" name="numOfPlayers" id="numOfPlayers" min="1" max="20" placeholder="Number of players for each team" [(ngModel)]="model.numOfPlayers" required>
<button class="btn btn-primary mt-3" type="button" (click)="generatePlayerCards()">Done</button>
</fieldset>
</div>
<div class="card-group">
<div *ngFor="let j of ngArr; let i = index; trackBy:trackByIndex;" class="col-4 mt-3">
<div class="card">
<div class="card-header text-left"><h5>New Player Data</h5></div>
<div class="card-body">
<label for="firstName{{i}}"></label>
<input type="text" name="firstName{{i}}" class="form-control my-1 mr-sm-1" autocomplete="off" placeholder="First Name" required [(ngModel)]="model.players[i].firstName">
<label for="lastName{{i}}"></label>
<input type="text" name="lastName{{i}}" class="form-control my-1 mr-sm-1" autocomplete="off" placeholder="Last Name" required [(ngModel)]="model.players[i].lastName">
<label for="score{{i}}"></label>
<input type="text" name="score{{i}}" class="form-control my-1 mr-sm-1" autocomplete="off" placeholder="Score" required [(ngModel)]="model.players[i].score">
</div>
</div>
</div>
</div>
<div class="col-3 mt-4">
<button [disabled]="newSearch.form.invalid" class="btn btn-primary mr-2" type="submit" (click)="search()">Submit</button>
<button class="btn btn-secondary" type="reset" (click)="resetForm()">Clear Form</button>
</div>
</form>
</div>
Upvotes: 2
Views: 536
Reputation: 321
In Angular in order to have dynamic fields and validation it is best practice to do it using a Form Array.
It might seem complicated at first, but Reactive forms in Angular are an incredible tool that will let you achieve great results with little to no effort in future. There are plenty video tutorials, this one is the best imho.
Upvotes: 1