I'm using reactive forms for implementing validation behavior. I have a problem with the validation of a dropdown component. The validation is shown before the mouseup event (The problem (yt link): Dropdown Validation)
Stackblitz link: https://angular-um4dtz.stackblitz.io/
.html
<div class="col-md-8">
<p-dropdown id="regionId" [required]="true" formControlName="selectedRegion"
placeholder="Select region (required)" [options]="regions" optionLabel="name"
[ngClass]="{'ng-invalid ng-dirty is-invalid' : (equipmentForm.get('selectedRegion').touched || equipmentForm.get('selectedRegion').dirty) && !equipmentForm.get('selectedRegion').valid }">
</p-dropdown>
<span class="invalid-feedback">
<span *ngIf="equipmentForm.get('selectedRegion').errors?.required">
Please select a region.
</span>
</span>
</div>
My question is, Is this expected behavior or?
CodePudding user response:
So, as far as I understood from debugging, it is weirdly the expected behavior.
Your input control selectedStock
has directly folowing error state: { "required": true }
. Due to that, your error message
<span class="invalid-feedback">
<span *ngIf="equipmentForm.get('selectedStock').errors?.required">
Please select a stock.
</span>
</span>
is already existing in the HTML. But it is not shown because of the CSS class invalid-feedback
. It becomes visible as soon as you want to click on your dropdown option because the input control becomes dirty and the class is-invalid
is applied.
And as far as I know, you don't need to set the class ng-invalid
by yourself to the control because it will be set by Angular.
Solution
The only way I found, at the moment, is following:
<p-dropdown
...
(onHide)="equipmentForm.get('selectedStock').markAsDirty()"
[ngClass]="{
'is-invalid': equipmentForm.get('selectedStock').dirty && !equipmentForm.get('selectedStock').valid
}">
</p-dropdown>
In this approach you mark the control as dirty as soon as the dropdown overlay gets closed. So, your error is shown afterward.