All Projects → ngneat → Error Tailor

ngneat / Error Tailor

Licence: mit
🦄 Making sure your tailor-made error solution is seamless!

Programming Languages

typescript
32286 projects

Projects that are alternatives of or similar to Error Tailor

Normform
Normform: A tiny CSS plugin to make your web forms beautiful again
Stars: ✭ 78 (-74.26%)
Mutual labels:  errors, form
Log
📗 Simple, configurable and scalable Structured Logging for Go.
Stars: ✭ 276 (-8.91%)
Mutual labels:  errors
bugsnag-symfony
Bugsnag notifier for the Symfony PHP framework. Monitor and report errors in your Symfony apps.
Stars: ✭ 42 (-86.14%)
Mutual labels:  errors
Laraform
Reactive Form Builder for Vue.js with Laravel Support
Stars: ✭ 259 (-14.52%)
Mutual labels:  form
vue-qs-form
Vue quick step form, Vue快速问卷表单
Stars: ✭ 16 (-94.72%)
Mutual labels:  form
Form Create
🔥🔥🔥 强大的动态表单生成器|form-create is a form generation component that can generate dynamic rendering, data collection, verification and submission functions through JSON.
Stars: ✭ 3,698 (+1120.46%)
Mutual labels:  form
grav-plugin-form
Grav Form Plugin
Stars: ✭ 48 (-84.16%)
Mutual labels:  form
Validate
A simple jQuery plugin to validate forms.
Stars: ✭ 298 (-1.65%)
Mutual labels:  form
Throw.js
HTTP Error collection to use in your next REST API.
Stars: ✭ 272 (-10.23%)
Mutual labels:  errors
Vue Form Generator
📋 A schema-based form generator component for Vue.js
Stars: ✭ 2,853 (+841.58%)
Mutual labels:  form
periskop
Exception Monitoring Service
Stars: ✭ 128 (-57.76%)
Mutual labels:  errors
tsfeatures
Calculates various features from time series data. Python implementation of the R package tsfeatures.
Stars: ✭ 87 (-71.29%)
Mutual labels:  errors
Validify
Simple-as-possible React form validation
Stars: ✭ 271 (-10.56%)
Mutual labels:  form
go-errors
Flexible, general-purpose error handling for Go.
Stars: ✭ 17 (-94.39%)
Mutual labels:  errors
Schema Plugin Flow
A highly extensible JavaScript library, abbreviated as Sifo. 一个高扩展性、可二开的插件式前端开发框架
Stars: ✭ 288 (-4.95%)
Mutual labels:  form
ono
Wrap errors without losing the original message, stack trace, or properties
Stars: ✭ 87 (-71.29%)
Mutual labels:  errors
fform
Flexibile and extendable form builder with constructor
Stars: ✭ 26 (-91.42%)
Mutual labels:  form
Formvuelar
Vue form components with server-side validation in mind
Stars: ✭ 263 (-13.2%)
Mutual labels:  form
Waitme
jquery plugin for easy creating loading css3/images animations
Stars: ✭ 302 (-0.33%)
Mutual labels:  form
Vue Form Builder
Super Form Builder built on top of Vue with Drag & Drop functionality, savable-form-schema and easy to maintain/upgrade your form.
Stars: ✭ 292 (-3.63%)
Mutual labels:  form


Making sure your tailor-made error solution is seamless!

MIT commitizen PRs styled with prettier All Contributors ngneat spectator

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!

Buy Me A Coffee

Getting Started

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.

Inputs

  • 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: &nbsp;
  <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" />
  • To modify the error display behavior and show the errors on submission alone, set the following input:
<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" />

Methods

  • 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" />

CSS Styling

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;
}

Config

  • 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 render the errors. This component should implement the ControlErrorComponent interface. If you only need to replace 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 errors are best displayed as a sibling ion-item of the field. Example below shows how this can be done using a 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's HTML element to be repositioned in the DOM. By default error components are inserted at the bottom of the field with error. If your UI layout dictates a different positioning scheme, you may use this hook.

    Since this error element can be placed anywhere in the DOM, it also has to be removed when the error component is destroyed. To provide for this, this function should return a callback that will then be invoked when the error component is destroyed. You may use this to remove the error HTML element that you inserted into the DOM yourself.

    Example below shows how the Ionic specific error component is repositioned in the DOM to suit Ionic's form layout. hostElem is the HTML element for the form control and errorElem 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" />

Recipes

I18n Example

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 {}

Control Error Style

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;
}

Contributors ✨

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

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].