I'm writing a custom form component which is basically a textbox that will change to a label or a textarea depending on a specific property.
So if the custom component is set as read-only, the textbox should be hidden and a label must be displayed.
This hide and show logic work flawlessly. However, the dom element responsible for displaying validation messages throws an error when the control is not found.
<span class="form-control-readonly" *ngIf="readonly == true" #valuelabel>
{{inputModel}}
</span>
<input
*ngIf="readonly != true"
#control="ngModel"
[id]="id"
type="text"
class="form-control"
[placeholder]="caption"
[(ngModel)]="inputModel"
(ngModelChange)="onTextChange()"
[maxlength]="maxLength"
[required]="isRequired === true ? '' : null"
[ngClass]="{'invalid': !control.valid, 'valid': control.valid }">
<div *ngIf="(readonly == false) && (control.invalid && hideFeedback === false)" class="invalid-feedback">
<div *ngIf="(readonly == false) && (control.errors.required)">{{ caption }} is required</div>
<div *ngIf="(readonly == false) && (control.errors.maxlength)">{{ caption }} should be {{ control.errors.maxlength.requiredLength }} characters long </div>
</div>
control.errors in the last div throws "Cannot read property 'invalid' of undefined" error. Probably, because the control doesn't exist in dom.
When ngIf on input is changed to hidden, it begins to work, but I want to achieve it with ngIf.
Instead of putting ngIf on input, wrap the input and validation div inside another div and apply condition. Thus, the input model will be always visible for the condition below.
<span class="form-control-readonly" *ngIf="readonly == true" #valuelabel>
{{inputModel}}
</span>
<div *ngIf="readonly != true">
<input
#control="ngModel"
[id]="id"
type="text"
class="form-control"
[placeholder]="caption"
[(ngModel)]="inputModel"
(ngModelChange)="onTextChange()"
[maxlength]="maxLength"
[required]="isRequired === true ? '' : null"
[ngClass]="{'invalid': !control.valid, 'valid': control.valid }">
<div *ngIf="(readonly == false) && (control.invalid && hideFeedback===false)" class="invalid-feedback">
<div *ngIf="(readonly == false) && (control.errors.required)">{{ caption }} is required</div>
<div *ngIf="(readonly == false) && (control.errors.maxlength)">{{ caption }} should be {{ control.errors.maxlength.requiredLength }} characters long </div>
</div>
</div>