Input Validation Template Reference ngFor - html

I am trying to validate an input that is required in a *ngFor loop.
But I cant get a unique template Reference.
On Submit all Input fields are required / or none if at least one is filled out.
I tried to declare Template Reference like #optionContent_{{i}} but i can fill that in [ngClass].
Any help?
<form name="form" (ngSubmit)="f.form.valid && addOption()" #f="ngForm" novalidate>
<div class="row" *ngFor="let size of optionModel.optionContent let i = index">
<div class="col-12">
<label for="optionContent_{{i}}>Name Option</label>
<input id="optionContent_{{i}}"
type="text"
#optionContent="ngModel"
[ngClass]="{ 'is-invalid': f.submitted && optionContent.invalid }"
required
name="optionContent"
[(ngModel)]="size.name" class="form-control">
</div>
</div>
</form>

the problem is in the name attribute they all have the same name, so ngForm gets confused try add dynamic name
<input ... name="optionContent{{i}}" ../>

Related

How to prevent repetition in Angular html?

I have an input in my html as follows:
<ng-container *ngIf="({required: <some_condition>, invalid: <some_condition>}) as emailErrors">
<input type="email" class="form-control" placeholder="Email" validate-onblur [class.is-invalid]="emailErrors.required || emailErrors.invalid" [attr.aria-invalid]="emailErrors.required || emailErrors.invalid" [attr.aria-describedby]="emailErrors.required || emailErrors.invalid ? 'email-error' : undefined">
<div *ngIf="emailErrors.required" id="email-error">
<p class="error-msg">{{messages.EMAIL_REQ}}</p>
</div>
</ng-container>
Here in my <input> tag I'm repeting this condition 3 times: emailErrors.required || emailErrors.invalid.
Can I store this condition here in a variable, so that I do not have to repeat it?
P.S. I'm new in Angular
I would recommend you to use the template form of Angular. These are fairly simpler to implement.
In the code below make sure you give name property on the input field otherwise an error will be thrown, while working on with [(ngModel)]
<form #f="ngForm">
<input type="email" class="form-control" placeholder="Email" name="mail" required [(ngModel)]="model.email" #mail="ngModel">
<span *ngIf="mail.invalid">
{{messages.EMAIL_REQ}}
</span>
</form>
Why not introduce an additional property in the wrapping <ng-container>? And seeing that emailErrors.invalid isn't used anywhere else, it could be removed if it's unneeded.
<ng-container *ngIf="({required: <condition_1>, reqOrInv: <condition_1> || <condition_2>}) as emailErrors">
<input
type="email"
class="form-control"
placeholder="Email"
validate-onblur
[class.is-invalid]="emailErrors.reqOrInv"
[attr.aria-invalid]="emailErrors.reqOrInv"
[attr.aria-describedby]="emailErrors.reqOrInv ? 'email-error' : undefined"
>
<div *ngIf="emailErrors.required" id="email-error">
<p class="error-msg">{{messages.EMAIL_REQ}}</p>
</div>
</ng-container>
But as #YashwardhanPauranik noted in their answer, you're better off using Angular template driven or reactive forms. They provide more granular control.

required field validation only for the first item in a list

I am using Template Driven for my Angula'rs form and I have a div that repeats several times (according to a counter variable).
The thing is , I need the required validation only for the first item in this list and I 'm not sure how to do that.
<div class="form-group required margin-left" *ngFor="let hore of horim;let i = index">
<label class="control-label translate-label" [id]="'lblShemPratiHore'+i">{{selectedLanguage.shemPrati}}</label>
<!-- <img src="../../../assets/images/parent.png" alt="shem prati"> -->
<input
[id]="'shemPratiHore'+i"
[(ngModel)]="hore.shemPrati"
class="form-control input-lg"
[name]="'shemPratiHore'+i"
[attr.aria-describedby]="'lblShemPratiHore'+i"
#shemPrati="ngModel"
required
[ngModelOptions]="{ updateOn: 'blur' }"/>/>
<div *ngIf="shemPrati.errors?.required && shemPrati.touched" class="alert alert-danger">
Required Field
</div>
</div>
try binding to the required attribute if index is equal 0.
[required]="index == 0"
The anwer for this post is as follow:
[required]="i==0"

How to validate checkbox in Angular 6 using reactive form validation

How to validate checkboxes for at least one selected error message. I tried, but it's not working. Link to my project
app.component:
<form [formGroup]="form" (ngSubmit)="submit()">
<label formArrayName="orders" *ngFor="let order of orders; let i = index">
<input type="checkbox" [formControlName]="i">
{{order[i].name}}
</label>
<div *ngIf="???">At least one order must be selected</div>
<br>
<button [disabled]="!form.valid">submit</button>
</form>

Angular 6 - Form Validation on blur

I want to validate input filled in onBlur how can i do this. please help me.
<form class="form-horizontal" role="form" name="form" id="form"
(ngSubmit)="f.form.valid && onSubmit()"
#f="ngForm" novalidate>
<input type="text" class="form-control" placeholder="Social Id"
[ngModel]="generalUserData.socialId" [maxlength]=12 name="socialId" [minlength]=10
(blur)="onBlurMethod($event.target.name, $event.target.value ,generalUserData)"
#socialId="ngModel" [ngClass]="{ 'is-invalid': f.submitted && socialId.invalid }"
pattern="\d{9}(v|V)|\d{12}" required/>
<div *ngIf="f.submitted && socialId.invalid" class="invalid-feedback">
<div *ngIf="socialId?.errors.required">NIC is required</div>
<div *ngIf="socialId?.errors.minlength">NIC must be at least 10 characters long.</div>
<div *ngIf="socialId?.errors.pattern">Not valid NIC</div>
<div *ngIf="socialId?.errors.maxlength">NIC must be less than 12 characters long.</div>
</div>
</form>
I used below sample link and then I want to validate as on blur how can I do this.
The onBlur() method has been changed since Angular 5. With template-driven forms you need to use the following syntax:
<input [(ngModel)]="lastname" [ngModelOptions]="{ updateOn: 'blur' }">
Here is the demo, hope it can help you :
https://codingthesmartway.com/angular5-forms-update/
I update code below like this
<input type="text" class="form-control" placeholder="Social Id"
[ngModel]="generalUserData.socialId" [maxlength]=12 name="socialId" [minlength]=10
(blur)="onBlurMethod($event.target.name, $event.target.value ,generalUserData)"
#socialId="ngModel" [ngClass]="{ 'is-invalid': (f.submitted || socialIdType.touched) && socialId.invalid }"
pattern="\d{9}(v|V)|\d{12}" required/>
<div *ngIf="(f.submitted || socialIdType.touched) && socialId.invalid" class="invalid-feedback">
<div *ngIf="socialId?.errors.required">NIC is required</div>
<div *ngIf="socialId?.errors.minlength">NIC must be at least 10 characters long.</div>
<div *ngIf="socialId?.errors.pattern">Not valid NIC</div>
<div *ngIf="socialId?.errors.maxlength">NIC must be less than 12 characters long.</div>
</div>
now it is working fine.

required attribute not working with primeng <p-dropdown>

I am working on a angular2 App and I am using primeng for UI elements. I have dropdowns where I am using the options in these dropdowns are dynamically generated from an API call. Now, when I click the submit button, I want it to validate the forms before submitting. So I am using 'required="required"' in order to make the validation happen.
I see that, if the data is not loaded into the dropdowns, the validation works fine, but when the data is loaded and dropdown options are populated, the primeng validation breaks and it does not throw any message.
Here's my html code..
<div method="post" class="content-form">
<div class="col-lg-6">
<form #myForm="ngForm" class="form-horizontal" novalidate>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">System of Origin</label>
<div class="col-sm-10">
<p-dropdown class="contentDetails" [options]="systemOfOrigins" [(ngModel)]="defaultSoO" [ngModelOptions]="{standalone: true}" required="required" filter="filter" placeholder="NONE"></p-dropdown>
</div>
</div>
<div class="form-group">
<label for="inputEmail3" class="col-sm-2 control-label">Content Type</label>
<div class="col-sm-10">
<p-dropdown class="contentDetails" [options]="contentTypes" [(ngModel)]="selectedContentType" [ngModelOptions]="{standalone: true}" filter="filter" required="required" placeholder="Choose"></p-dropdown>
</div>
</div>
<div class="form-group">
<label for="inputPassword3" class="col-sm-2 control-label">Rendition</label>
<div class="col-sm-10">
<p-dropdown id ="rendition" placeholder="Select Rendition" class="contentDetails" [options]="renditions" [(ngModel)]="renditionSelected" [ngModelOptions]="{standalone: true}" filter="filter" required="required"></p-dropdown>
</div>
</div>
</form>
Am I not using the required attribute properly or is there any other way to do it with API calls ?
Help is appreciated
This issue happens if there is a dummy first element in the options array that is used to display please select text, and the label in that dummy element is having some value in it. So just set the label value as '' or null or undefined. It will work.
Try
<p-dropdown [required]="true">
required is a boolean property. If you are setting it dynamically, [required]="isRequired", otherwise required="true" should do it for you.
Try replacing required="required" with required="true" and seeing if that makes them required. If not, I suggest adding a plunkr