Add model driven form form 'forms' app
parent
17c89875dc
commit
1d9c108bfb
|
@ -5,9 +5,9 @@
|
||||||
"title": "Ersten Prototyp mit Angular 2.0 entwickeln",
|
"title": "Ersten Prototyp mit Angular 2.0 entwickeln",
|
||||||
"description": "Der Prototyp soll zeigen, wie Routing und HTTP-Anbindung umgesetzt werden können.",
|
"description": "Der Prototyp soll zeigen, wie Routing und HTTP-Anbindung umgesetzt werden können.",
|
||||||
"tags": [],
|
"tags": [],
|
||||||
"state": "IN_PROGRESS",
|
"state": "BACKLOG",
|
||||||
"assignee": {
|
"assignee": {
|
||||||
"name": "Christoph Höller",
|
"name": "Christoph Höllers",
|
||||||
"email": ""
|
"email": ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -40,18 +40,18 @@
|
||||||
"change_settings": true
|
"change_settings": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 302,
|
"id": 302,
|
||||||
"name": "user_edit",
|
"name": "user_edit",
|
||||||
"password": "ea847988ba59727dbf4e34ee75726dc3",
|
"password": "ea847988ba59727dbf4e34ee75726dc3",
|
||||||
"edit_tasks": true,
|
"edit_tasks": true,
|
||||||
"change_settings": false
|
"change_settings": false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id" : 303,
|
"id": 303,
|
||||||
"name": "user",
|
"name": "user",
|
||||||
"password": "5ebe2294ecd0e0f08eab7690d2a6ee69",
|
"password": "5ebe2294ecd0e0f08eab7690d2a6ee69",
|
||||||
"edit_tasks": false,
|
"edit_tasks": false,
|
||||||
"change_settings": false
|
"change_settings": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -31,6 +31,9 @@
|
||||||
<li routerLinkActive="active">
|
<li routerLinkActive="active">
|
||||||
<a routerLink='/blog' class="link">Blog</a>
|
<a routerLink='/blog' class="link">Blog</a>
|
||||||
</li>
|
</li>
|
||||||
|
<li routerLinkActive="active">
|
||||||
|
<a routerLink='/model-form' class="link">Model Form</a>
|
||||||
|
</li>
|
||||||
<!--
|
<!--
|
||||||
<li routerLinkActive="active">
|
<li routerLinkActive="active">
|
||||||
<a routerLink='/tasks/new' class="link">Neue Aufgabe anlegen</a>
|
<a routerLink='/tasks/new' class="link">Neue Aufgabe anlegen</a>
|
||||||
|
|
|
@ -16,6 +16,8 @@ import {SOCKET_IO, AUTH_ENABLED} from './app.tokens';
|
||||||
import {environment} from '../environments/environment';
|
import {environment} from '../environments/environment';
|
||||||
import {mockIO} from './mocks/mock-socket';
|
import {mockIO} from './mocks/mock-socket';
|
||||||
import {TaskItemComponent} from './tasks/task-list/task-item.component';
|
import {TaskItemComponent} from './tasks/task-list/task-item.component';
|
||||||
|
import {UserService} from "./services/user-service/user.service";
|
||||||
|
import {ShowErrorComponentModelDriven} from "./show-error/show-error-model-driven.component";
|
||||||
|
|
||||||
export function socketIoFactory() {
|
export function socketIoFactory() {
|
||||||
if (environment.e2eMode) {
|
if (environment.e2eMode) {
|
||||||
|
@ -29,6 +31,7 @@ const enableAuthentication = !environment.e2eMode;
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [BrowserModule, FormsModule, ReactiveFormsModule, appRouting, HttpModule],
|
imports: [BrowserModule, FormsModule, ReactiveFormsModule, appRouting, HttpModule],
|
||||||
providers: [LoginService,
|
providers: [LoginService,
|
||||||
|
UserService,
|
||||||
UserStore,
|
UserStore,
|
||||||
TaskService,
|
TaskService,
|
||||||
TaskStore,
|
TaskStore,
|
||||||
|
@ -41,6 +44,7 @@ const enableAuthentication = !environment.e2eMode;
|
||||||
routingComponents,
|
routingComponents,
|
||||||
TaskItemComponent,
|
TaskItemComponent,
|
||||||
ShowErrorComponent,
|
ShowErrorComponent,
|
||||||
|
ShowErrorComponentModelDriven,
|
||||||
APPLICATION_VALIDATORS],
|
APPLICATION_VALIDATORS],
|
||||||
bootstrap: [AppComponent]
|
bootstrap: [AppComponent]
|
||||||
})
|
})
|
||||||
|
|
|
@ -10,15 +10,16 @@ import {tasksRoutes, tasksRoutingComponents, tasksRoutingProviders} from './task
|
||||||
import {RxDemoComponent} from './rxdemo/rxdemo.component';
|
import {RxDemoComponent} from './rxdemo/rxdemo.component';
|
||||||
import {LoginGuard} from './login/login.guard';
|
import {LoginGuard} from './login/login.guard';
|
||||||
import {blogRoutingComponents} from "./blog/blog.routing";
|
import {blogRoutingComponents} from "./blog/blog.routing";
|
||||||
|
import {ModelDrivenFormComponent} from "./model-driven-form/model-driven-form.component";
|
||||||
|
|
||||||
export const appRoutes: Routes = [
|
export const appRoutes: Routes = [
|
||||||
{path: 'dashboard', component: DashboardComponent, data: {title: 'Startseite'}},
|
{path: 'dashboard', component: DashboardComponent, data: {title: 'Startseite'}},
|
||||||
{path: '', redirectTo: '/dashboard', pathMatch: 'full'},
|
{path: '', redirectTo: '/dashboard', pathMatch: 'full'},
|
||||||
{path: 'settings', component: SettingsComponent, data: { title: 'Einstellungen' },
|
{path: 'settings', component: SettingsComponent, data: { title: 'Einstellungen' }},
|
||||||
},
|
|
||||||
{path: 'about', component: AboutComponent, data: {title: 'Über uns'}},
|
{path: 'about', component: AboutComponent, data: {title: 'Über uns'}},
|
||||||
{path: 'rxdemo', component: RxDemoComponent, data: {title: 'RxJS Demo'}},
|
{path: 'rxdemo', component: RxDemoComponent, data: {title: 'RxJS Demo'}},
|
||||||
{path: 'blog', component: BlogComponent, data: {title: 'Blog'}},
|
{path: 'blog', component: BlogComponent, data: {title: 'Blog'}},
|
||||||
|
{path: 'model-form', component: ModelDrivenFormComponent, data: { title: 'Model Driven Task Form' }},
|
||||||
|
|
||||||
{path: 'login', component: LoginComponent},
|
{path: 'login', component: LoginComponent},
|
||||||
|
|
||||||
|
@ -34,7 +35,7 @@ export const appRoutes: Routes = [
|
||||||
export const appRouting = RouterModule.forRoot(appRoutes);
|
export const appRouting = RouterModule.forRoot(appRoutes);
|
||||||
|
|
||||||
export const routingComponents = [DashboardComponent, SettingsComponent, AboutComponent, LoginComponent, NotFoundComponent,
|
export const routingComponents = [DashboardComponent, SettingsComponent, AboutComponent, LoginComponent, NotFoundComponent,
|
||||||
RxDemoComponent, ...blogRoutingComponents, ...tasksRoutingComponents];
|
RxDemoComponent, ModelDrivenFormComponent, ...blogRoutingComponents, ...tasksRoutingComponents];
|
||||||
|
|
||||||
export const routingProviders = [LoginGuard,
|
export const routingProviders = [LoginGuard,
|
||||||
...tasksRoutingProviders];
|
...tasksRoutingProviders];
|
||||||
|
|
|
@ -2,8 +2,8 @@ import {TestBed} from "@angular/core/testing";
|
||||||
import {LoginComponent} from "./login.component";
|
import {LoginComponent} from "./login.component";
|
||||||
import {RouterTestingModule} from "@angular/router/testing";
|
import {RouterTestingModule} from "@angular/router/testing";
|
||||||
import {LoginService} from "../services/login-service/login-service";
|
import {LoginService} from "../services/login-service/login-service";
|
||||||
import {MockLoginService} from "../mocks/mock-login-service.spec";
|
|
||||||
import {FormsModule} from "@angular/forms";
|
import {FormsModule} from "@angular/forms";
|
||||||
|
import {MockLoginService} from "../mocks/mock-login-service.spec";
|
||||||
import Spy = jasmine.Spy;
|
import Spy = jasmine.Spy;
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,8 +32,7 @@ describe('Login Component Template Driven Form Test with Spy', () => {
|
||||||
|
|
||||||
// Login ausfuellen und absenden
|
// Login ausfuellen und absenden
|
||||||
loginFixture.whenStable().then(() => {
|
loginFixture.whenStable().then(() => {
|
||||||
// Spy anmelden
|
// Spy anmelden, die eigentliche Methode wird nicht mehr aufgerufen
|
||||||
// sobald Spy angemeldet ist, wird der eigentliche Methodenrumpf nicht mehr aufgerufen
|
|
||||||
const spy = spyOn(loginInstance, 'login');
|
const spy = spyOn(loginInstance, 'login');
|
||||||
|
|
||||||
// Formular Eingabe
|
// Formular Eingabe
|
||||||
|
|
|
@ -0,0 +1,87 @@
|
||||||
|
<h2 *ngIf="!task.id">Neue Aufgabe anlegen</h2>
|
||||||
|
<h2 *ngIf="task.id">Aufgabe bearbeiten</h2>
|
||||||
|
|
||||||
|
<form novalidate [formGroup]="taskForm"
|
||||||
|
(ngSubmit)="saveTask(taskForm.value)">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Titel</label>
|
||||||
|
<input class="form-control" formControlName="title"/>
|
||||||
|
</div>
|
||||||
|
<pjm-show-error text="Titel" path="title"></pjm-show-error>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Beschreibung</label>
|
||||||
|
<textarea class="form-control" formControlName="description">
|
||||||
|
</textarea>
|
||||||
|
<pjm-show-error text="Beschreibung" path="description"></pjm-show-error>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<label>Tags</label>
|
||||||
|
<div formArrayName="tags">
|
||||||
|
<div *ngFor="let tag of tagsArray.controls; let i = index">
|
||||||
|
<div class="tag-controls" [formGroupName]="i">
|
||||||
|
<input class="form-control" formControlName="label">
|
||||||
|
<button class="btn btn-danger" (click)="removeTag(i)">
|
||||||
|
Tag entfernen
|
||||||
|
</button>
|
||||||
|
<pjm-show-error text="Ein Tag" path="tags.{{i}}.label"></pjm-show-error>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<button class="btn btn-success" (click)="addTag()"> + </button>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Status</label>
|
||||||
|
<select formControlName="state" class="form-control">
|
||||||
|
<option *ngFor="let state of model.states" [value]="state">
|
||||||
|
{{model.stateTexts[state]}}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="checkbox">
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" formControlName="favorite">
|
||||||
|
Zu Favoriten hinzufügen
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<h4>Zuständiger</h4>
|
||||||
|
<div formGroupName="assignee">
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Name</label>
|
||||||
|
<input type="text" class="form-control"
|
||||||
|
formControlName="name"/>
|
||||||
|
<pjm-show-error path="assignee/name" text="Name"></pjm-show-error>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>E-Mail</label>
|
||||||
|
<input type="text" class="form-control"
|
||||||
|
formControlName="email"/>
|
||||||
|
<pjm-show-error path="assignee.email"></pjm-show-error>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div *ngIf="taskForm.hasError('assigneeRequired')"
|
||||||
|
class="alert alert-danger">
|
||||||
|
Der Task befindet sich nicht mehr im Backlog <br>
|
||||||
|
Bitte geben Sie einen Zuständigen an.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit"
|
||||||
|
class="btn btn-default"
|
||||||
|
[disabled]="!taskForm.valid">
|
||||||
|
Aufgabe speichern
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<button (click)="loadTask(1)"
|
||||||
|
class="btn btn-default">
|
||||||
|
Task 1 laden
|
||||||
|
</button>
|
||||||
|
<button (click)="loadTask(2)"
|
||||||
|
class="btn btn-default">
|
||||||
|
Task 2 laden
|
||||||
|
</button>
|
|
@ -0,0 +1,66 @@
|
||||||
|
import {ReactiveFormsModule} from '@angular/forms';
|
||||||
|
import {TestBed, ComponentFixture} from '@angular/core/testing';
|
||||||
|
import {ModelDrivenFormComponent} from './model-driven-form.component';
|
||||||
|
import {TaskService} from '../services/task-service/task.service';
|
||||||
|
import {UserService} from '../services/user-service/user.service';
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [ReactiveFormsModule],
|
||||||
|
providers: [TaskService, UserService],
|
||||||
|
declarations: [ModelDrivenFormComponent]
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('Model Driven Form', () => {
|
||||||
|
it('should validate the title directly', () => {
|
||||||
|
|
||||||
|
const fixture = TestBed.createComponent(ModelDrivenFormComponent);
|
||||||
|
const form = fixture.componentInstance.taskForm;
|
||||||
|
|
||||||
|
const titleControl = form.get('title');
|
||||||
|
expect(titleControl.errors['required']).toBeTruthy(); // Cannot read property 'errors' of undefined
|
||||||
|
|
||||||
|
titleControl.setValue('Task');
|
||||||
|
expect(titleControl.errors['required']).toBeUndefined();
|
||||||
|
const minError = {requiredLength: 5, actualLength: 4};
|
||||||
|
|
||||||
|
expect(titleControl.errors['minlength']).toEqual(minError);
|
||||||
|
titleControl.setValue('Task 1');
|
||||||
|
expect(titleControl.errors).toBeNull();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
it('should validate the whole form ', fakeAsync(() => {
|
||||||
|
|
||||||
|
const fixture = TestBed.createComponent(ModelDrivenFormComponent);
|
||||||
|
|
||||||
|
const form = fixture.componentInstance.taskForm;
|
||||||
|
|
||||||
|
console.log(form.patchValue({title: 'Task123'}));
|
||||||
|
fixture.detectChanges();
|
||||||
|
tick(5000);
|
||||||
|
fixture.detectChanges();
|
||||||
|
tick(50000);
|
||||||
|
console.log(form.valid)
|
||||||
|
|
||||||
|
|
||||||
|
}));
|
||||||
|
|
||||||
|
it('should be able to work with Observable.delay', fakeAsync(() => {
|
||||||
|
const actuallyDone=false;
|
||||||
|
const source = Observable.of(true).delay(10);
|
||||||
|
source.subscribe(
|
||||||
|
val => {
|
||||||
|
actuallyDone = true;
|
||||||
|
},
|
||||||
|
err => fail(err)
|
||||||
|
);
|
||||||
|
tick(100);
|
||||||
|
expect(actuallyDone).toBeTruthy(); // Expected false to be truthy.
|
||||||
|
|
||||||
|
discardPeriodicTasks();
|
||||||
|
}));
|
||||||
|
*/
|
||||||
|
);
|
|
@ -0,0 +1,117 @@
|
||||||
|
import {Component} from '@angular/core';
|
||||||
|
import {FormGroup, FormArray, FormControl, FormBuilder, Validators} from '@angular/forms';
|
||||||
|
import {Task, createInitialTask} from '../models/model-interfaces';
|
||||||
|
import * as model from '../models/model-interfaces';
|
||||||
|
import {ifNotBacklogThanAssignee, emailValidator, UserExistsValidatorDirective} from '../models/app-validators';
|
||||||
|
import {TaskService} from '../services/task-service/task.service';
|
||||||
|
import {UserService} from '../services/user-service/user.service';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'pjm-model-driven-form',
|
||||||
|
templateUrl: './model-driven-form.component.html'
|
||||||
|
})
|
||||||
|
export class ModelDrivenFormComponent {
|
||||||
|
|
||||||
|
model = model;
|
||||||
|
task: Task = createInitialTask();
|
||||||
|
|
||||||
|
taskForm: FormGroup;
|
||||||
|
tagsArray: FormArray;
|
||||||
|
|
||||||
|
constructor(private taskService: TaskService,
|
||||||
|
private userService: UserService,
|
||||||
|
fb: FormBuilder) {
|
||||||
|
this.taskForm = fb.group({
|
||||||
|
title: ['', [Validators.required, Validators.minLength(5)]],
|
||||||
|
description: ['', Validators.maxLength(2000)],
|
||||||
|
favorite: [false],
|
||||||
|
state: ['BACKLOG'],
|
||||||
|
tags: fb.array([
|
||||||
|
this.createTagControl()
|
||||||
|
]),
|
||||||
|
assignee: fb.group({
|
||||||
|
name: ['', null, this.userExistsValidatorReused],
|
||||||
|
email: ['', emailValidator],
|
||||||
|
})
|
||||||
|
}, {validator: ifNotBacklogThanAssignee});
|
||||||
|
|
||||||
|
this.taskForm.valueChanges.subscribe((value) => {
|
||||||
|
Object.assign(this.task, value);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.tagsArray = <FormArray>this.taskForm.controls['tags'];
|
||||||
|
|
||||||
|
/*
|
||||||
|
this.taskForm = new FormGroup({
|
||||||
|
title: new FormControl(''),
|
||||||
|
description: new FormControl(''),
|
||||||
|
favorite: new FormControl(false),
|
||||||
|
state: new FormControl('BACKLOG'),
|
||||||
|
tags: new FormArray([
|
||||||
|
new FormGroup({
|
||||||
|
label: new FormControl('')
|
||||||
|
})
|
||||||
|
]),
|
||||||
|
assignee: new FormGroup({
|
||||||
|
name: new FormControl(''),
|
||||||
|
email: new FormControl('')
|
||||||
|
}),
|
||||||
|
});*/
|
||||||
|
}
|
||||||
|
|
||||||
|
private createTagControl(): FormGroup {
|
||||||
|
return new FormGroup({
|
||||||
|
label: new FormControl('', Validators.minLength(3))
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addTag() {
|
||||||
|
this.tagsArray.push(this.createTagControl());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
removeTag(i: number) {
|
||||||
|
this.tagsArray.removeAt(i);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
saveTask(value: any) {
|
||||||
|
console.log(value);
|
||||||
|
Object.assign(this.task, value);
|
||||||
|
this.taskService.saveTask(this.task);
|
||||||
|
}
|
||||||
|
|
||||||
|
loadTask(id: number) {
|
||||||
|
const task : Task = this.taskService.getTask(id);
|
||||||
|
this.adjustTagsArray(task.tags);
|
||||||
|
this.taskForm.patchValue(task);
|
||||||
|
this.task = task;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private adjustTagsArray(tags: any[]) {
|
||||||
|
const tagCount = tags ? tags.length : 0;
|
||||||
|
while (tagCount > this.tagsArray.controls.length) {
|
||||||
|
this.addTag();
|
||||||
|
}
|
||||||
|
while (tagCount < this.tagsArray.controls.length) {
|
||||||
|
this.removeTag(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
userExistsValidator = (control) => {
|
||||||
|
return this.userService.checkUserExists(control.value)
|
||||||
|
.map(checkResult => {
|
||||||
|
return (checkResult === false) ? {userNotFound: true} : null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
userExistsValidatorReused = (control) => {
|
||||||
|
const validator = new UserExistsValidatorDirective(this.userService);
|
||||||
|
return validator.validate(control);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
import {ModelDrivenFormComponent} from "./model-driven-form.component";
|
||||||
|
|
||||||
|
export const modelDrivenFormRoutingComponent = [ModelDrivenFormComponent];
|
|
@ -2,8 +2,10 @@ import {Directive, forwardRef} from '@angular/core';
|
||||||
import {
|
import {
|
||||||
FormControl,
|
FormControl,
|
||||||
AbstractControl,
|
AbstractControl,
|
||||||
NG_VALIDATORS
|
NG_VALIDATORS, NG_ASYNC_VALIDATORS
|
||||||
} from '@angular/forms';
|
} from '@angular/forms';
|
||||||
|
import {UserService} from "../services/user-service/user.service";
|
||||||
|
import {Observable} from "rxjs";
|
||||||
|
|
||||||
export function asyncIfNotBacklogThenAssignee(control): Promise<any> {
|
export function asyncIfNotBacklogThenAssignee(control): Promise<any> {
|
||||||
const promise = new Promise((resolve, reject) => {
|
const promise = new Promise((resolve, reject) => {
|
||||||
|
@ -82,6 +84,27 @@ export function emailValidator2(control): {[key: string]: any} {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Directive({
|
||||||
|
selector: '[pjmUserExistsValidator]',
|
||||||
|
providers: [
|
||||||
|
{
|
||||||
|
provide: NG_ASYNC_VALIDATORS,
|
||||||
|
useExisting: forwardRef(() => UserExistsValidatorDirective), multi: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
export class UserExistsValidatorDirective {
|
||||||
|
constructor(private userService: UserService) {
|
||||||
|
}
|
||||||
|
|
||||||
|
validate(control: AbstractControl): Observable<any> {
|
||||||
|
return this.userService.checkUserExists(control.value)
|
||||||
|
.map(userExists => {
|
||||||
|
return (userExists === false) ? {userNotFound: true} :null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Directive({
|
@Directive({
|
||||||
selector: '[emailValidator]',
|
selector: '[emailValidator]',
|
||||||
providers: [
|
providers: [
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
import {Observable} from 'rxjs/Observable';
|
||||||
|
export class UserService {
|
||||||
|
checkUserExists(name: string): Observable<boolean> {
|
||||||
|
const result = name == null || name.toLowerCase() !== 'johnny incognito';
|
||||||
|
return Observable.of(result).delay(250);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
import {Component, Input, Optional} from '@angular/core';
|
||||||
|
import {NgForm, FormGroup, FormGroupDirective} from '@angular/forms';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'pjm-show-error',
|
||||||
|
template: `
|
||||||
|
<div *ngIf="errorMessages" class="alert alert-danger">
|
||||||
|
<div *ngFor="let errorMessage of errorMessages">
|
||||||
|
{{errorMessage}}
|
||||||
|
</div>
|
||||||
|
</div>` })
|
||||||
|
export class ShowErrorComponentModelDriven {
|
||||||
|
|
||||||
|
@Input('path') path;
|
||||||
|
@Input('text') displayName = '';
|
||||||
|
|
||||||
|
constructor(@Optional() private ngForm: NgForm,
|
||||||
|
@Optional() private formGroup: FormGroupDirective) {
|
||||||
|
}
|
||||||
|
|
||||||
|
get errorMessages(): string[] {
|
||||||
|
let form: FormGroup;
|
||||||
|
if (this.ngForm) {
|
||||||
|
form = this.ngForm.form;
|
||||||
|
} else {
|
||||||
|
form = this.formGroup.form;
|
||||||
|
}
|
||||||
|
const control = form.get(this.path);
|
||||||
|
const messages = [];
|
||||||
|
if (!control || !(control.touched) || !control.errors) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (const code in control.errors) {
|
||||||
|
if (control.errors.hasOwnProperty(code)) {
|
||||||
|
const error = control.errors[code];
|
||||||
|
let message = '';
|
||||||
|
switch (code) {
|
||||||
|
case 'required':
|
||||||
|
message = `${this.displayName} ist ein Pflichtfeld`;
|
||||||
|
break;
|
||||||
|
case 'minlength':
|
||||||
|
message = `${this.displayName} muss mindestens ${error.requiredLength} Zeichen enthalten`;
|
||||||
|
break;
|
||||||
|
case 'maxlength':
|
||||||
|
message = `${this.displayName} darf maximal ${error.requiredLength} Zeichen enthalten`;
|
||||||
|
break;
|
||||||
|
case 'invalidEMail':
|
||||||
|
message = `Bitte geben Sie eine gültige E-Mail-Adresse an`;
|
||||||
|
break;
|
||||||
|
case 'userNotFound':
|
||||||
|
message = `Der eingetragene Benutzer existiert nicht.`;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
message = `${name} ist nicht valide`;
|
||||||
|
}
|
||||||
|
messages.push(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return messages;
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,6 @@ import {EditTaskComponent} from './edit-task/edit-task.component';
|
||||||
import {EditTaskGuard} from './edit-task/edit-task.guard';
|
import {EditTaskGuard} from './edit-task/edit-task.guard';
|
||||||
import {TaskOverviewComponent} from './task-overview/task-overview.component';
|
import {TaskOverviewComponent} from './task-overview/task-overview.component';
|
||||||
import {TasksComponent} from './tasks.component';
|
import {TasksComponent} from './tasks.component';
|
||||||
import {LoginGuard} from '../login/login.guard';
|
|
||||||
|
|
||||||
export const tasksRoutes: Routes = [{
|
export const tasksRoutes: Routes = [{
|
||||||
path: '', component: TasksComponent,
|
path: '', component: TasksComponent,
|
||||||
|
|
Loading…
Reference in New Issue