Reputation: 487
I have this code in my Material table
:
<ng-container matColumnDef="columnDef">
<th mat-header-cell *matHeaderCellDef>Column heading</th>
<td mat-cell *matCellDef="let row">
<mat-form-field>
<input matInput [(ngModel)]="row.myField">
<mat-error *ngIf="row.myField > 0"> My error message </mat-error>
</mat-form-field>
</td>
</ng-container>
The thing is that mat-form-field is not a FormControl
, but it would be nice if mat-error
would somehow validate this input and display the error message.
Can someone tell me if it is possible?
Upvotes: 26
Views: 36155
Reputation: 34093
If you get a reference to the <mat-chip-list>
element you can manually set it's errorState
property
@ViewChild('chipList') chipList;
setErrorState(): void {
this.chipList.errorState = this.dataList.length >= 0;
}
Here's a demo: https://stackblitz.com/edit/angular-matchiplist-with-error-message?file=app%2Fchips-input-example.ts
Upvotes: 0
Reputation: 13
You can use this:
<mat-form-field
appearance="fill"
class="mat-input"
[ngClass]="{ 'mat-form-field-invalid': !!errorMessage }"
[floatLabel]="'always'"
>
<mat-label>{{ label }}</mat-label>
<input
matInput
type="text"
[(ngModel)]="object[valueProperty]"
(focusout)="onFocusLost()"
/>
<span class="error" *ngIf="!!errorMessage"> {{ errorMessage }}</span>
</mat-form-field>
onFocusLost() {
setTimeout(this.validate, 200);
}
validate=()=> {
this.errorMessage = this.validator.ValidationMessage(text);
}
.error {
font-size: 10px;
color: red;
position: absolute;
top: 40px;
left: 0;
}
Upvotes: 0
Reputation: 518
I think following code will give good solution. I have done the auto validation trigger when the user navigated to the component.
Below example implemented for required validation, based on your requirement change the validator
<mat-form-field>
<input matInput [(ngModel)]="row.myField" #sampleField="ngModel" required>
<mat-error *ngIf="sampleField.invalid && (sampleField.errors && sampleField.errors['required'])"> My error message </mat-error>
</mat-form-field>
If you don't want to auto trigger the validation then can skip the below ts statements
//in ts
@ViewChild('sampleField', { static: false })
set input(element: NgModel) {
if(element) {
element.control.markAllAsTouched()
}
}
Upvotes: 2
Reputation: 2598
you can use a span attribute with custom style:
<mat-form-field>
<input matInput [(ngModel)]="row.myField">
<span *ngIf="row.myField > 0"
class="error">My error message
</span>
</mat-form-field>
component.css (this is just an example)
.error {
font-size: 10px;
color: red;
}
Upvotes: 5
Reputation: 1817
While <mat-error>
is tied to an error condition of the formControl
, <mat-hint>
is not.
You can try this hack:
<mat-form-field [class.mat-form-field-invalid]="hasError">
<input matInput [(ngModel)]="some.model">
<mat-hint class="mat-error" *ngIf="hasError">Error Message</mat-hint>
</mat-form-field>
Upvotes: 26
Reputation: 403
You are correct that mat-form-field
is not a form control, but matInput
is. You just need to wrap the input in a form and specify the name
for the form control when you are using ngModel
binding. You can use the built in min
validator on a number type input to do the check for you, then Angular Material will integrate with the FormsModule to hide/show the error as appropriate. The code below should work:
<form>
<table mat-table>
...
<ng-container matColumnDef="columnDef">
<th mat-header-cell *matHeaderCellDef>Column heading</th>
<td mat-cell *matCellDef="let row">
<mat-form-field>
<input matInput type="number" [(ngModel)]="row.myField" [min]="0" [name]="'myField'+row.id">
<mat-error>My error message</mat-error>
</mat-form-field>
</td>
</ng-container>
...
</table>
</form>
Note that you need to use a unique row id in the name
to make sure that each row gets a unique control in the NgForm. If you don't have a unique column to use you can create a form inside the td
element.
Upvotes: 7
Reputation: 5267
<mat-error *ngIf="row.myField.length > 0"> My error message </mat-error>
You are missing the .length
of your row.myField > 0
Upvotes: -1