Making sure your tailor-made error solution is seamless!
The Error Tailor offers seamless handling of form errors, saving you the trouble of repeating the error boilerplate.It's fully customizable, so you can control when, where, and how each form field's errors are displayed.Sit back, relax, and let the Error Tailor do all the work!
Run ng add @ngneat/error-tailor
. This command updates the AppModule
, and adds the ErrorTailorModule
dependency:
@NgModule({
declarations: [AppComponent],
imports: [
ReactiveFormsModule,
ErrorTailorModule.forRoot({
errors: {
useValue: {
required: 'This field is required',
minlength: ({ requiredLength, actualLength }) =>
`Expect ${requiredLength} but got ${actualLength}`,
invalidAddress: error => `Address isn't valid`
}
}
})
],
bootstrap: [AppComponent]
})
export class AppModule {}
The errors
config property takes a partial Provider
, that should provide a HashMap<string | (err:any) => string>
that is an object with keys corresponding to the errors name that you want to handle, and values that can be a simple string, or function that return a string used as error message to be shown.Now the only thing you need to add is the errorTailor
directive to your form:
<form [formGroup]="form" errorTailor>
<div class="form-group">
<input class="form-control" formControlName="name" placeholder="Name" />
</div>
<section formGroupName="address">
<div class="form-group">
<input class="form-control" formControlName="city" placeholder="City" />
</div>
<div class="form-group">
<input class="form-control" formControlName="country" placeholder="Country" />
</div>
</section>
<div class="form-group">
<select formControlName="animal" class="form-control">
<option *ngFor="let option of options; index as index" [ngValue]="option">
{{ option.label }}
</option>
</select>
</div>
<button class="btn btn-success">Submit</button>
</form>
export class AppComponent {
form: FormGroup;
constructor(private builder: FormBuilder) {}
ngOnInit() {
this.form = this.builder.group({
name: ['', [Validators.required, Validators.minLength(3)]],
terms: [false, Validators.requiredTrue],
animal: [null, Validators.required],
address: this.builder.group(
{
city: ['', Validators.required],
country: ['']
},
{ validator: addressValidator }
)
});
}
}
The directive will show all errors for a form field automatically in two instances - on the field element blur and on form submit.
controlErrorsClass
- A custom class that'll be added to the control error component, a component that is added after the form field when an error needs to be displayed:<input class="form-control" formControlName="city"
placeholder="City" controlErrorsClass="my-class" />
controlErrorsTpl
- A custom error template to be used instead of the control error component's default view:<form errorTailor>
<ng-template let-error let-text="text" #tpl> {{ error | json }} {{ text }} </ng-template>
<div class="form-group">
<input class="form-control" ngModel required name="name" [controlErrorsTpl]="tpl" />
</div>
<button class="btn btn-success">Submit</button>
</form>
controlErrorAnchor
- A custom anchor
element for the control error component. The default anchor is the form field element:<div class="form-check form-group">
<input type="checkbox" formControlName="terms" id="check" [controlErrorAnchor]="anchor" />
<label class="form-check-label" for="check">
I agree to the terms and conditions
</label>
<ng-template controlErrorAnchor #anchor="controlErrorAnchor"></ng-template>
</div>
The custom anchor
can also be added as a directive, in which case it'll act as the anchor for any nested form fields:
<div class="form-check form-group" controlErrorAnchor>
<input type="checkbox" formControlName="terms" id="check" />
<label class="form-check-label" for="check">
I agree to the terms and conditions
</label>
</div>
controlErrors
- Additional errors to use for the form field, that aren't specified in the config:<input class="form-control" formControlName="country" placeholder="Country"
[controlErrors]="extraErrors" />
controlErrorsIgnore
- A custom attribute on a form field element to skip instantiating of a control error component on it.One typical case when to use it is radio buttons in the same radio group where it's enough to show only one error message and not all of them for each separate radio button.
<div class="form-group">
Communication language:
<input type="radio" name="languages" formControlName="languages"
value="en" id="en" [controlErrorAnchor]="anchorRadio" />
<label class="form-radio-label" for="en">English</label>
<input type="radio" name="languages" formControlName="languages"
value="de" id="de" controlErrorsIgnore />
<label class="form-radio-label" for="de">German</label>
<input type="radio" name="languages" formControlName="languages"
value="cs" id="cs" controlErrorsIgnore />
<label class="form-radio-label" for="cs">Czech</label>
<ng-template controlErrorAnchor #anchorRadio="controlErrorAnchor"></ng-template>
</div>
controlErrorsOnAsync
- To modify the error display behavior to not show errors from async validators, set the following input:<input [controlErrorsOnAsync]="false" formControlName="name" />
<input [controlErrorsOnBlur]="false" [controlErrorsOnAsync]="false" formControlName="name" />
controlErrorsOnBlur
- To modify the error display behavior to not show errors on blur, set the following input:<input [controlErrorsOnBlur]="false" formControlName="name" />
showError()
- Programmatic access to show a control error component (without a blur or a submit event). A validation error should still exist on that element. The key is the published exportAs
reference of errorTailor
to a directive instance of ControlErrorsDirective
and calling its public method showError()
.Syntax as @ViewChild('gdprErrorTailor', { static: true }) gdprErrorTailor: ControlErrorsDirective;
is used to get the reference and later call this.gdprErrorTailor.showError()
.
hideError()
- Programmatic access to hide an already shown control error component with the same logic as showError()
, so for example: this.gdprErrorTailor.hideError()
.<input type="checkbox" formControlName="gdpr" #gdprErrorTailor="errorTailor" />
The library adds a form-submitted
to the submitted form. You can use it to style your inputs:
.form-submitted input.ng-invalid,
.form-submitted select.ng-invalid {
border-color: #dc3545;
}
blurPredicate
- Elements that should listen the focusout
event. The default predicate is:{
blurPredicate(element) {
return element.tagName === 'INPUT' || element.tagName === 'SELECT';
}
}
controlErrorComponent
- Optional. Allows changing the default component that is used to renderthe errors. This component should implement the ControlErrorComponent
interface. If you only need toreplace the error component's template, you may derive it from the default component,DefaultControlErrorComponent
, and provide the requisite HTML template.
A common example is when using Ionic forms where each form field is wrapped in an ion-item
and errorsare best displayed as a sibling ion-item
of the field. Example below shows how this can be done usinga custom control error component.
For example:
// Custom error component that will replace the standard DefaultControlErrorComponent.
@Component({
template: `
<ion-item lines="none" class="ion-text-wrap" [class.hide-control]="hideError">
<ion-label color="danger" class="ion-no-margin ion-text-wrap" stacked>
{{ errorText }}
</ion-label>
</ion-item>
`
})
export class IonicControlErrorComponent extends DefaultControlErrorComponent {
}
@NgModule({
declarations: [AppComponent, IonicControlErrorComponent],
imports: [
ReactiveFormsModule,
ErrorTailorModule.forRoot({
errors: {
useValue: {
required: 'This field is required'
}
},
controlErrorComponent: IonicControlErrorComponent
})
],
bootstrap: [AppComponent]
})
export class AppModule {}
controlErrorComponentAnchorFn
- Optional. A hook function that allows the error component'sHTML element to be repositioned in the DOM. By default error components are inserted at thebottom of the field with error. If your UI layout dictates a different positioningscheme, you may use this hook.
Since this error element can be placed anywhere in the DOM, it also has to beremoved when the error component is destroyed. To provide for this, thisfunction should return a callback that will then be invoked when the error componentis destroyed. You may use this to remove the error HTML element that you insertedinto the DOM yourself.
Example below shows how the Ionic specific error component is repositioned in the DOMto suit Ionic's form layout. hostElem
is the HTML element for the form control anderrorElem
is the HTML element for the error component.
anchorIonicErrorComponent(hostElement: Element, errorElement: Element) {
hostElement.parentElement.insertAdjacentElement('afterend', errorElement);
return () => {
let errorNode = hostElement.parentElement.querySelector('custom-control-error');
if (errorNode) {
errorNode.remove();
}
};
}
@NgModule({
declarations: [AppComponent, IonicControlErrorComponent],
imports: [
ReactiveFormsModule,
ErrorTailorModule.forRoot({
errors: {
useValue: {
required: 'This field is required'
}
},
controlErrorComponent: IonicControlErrorComponent,
controlErrorComponentAnchorFn: anchorIonicErrorComponent
})
],
bootstrap: [AppComponent]
})
export class AppModule {}
controlErrorsOnBlur
- To modify the error display behavior and show the errors on submission alone, set the following input:
<input [controlErrorsOnBlur]="false" formControlName="name" />
Here's how to support i18n:
import { TranslocoService } from '@ngneat/transloco';
@NgModule({
declarations: [AppComponent],
imports: [
ErrorTailorModule.forRoot({
errors: {
useFactory(service: TranslocoService) {
return {
required: error => service.translate('errors.required')
};
},
deps: [TranslocoService]
}
})
],
bootstrap: [AppComponent]
})
export class AppModule {}
Here's a default style you can use for the error component:
.control-error {
width: 100%;
margin-top: 0.25rem;
font-size: 12px;
color: #dc3545;
}
Thanks goes to these wonderful people (emoji key):
Netanel Basal |
Toni Villena |
Inbal Sinai |
Daniele Morosinotto |
Ryan Hutchison |
Miloš Lapiš |
Hari Mahadevan |
This project follows the all-contributors specification. Contributions of any kind welcome!
Icon made by Nhor Phai from www.flaticon.com
问题 There are two databases are configured in my project, the one is running on my local machine and other is running on Remote server. I don't have any issue accessing the remote DB server but getting
最近将Swift4 升级到最新的 Swift4.2,发现了一些问题,其中就包括 调用相册及拍照 UIImagePickerControllerDelegate 委托不执行,导致获取不到选中的图片并且报如下错误: [discovery] errors encountered while discovering extensions: Error Domain=PlugInKit Code
2 After lots of attempt,the solution is delete user mysql.infoschema first and then do vamshi’s steps: Create user: mysql> CREATE USER ‘mysql.infoschema’@‘localhost’ IDENTIFIED BY ‘password’; Query OK
stm32的makefile编译时发生错误: startup_stm32f10x_hd.S: Assembler messages: startup_stm32f10x_hd.S:1: Error: junk at end of line, first unrecognized character is `*' startup_stm32f10x_hd.S:2: Error: junk at en
打印PHP错误日志,相当于PHP的trigger_error函数。此函数与echo很相似,唯一不同的插入了第一个参数,来接受错误等级,如E_ERROR或E_WARNING。 PHPX_FUNCTION(cpp_test) { error(E_ERROR, "error: a=%d, b=%f, c=%s.\n", args[0].toInt(), args[1].toFloat(), ar
介绍 (Introduction) java.lang.reflect Error包含在反射操作期间可能发生的错误。 错误摘要 Sr.No. 错误和描述 1 GenericSignatureFormatError 当需要解释类型,方法或构造函数的通用签名信息的反射方法遇到语法错误的签名属性时抛出。
介绍 (Introduction) java.util.zip Error包含在zip/unzip操作期间可能发生的错误。 接口概要 (Interface Summary) Sr.No. 错误和描述 1 ZipError 表示发生了不可恢复的错误。
error 创建一个只有 error 事件的 Observable error 操作符将创建一个 Observable,这个 Observable 只会产生一个 error 事件。 演示 创建一个只有 error 事件的 Observable: let error: Error = ... let id = Observable<Int>.error(error) 它相当于: let error
AndroidStudio已更新所有内容都已更新我认为错误来自这里C:\Users\lanet\AppData\Local\Android\sdk\tools\bin\sdkmanager,因为当我查看时无法创建此文件夹,我正在等待建议。谢谢 C:\用户\lanet [!] Android工具链-为Android设备开发(Android SDK版本29.0.3) [√]Android Studio
当我们在开发某些东西时,经常会需要我们自己的 error 类来反映在我们的任务中可能出错的特定任务。对于网络操作中的 error,我们需要 HttpError,对于数据库操作中的 error,我们需要 DbError,对于搜索操作中的 error,我们需要 NotFoundError,等等。 我们自定义的 error 应该支持基本的 error 的属性,例如 message,name,并且最好还有