Reputation: 7490
I have this html code that's working properly:
<div class="form-group"
[ngClass]="{'has-error': !control.valid && control.dirty, 'has-success': control.valid && control.dirty}">
<label class="col-sm-3 control-label">User:</label>
<div class="col-sm-9">
<input class="form-control" type="email" id="email"
minlength="5"
ngControl="email" #control="ngForm">
<span class="help-block" *ngIf="!control.valid && control.dirty">
este campo debe ser mayor que 5
</span>
</div>
</div>
I want to create a component like this:
<control-validation>
<label>User:</label>
<input class="form-control" type="email" id="email"
minlength="5"
ngControl="email" #control="ngForm">
<error-messages>
<span class="help-block" *ngIf="!control.valid && control.dirty">
este campo debe ser mayor que 5
</span>
</error-messages>
</control-validation>
I have a problem with ngClass, the parent directive should know what's the input reference name. How can I select the input and get the reference name "#control" and use it in the parent component in order to ngClass works properly?
I accept any other solutions to create a component that encapsulates any input validation according to this css.
Upvotes: 1
Views: 1723
Reputation: 202206
In fact, I would use another approach. What is specific here is the input. If you want to modularize the repetitive logic (the label, the error messages and the class), I would create a dedicated component that leverages the ng-content of Angular2.
Let's call the component field
. I would use it this way:
<field label="User">
<input class="form-control" type="email" id="email"
minlength="5"
ngControl="email" #control="ngForm">
</field>
At the beginning the component template could be the following:
<div class="form-group">
<label>{{label}}</label>
<div class="col-sm-9">
<ng-content ></ng-content>
</div>
</div>
You need to define an input for the label into your component:
@Component({
selector: 'field',
template: `
(...)
`
})
export class FieldComponent {
@Input()
private label:string;
}
Then you need to reference the control associated with the input within the ng-content
using @ContentChild
:
@Component({
(...)
})
export class FieldComponent {
(...)
@ContentChild(NgControlName)
private control:NgControlName;
}
This way you will be able to use it (control
) within the component template to check the validity of the control:
@Component({
selector: 'field',
template: `
<div class="form-group" [ngClass]="{'has-error': !control.valid && control.dirty, 'has-success': control.valid && control.dirty}">
<label class="col-sm-3 control-label">{{label}}</label>
<div class="col-sm-9">
<ng-content></ng-content>
<span class="help-block"*ngIf="!control.valid && control.dirty">
este campo debe ser mayor que 5
</span>
</div>
</div>
`
})
export class FieldComponent {
(...)
}
With this approach, you will be able to use the field
component for other inputs without having to duplicate code...
See this plunkr: https://plnkr.co/edit/rGpGCnyrEm3Q9Ezbj5em?p=preview.
See this article (section "Form component for fields" for more details:
Upvotes: 3