Skip to content

Commit

Permalink
feat(dynamic-form-group): Implement a non-observable error API
Browse files Browse the repository at this point in the history
- This simplifies the API by removing the need for the async pipe as a standard though it is still supported.
- Documentation and demos updated
  • Loading branch information
ScottMGerstl committed Jan 10, 2019
1 parent 14b5eae commit ac713c8
Show file tree
Hide file tree
Showing 9 changed files with 235 additions and 59 deletions.
102 changes: 94 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ npm i --save ngx-dynamic-form-builder
## Usage

app.module.ts
```js
```typescript
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { CompanyPanelComponent } from './company-panel.component';

Expand All @@ -44,7 +44,7 @@ export class AppModule {}
```

company.ts
```js
```typescript
import { Validate, IsNotEmpty } from 'class-validator';
import { plainToClassFromExist } from 'class-transformer';
import { TextLengthMore15 } from '../utils/custom-validators';
Expand Down Expand Up @@ -77,12 +77,12 @@ company-panel.component.html
```html
<form [formGroup]="form" novalidate>
<input formControlName="name" [placeholder]="strings.name">
<p *ngIf="(form?.customValidateErrors | async)?.name?.length">
Error: {{(form.customValidateErrors | async).name[0]}}
<p *ngIf="form?.formErrors?.name?.length">
Error: {{form.formErrors.name[0]}}
</p>
<p>Form status: {{ form.status | json }}</p>
<p *ngIf="!form.valid">
Custom validation errors: {{form.customValidateErrors|async|json}}
Form errors: {{form?.formErrors|json}}
</p>
<p *ngIf="savedItem">
Saved item: {{savedItem|json}}
Expand All @@ -94,7 +94,7 @@ company-panel.component.html
```

company-panel.component.ts
```js
```typescript
import { DynamicFormGroup, DynamicFormBuilder } from 'ngx-dynamic-form-builder';
import { Company } from './../../shared/models/company';
import { Input, Component } from '@angular/core';
Expand Down Expand Up @@ -145,7 +145,7 @@ export class CompanyPanelComponent {
```

custom-validators.ts
```css
```typescript
import {
ValidatorConstraintInterface, ValidatorConstraint
} from 'class-validator';
Expand All @@ -158,6 +158,92 @@ export class TextLengthMore15 implements ValidatorConstraintInterface {
}
```

## Observable Errors
the customValidateErrors property can be subscribed for cases in which your code should act on changes in errors

company-panel.component.html
```html
<form [formGroup]="form" novalidate>
<input formControlName="name" [placeholder]="strings.name">
<p *ngIf="(form?.customValidateErrors | async)?.name?.length">
Error: {{(form.customValidateErrors | async).name[0]}}
</p>
<p>Form status: {{ form.status | json }}</p>
<p *ngIf="!form.valid">
Observable validation errors: {{form.customValidateErrors|async|json}}
</p>
<p *ngIf="savedItem">
Saved item: {{savedItem|json}}
</p>
<button (click)="onLoadClick()">Load</button>
<button (click)="onClearClick()">Clear</button>
<button (click)="onSaveClick()" [disabled]="!form.valid">Save</button>
</form>
```

company-panel.component.ts
```typescript
import { DynamicFormGroup, DynamicFormBuilder } from 'ngx-dynamic-form-builder';
import { Company } from './../../shared/models/company';
import { Input, Component } from '@angular/core';
import { Validators } from '@angular/forms';
import { Subscription } from 'rxjs';

@Component({
selector: 'company-panel',
templateUrl: './company-panel.component.html'
})
export class CompanyPanelComponent implements onDestroy {

@Input()
form: DynamicFormGroup<Company>;
@Input()
item = new Company({
'id': 11,
'name': '123456789012345'
});
@Input()
strings = Company.strings;

fb = new DynamicFormBuilder();
savedItem: Company;

errorChangeSubscription: Subscription;

constructor() {
this.form = this.fb.group(Company, {
name: ''
});

this.errorChangeSubscription = this.form.customValidateErrors.subscribe((allErrors) => {
console.log('Errors changed': allErrors);
})
}
ngOnDestroy() {
if(this.errorChangeSubscription != null && this.errorChangeSubscription.closed === false) {
this.errorChangeSubscription.unsubscribe();
}
}
onLoadClick(): void {
this.savedItem = undefined;
this.form.object = this.item;
this.form.validateAllFormFields();
}
onClearClick(): void {
this.savedItem = undefined;
this.form.object = new Company();
this.form.validateAllFormFields();
}
onSaveClick(): void {
if (this.form.valid) {
this.savedItem = this.form.object;
} else {
this.form.validateAllFormFields();
}
}
}
```

## License

MIT
MIT
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
matInput
formControlName="name"
[placeholder]="strings.name">
<mat-error *ngIf="(form?.customValidateErrors | async)?.name?.length">
{{(form.customValidateErrors | async).name[0]}}
<mat-error *ngIf="form?.formErrors?.name?.length">
{{form?.formErrors.name[0]}}
</mat-error>
</mat-form-field>
<mat-form-field class="full-width">
Expand All @@ -16,14 +16,14 @@
formControlName="regionNum"
type="number"
[placeholder]="strings.regionNum">
<mat-error *ngIf="(form?.customValidateErrors | async)?.regionNum?.length">
{{(form.customValidateErrors | async).regionNum[0]}}
<mat-error *ngIf="form?.formErrors?.regionNum?.length">
{{form?.formErrors.regionNum[0]}}
</mat-error>
</mat-form-field>
<div class="full-width">
<p>Form status: {{ form.status | json }}</p>
<p *ngIf="!form.valid">
Custom validation errors: {{form.customValidateErrors|async|json}}
Form errors: {{form?.formErrors|json}}
</p>
<p *ngIf="savedItem">Saved item: {{savedItem|json}}</p>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ <h3>Group form</h3>
matInput
formControlName="username"
placeholder="Username">
<mat-error *ngIf="(form?.customValidateErrors | async)?.username?.length">
{{(form?.customValidateErrors | async).username[0]}}
<mat-error *ngIf="form?.formErrors?.username?.length">
{{form?.formErrors.username[0]}}
</mat-error>
</mat-form-field>
<mat-form-field class="full-width">
Expand All @@ -17,14 +17,14 @@ <h3>Group form</h3>
type="password"
formControlName="password"
placeholder="Password">
<mat-error *ngIf="(form?.customValidateErrors | async)?.password?.length">
{{(form.customValidateErrors | async).password[0]}}
<mat-error *ngIf="form?.formErrors?.password?.length">
{{form?.formErrors.password[0]}}
</mat-error>
</mat-form-field>
<div class="full-width">
<p>Form status: {{ form.status | json }}</p>
<p *ngIf="!form.valid">
Custom validation errors: {{form.customValidateErrors|async|json}}
Form errors: {{form?.formErrors|json}}
</p>
<p *ngIf="savedItem">Saved item: {{savedItem|json}}</p>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ <h3>Group form</h3>
matInput
formControlName="username"
placeholder="Username">
<mat-error *ngIf="(form?.customValidateErrors | async)?.username?.length">
{{(form?.customValidateErrors | async).username[0]}}
<mat-error *ngIf="form?.formErrors?.username?.length">
{{form?.formErrors.username[0]}}
</mat-error>
</mat-form-field>
<mat-form-field class="full-width">
Expand All @@ -17,8 +17,8 @@ <h3>Group form</h3>
type="password"
formControlName="password"
placeholder="Password">
<mat-error *ngIf="(form?.customValidateErrors | async)?.password?.length">
{{(form.customValidateErrors | async).password[0]}}
<mat-error *ngIf="form?.formErrors?.password?.length">
{{form?.formErrors.password[0]}}
</mat-error>
</mat-form-field>
<mat-form-field class="full-width">
Expand All @@ -27,8 +27,8 @@ <h3>Group form</h3>
type="email"
formControlName="email"
placeholder="Email">
<mat-error *ngIf="(form?.customValidateErrors | async)?.email?.length">
{{(form.customValidateErrors | async).email[0]}}
<mat-error *ngIf="form?.formErrors?.email?.length">
{{form?.formErrors.email[0]}}
</mat-error>
</mat-form-field>
<mat-form-field class="full-width">
Expand All @@ -41,8 +41,8 @@ <h3>Group form</h3>
date of birth is
<strong>required</strong>
</mat-error>
<mat-error *ngIf="(form?.customValidateErrors | async)?.dateOfBirth?.length">
{{(form.customValidateErrors | async).dateOfBirth[0]}}
<mat-error *ngIf="form?.formErrors?.dateOfBirth?.length">
{{form?.formErrors.dateOfBirth[0]}}
</mat-error>
</mat-form-field>
<div formGroupName="department">
Expand All @@ -52,8 +52,8 @@ <h3>Department of user</h3>
matInput
formControlName="name"
placeholder="Department name">
<mat-error *ngIf="(form?.customValidateErrors | async)?.department?.name?.length">
{{(form.customValidateErrors | async).department.name[0]}}
<mat-error *ngIf="form?.formErrors?.department?.name?.length">
{{form?.formErrors.department.name[0]}}
</mat-error>
</mat-form-field>
<div formGroupName="company">
Expand All @@ -63,8 +63,8 @@ <h3>Company of department</h3>
matInput
formControlName="name"
placeholder="Company name">
<mat-error *ngIf="(form?.customValidateErrors | async)?.department?.company?.name?.length">
{{(form.customValidateErrors | async).department.company.name[0]}}
<mat-error *ngIf="form?.formErrors?.department?.company?.name?.length">
{{form?.formErrors.department.company.name[0]}}
</mat-error>
</mat-form-field>
<mat-form-field class="full-width">
Expand All @@ -73,8 +73,8 @@ <h3>Company of department</h3>
formControlName="regionNum"
type="number"
placeholder="Company region num">
<mat-error *ngIf="(form?.customValidateErrors | async)?.department?.company?.regionNum?.length">
{{(form.customValidateErrors | async).department?.company?.regionNum[0]}}
<mat-error *ngIf="form?.formErrors?.department?.company?.regionNum?.length">
{{form?.formErrors.department?.company?.regionNum[0]}}
</mat-error>
</mat-form-field>
</div>
Expand All @@ -86,7 +86,7 @@ <h3>Company of department</h3>
<div class="full-width">
<p>Form status: {{ form.status | json }}</p>
<p *ngIf="!form.valid">
Custom validation errors: {{form.customValidateErrors|async|json}}
Form errors: {{form?.formErrors|json}}
</p>
<p *ngIf="savedItem">Saved item: {{savedItem|json}}</p>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<form
[formGroup]="form"
*ngIf="form?.customValidateErrors | async as errors"
*ngIf="form?.formErrors as errors"
novalidate>
<h3>Create project: step-1</h3>
<mat-form-field class="full-width">
Expand All @@ -20,7 +20,7 @@ <h3>Create project: step-1</h3>
<div class="full-width">
<p>Form status: {{ form.status | json }}</p>
<p *ngIf="!form.valid">
Custom validation errors: {{errors | json}}
Form errors: {{errors | json}}
</p>
</div>
<div class="full-width">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<form
[formGroup]="form"
*ngIf="form?.customValidateErrors | async as errors"
*ngIf="form?.formErrors as errors"
novalidate>
<h3>Create project: step-2</h3>
<mat-form-field
Expand Down Expand Up @@ -59,7 +59,7 @@ <h4>
<div class="full-width">
<p>Form status: {{ form.status | json }}</p>
<p *ngIf="!form.valid">
Custom validation errors: {{errors | json}}
Form errors: {{errors | json}}
</p>
</div>
<div class="full-width">
Expand Down
26 changes: 13 additions & 13 deletions apps/demo/src/app/panels/user-panel/user-panel.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ <h3>Group form</h3>
matInput
formControlName="username"
[placeholder]="strings.username">
<mat-error *ngIf="(form?.customValidateErrors | async)?.username?.length">
{{(form?.customValidateErrors | async).username.join('. ')}}
<mat-error *ngIf="form?.formErrors?.username?.length">
{{form?.formErrors.username.join('. ')}}
</mat-error>
</mat-form-field>
<mat-form-field class="full-width">
Expand All @@ -17,8 +17,8 @@ <h3>Group form</h3>
type="email"
formControlName="email"
[placeholder]="strings.email">
<mat-error *ngIf="(form?.customValidateErrors | async)?.email?.length">
{{(form.customValidateErrors | async).email.join('. ')}}
<mat-error *ngIf="form?.formErrors?.email?.length">
{{form?.formErrors.email.join('. ')}}
</mat-error>
</mat-form-field>
<mat-form-field class="full-width">
Expand All @@ -31,8 +31,8 @@ <h3>Group form</h3>
date of birth is
<strong>required</strong>
</mat-error>
<mat-error *ngIf="(form?.customValidateErrors | async)?.dateOfBirth?.length">
{{(form.customValidateErrors | async).dateOfBirth.join('. ')}}
<mat-error *ngIf="form?.formErrors?.dateOfBirth?.length">
{{form?.formErrors.dateOfBirth.join('. ')}}
</mat-error>
</mat-form-field>
<div formGroupName="department">
Expand All @@ -42,8 +42,8 @@ <h3>Department of user</h3>
matInput
formControlName="name"
[placeholder]="strings.department">
<mat-error *ngIf="(form?.customValidateErrors | async)?.department?.name?.length">
{{(form.customValidateErrors | async).department.name.join('. ')}}
<mat-error *ngIf="form?.formErrors?.department?.name?.length">
{{form?.formErrors.department.name.join('. ')}}
</mat-error>
</mat-form-field>
<div formGroupName="company">
Expand All @@ -53,8 +53,8 @@ <h3>Company of department</h3>
matInput
formControlName="name"
[placeholder]="departmentStrings.company">
<mat-error *ngIf="(form?.customValidateErrors | async)?.department?.company?.name?.length">
{{(form.customValidateErrors | async).department.company.name.join('. ')}}
<mat-error *ngIf="form?.formErrors?.department?.company?.name?.length">
{{form?.formErrors.department.company.name.join('. ')}}
</mat-error>
</mat-form-field>
<mat-form-field class="full-width">
Expand All @@ -63,8 +63,8 @@ <h3>Company of department</h3>
formControlName="regionNum"
type="number"
[placeholder]="companyStrings.regionNum">
<mat-error *ngIf="(form?.customValidateErrors | async)?.department?.company?.regionNum?.length">
{{(form.customValidateErrors | async).department.company.regionNum.join('. ')}}
<mat-error *ngIf="form?.formErrors?.department?.company?.regionNum?.length">
{{form?.formErrors.department.company.regionNum.join('. ')}}
</mat-error>
</mat-form-field>
</div>
Expand All @@ -76,7 +76,7 @@ <h3>Company of department</h3>
<div class="full-width">
<p>Form status: {{ form.status | json }}</p>
<p *ngIf="!form.valid">
Custom validation errors: {{form.customValidateErrors|async|json}}
Form errors: {{form.formErrors|json}}
</p>
<p *ngIf="savedItem">Saved item: {{savedItem|json}}</p>
</div>
Expand Down
Loading

0 comments on commit ac713c8

Please sign in to comment.