Client: reactive forms

pull/10/head
Chocobozzz 2016-09-09 22:16:51 +02:00
parent ab32b0fc80
commit 4b2f33f3c6
19 changed files with 282 additions and 128 deletions

View File

@ -3,25 +3,25 @@
<div *ngIf="information" class="alert alert-success">{{ information }}</div> <div *ngIf="information" class="alert alert-success">{{ information }}</div>
<div *ngIf="error" class="alert alert-danger">{{ error }}</div> <div *ngIf="error" class="alert alert-danger">{{ error }}</div>
<form role="form" (ngSubmit)="changePassword()" [formGroup]="changePasswordForm"> <form role="form" (ngSubmit)="changePassword()" [formGroup]="form">
<div class="form-group"> <div class="form-group">
<label for="new-password">New password</label> <label for="new-password">New password</label>
<input <input
type="password" class="form-control" name="new-password" id="new-password" type="password" class="form-control" id="new-password"
[(ngModel)]="newPassword" #newPasswordInput="ngModel" formControlName="new-password"
> >
<div [hidden]="changePasswordForm.controls['new-password'].valid || changePasswordForm.controls['new-password'].pristine" class="alert alert-warning"> <div *ngIf="formErrors['new-password']" class="alert alert-danger">
The password should have more than 5 characters {{ formErrors['new-password'] }}
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="name">Confirm new password</label> <label for="name">Confirm new password</label>
<input <input
type="password" class="form-control" name="new-confirmed-password" id="new-confirmed-password" type="password" class="form-control" id="new-confirmed-password"
[(ngModel)]="newConfirmedPassword" #newConfirmedPasswordInput="ngModel" formControlName="new-confirmed-password"
> >
</div> </div>
<input type="submit" value="Change password" class="btn btn-default" [disabled]="!changePasswordForm.valid"> <input type="submit" value="Change password" class="btn btn-default" [disabled]="!form.valid">
</form> </form>

View File

@ -1,44 +1,64 @@
import { } from '@angular/common'; import { } from '@angular/common';
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup } from '@angular/forms';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { AccountService } from './account.service'; import { AccountService } from './account.service';
import { FormReactive, USER_PASSWORD } from '../shared';
@Component({ @Component({
selector: 'my-account', selector: 'my-account',
template: require('./account.component.html') template: require('./account.component.html')
}) })
export class AccountComponent implements OnInit { export class AccountComponent extends FormReactive implements OnInit {
newPassword = '';
newConfirmedPassword = '';
changePasswordForm: FormGroup;
information: string = null; information: string = null;
error: string = null; error: string = null;
form: FormGroup;
formErrors = {
'new-password': '',
'new-confirmed-password': ''
};
validationMessages = {
'new-password': USER_PASSWORD.MESSAGES,
'new-confirmed-password': USER_PASSWORD.MESSAGES
};
constructor( constructor(
private accountService: AccountService, private accountService: AccountService,
private formBuilder: FormBuilder,
private router: Router private router: Router
) {} ) {
super();
}
buildForm() {
this.form = this.formBuilder.group({
'new-password': [ '', USER_PASSWORD.VALIDATORS ],
'new-confirmed-password': [ '', USER_PASSWORD.VALIDATORS ],
});
this.form.valueChanges.subscribe(data => this.onValueChanged(data));
}
ngOnInit() { ngOnInit() {
this.changePasswordForm = new FormGroup({ this.buildForm();
'new-password': new FormControl('', [ <any>Validators.required, <any>Validators.minLength(6) ]),
'new-confirmed-password': new FormControl('', [ <any>Validators.required, <any>Validators.minLength(6) ]),
});
} }
changePassword() { changePassword() {
const newPassword = this.form.value['new-password'];
const newConfirmedPassword = this.form.value['new-confirmed-password'];
this.information = null; this.information = null;
this.error = null; this.error = null;
if (this.newPassword !== this.newConfirmedPassword) { if (newPassword !== newConfirmedPassword) {
this.error = 'The new password and the confirmed password do not correspond.'; this.error = 'The new password and the confirmed password do not correspond.';
return; return;
} }
this.accountService.changePassword(this.newPassword).subscribe( this.accountService.changePassword(newPassword).subscribe(
ok => this.information = 'Password updated.', ok => this.information = 'Password updated.',
err => this.error = err err => this.error = err

View File

@ -2,14 +2,14 @@
<div *ngIf="error" class="alert alert-danger">{{ error }}</div> <div *ngIf="error" class="alert alert-danger">{{ error }}</div>
<form (ngSubmit)="makeFriends()" [formGroup]="friendAddForm"> <form (ngSubmit)="makeFriends()" [formGroup]="form">
<div class="form-group" *ngFor="let url of urls; let id = index; trackBy:customTrackBy"> <div class="form-group" *ngFor="let url of urls; let id = index; trackBy:customTrackBy">
<label for="username">Url</label> <label for="username">Url</label>
<div class="input-group"> <div class="input-group">
<input <input
type="text" class="form-control" placeholder="http://domain.com" type="text" class="form-control" placeholder="http://domain.com"
[name]="'url-' + id" [id]="'url-' + id" [formControlName]="'url-' + id" [(ngModel)]="urls[id]" [id]="'url-' + id" [formControlName]="'url-' + id"
/> />
<span class="input-group-btn"> <span class="input-group-btn">
<button *ngIf="displayAddField(id)" (click)="addField()" class="btn btn-default" type="button">+</button> <button *ngIf="displayAddField(id)" (click)="addField()" class="btn btn-default" type="button">+</button>
@ -17,7 +17,7 @@
</span> </span>
</div> </div>
<div [hidden]="friendAddForm.controls['url-' + id].valid || friendAddForm.controls['url-' + id].pristine" class="alert alert-warning"> <div [hidden]="form.controls['url-' + id].valid || form.controls['url-' + id].pristine" class="alert alert-warning">
It should be a valid url. It should be a valid url.
</div> </div>
</div> </div>

View File

@ -11,19 +11,19 @@ import { FriendService } from '../shared';
styles: [ require('./friend-add.component.scss') ] styles: [ require('./friend-add.component.scss') ]
}) })
export class FriendAddComponent implements OnInit { export class FriendAddComponent implements OnInit {
friendAddForm: FormGroup; form: FormGroup;
urls = [ ]; urls = [ ];
error: string = null; error: string = null;
constructor(private router: Router, private friendService: FriendService) {} constructor(private router: Router, private friendService: FriendService) {}
ngOnInit() { ngOnInit() {
this.friendAddForm = new FormGroup({}); this.form = new FormGroup({});
this.addField(); this.addField();
} }
addField() { addField() {
this.friendAddForm.addControl(`url-${this.urls.length}`, new FormControl('', [ validateUrl ])); this.form.addControl(`url-${this.urls.length}`, new FormControl('', [ validateUrl ]));
this.urls.push(''); this.urls.push('');
} }
@ -42,7 +42,7 @@ export class FriendAddComponent implements OnInit {
isFormValid() { isFormValid() {
// Do not check the last input // Do not check the last input
for (let i = 0; i < this.urls.length - 1; i++) { for (let i = 0; i < this.urls.length - 1; i++) {
if (!this.friendAddForm.controls[`url-${i}`].valid) return false; if (!this.form.controls[`url-${i}`].valid) return false;
} }
const lastIndex = this.urls.length - 1; const lastIndex = this.urls.length - 1;
@ -50,13 +50,13 @@ export class FriendAddComponent implements OnInit {
if (this.urls[lastIndex] === '' && lastIndex !== 0) { if (this.urls[lastIndex] === '' && lastIndex !== 0) {
return true; return true;
} else { } else {
return this.friendAddForm.controls[`url-${lastIndex}`].valid; return this.form.controls[`url-${lastIndex}`].valid;
} }
} }
removeField(index: number) { removeField(index: number) {
// Remove the last control // Remove the last control
this.friendAddForm.removeControl(`url-${this.urls.length - 1}`); this.form.removeControl(`url-${this.urls.length - 1}`);
this.urls.splice(index, 1); this.urls.splice(index, 1);
} }
@ -94,7 +94,8 @@ export class FriendAddComponent implements OnInit {
private getNotEmptyUrls() { private getNotEmptyUrls() {
const notEmptyUrls = []; const notEmptyUrls = [];
this.urls.forEach((url) => { Object.keys(this.form.value).forEach((urlKey) => {
const url = this.form.value[urlKey];
if (url !== '') notEmptyUrls.push(url); if (url !== '') notEmptyUrls.push(url);
}); });

View File

@ -2,28 +2,28 @@
<div *ngIf="error" class="alert alert-danger">{{ error }}</div> <div *ngIf="error" class="alert alert-danger">{{ error }}</div>
<form role="form" (ngSubmit)="addUser()" [formGroup]="userAddForm"> <form role="form" (ngSubmit)="addUser()" [formGroup]="form">
<div class="form-group"> <div class="form-group">
<label for="username">Username</label> <label for="username">Username</label>
<input <input
type="text" class="form-control" name="username" id="username" placeholder="Username" type="text" class="form-control" id="username" placeholder="Username"
[(ngModel)]="username" formControlName="username"
> >
<div [hidden]="userAddForm.controls.username.valid || userAddForm.controls.username.pristine" class="alert alert-danger"> <div *ngIf="formErrors.username" class="alert alert-danger">
Username is required with a length >= 3 and <= 20 {{ formErrors.username }}
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="password">Password</label> <label for="password">Password</label>
<input <input
type="password" class="form-control" name="password" id="password" placeholder="Password" type="password" class="form-control" id="password" placeholder="Password"
[(ngModel)]="password" formControlName="password"
> >
<div [hidden]="userAddForm.controls.password.valid || userAddForm.controls.password.pristine" class="alert alert-danger"> <div *ngIf="formErrors.password" class="alert alert-danger">
Password is required with a length >= 6 {{ formErrors.password }}
</div> </div>
</div> </div>
<input type="submit" value="Add user" class="btn btn-default" [disabled]="!userAddForm.valid"> <input type="submit" value="Add user" class="btn btn-default" [disabled]="!form.valid">
</form> </form>

View File

@ -1,32 +1,54 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl, Validators } from '@angular/forms'; import { FormBuilder, FormGroup } from '@angular/forms';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { UserService } from '../shared'; import { UserService } from '../shared';
import { FormReactive, USER_USERNAME, USER_PASSWORD } from '../../../shared';
@Component({ @Component({
selector: 'my-user-add', selector: 'my-user-add',
template: require('./user-add.component.html') template: require('./user-add.component.html')
}) })
export class UserAddComponent implements OnInit { export class UserAddComponent extends FormReactive implements OnInit {
userAddForm: FormGroup;
error: string = null; error: string = null;
username = '';
password = '';
constructor(private router: Router, private userService: UserService) {} form: FormGroup;
formErrors = {
'username': '',
'password': ''
};
validationMessages = {
'username': USER_USERNAME.MESSAGES,
'password': USER_PASSWORD.MESSAGES,
};
constructor(
private formBuilder: FormBuilder,
private router: Router,
private userService: UserService
) {
super();
}
buildForm() {
this.form = this.formBuilder.group({
username: [ '', USER_USERNAME.VALIDATORS ],
password: [ '', USER_PASSWORD.VALIDATORS ],
});
this.form.valueChanges.subscribe(data => this.onValueChanged(data));
}
ngOnInit() { ngOnInit() {
this.userAddForm = new FormGroup({ this.buildForm();
username: new FormControl('', [ <any>Validators.required, <any>Validators.minLength(3), <any>Validators.maxLength(20) ]),
password: new FormControl('', [ <any>Validators.required, <any>Validators.minLength(6) ]),
});
} }
addUser() { addUser() {
this.error = null; this.error = null;
this.userService.addUser(this.username, this.password).subscribe( const { username, password } = this.form.value;
this.userService.addUser(username, password).subscribe(
ok => this.router.navigate([ '/admin/users/list' ]), ok => this.router.navigate([ '/admin/users/list' ]),
err => this.error = err.text err => this.error = err.text

View File

@ -28,7 +28,8 @@ import {
VideoMiniatureComponent, VideoMiniatureComponent,
VideoSortComponent, VideoSortComponent,
VideoWatchComponent, VideoWatchComponent,
VideoService VideoService,
WebTorrentService
} from './videos'; } from './videos';
import { import {
FriendsComponent, FriendsComponent,
@ -59,7 +60,7 @@ const APP_PROVIDERS = [
AuthService, AuthService,
RestExtractor, RestExtractor,
RestExtractor, RestService, VideoService, SearchService, FriendService, UserService, AccountService RestExtractor, RestService, VideoService, SearchService, FriendService, UserService, AccountService, WebTorrentService
]; ];
/** /**
* `AppModule` is the main entry point into Angular2's bootstraping process * `AppModule` is the main entry point into Angular2's bootstraping process

View File

@ -2,28 +2,28 @@
<div *ngIf="error" class="alert alert-danger">{{ error }}</div> <div *ngIf="error" class="alert alert-danger">{{ error }}</div>
<form role="form" (ngSubmit)="login()" [formGroup]="loginForm"> <form role="form" (ngSubmit)="login()" [formGroup]="form">
<div class="form-group"> <div class="form-group">
<label for="username">Username</label> <label for="username">Username</label>
<input <input
type="text" class="form-control" name="username" id="username" placeholder="Username" type="text" class="form-control" id="username" placeholder="Username" required
[(ngModel)]="username" formControlName="username"
> >
<div [hidden]="loginForm.controls.username.valid || loginForm.controls.username.pristine" class="alert alert-danger"> <div *ngIf="formErrors.username" class="alert alert-danger">
Username is required {{ formErrors.username }}
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="password">Password</label> <label for="password">Password</label>
<input <input
type="password" class="form-control" name="password" id="password" placeholder="Password" type="password" class="form-control" name="password" id="password" placeholder="Password" required
[(ngModel)]="password" formControlName="password"
> >
<div [hidden]="loginForm.controls.password.valid || loginForm.controls.password.pristine" class="alert alert-danger"> <div *ngIf="formErrors.password" class="alert alert-danger">
Password is required {{ formErrors.password }}
</div> </div>
</div> </div>
<input type="submit" value="Login" class="btn btn-default" [disabled]="!loginForm.valid"> <input type="submit" value="Login" class="btn btn-default" [disabled]="!form.valid">
</form> </form>

View File

@ -1,39 +1,60 @@
import { Component, OnInit } from '@angular/core'; import { Component, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { AuthService } from '../shared'; import { AuthService, FormReactive } from '../shared';
@Component({ @Component({
selector: 'my-login', selector: 'my-login',
template: require('./login.component.html') template: require('./login.component.html')
}) })
export class LoginComponent implements OnInit { export class LoginComponent extends FormReactive implements OnInit {
error: string = null; error: string = null;
username = '';
password: ''; form: FormGroup;
loginForm: FormGroup; formErrors = {
'username': '',
'password': ''
};
validationMessages = {
'username': {
'required': 'Username is required.',
},
'password': {
'required': 'Password is required.'
}
};
constructor( constructor(
private authService: AuthService, private authService: AuthService,
private formBuilder: FormBuilder,
private router: Router private router: Router
) {} ) {
super();
}
buildForm() {
this.form = this.formBuilder.group({
username: [ '', Validators.required ],
password: [ '', Validators.required ],
});
this.form.valueChanges.subscribe(data => this.onValueChanged(data));
}
ngOnInit() { ngOnInit() {
this.loginForm = new FormGroup({ this.buildForm();
username: new FormControl('', [ <any>Validators.required ]),
password: new FormControl('', [ <any>Validators.required ]),
});
} }
login() { login() {
this.authService.login(this.username, this.password).subscribe( this.error = null;
result => {
this.error = null; const { username, password } = this.form.value;
this.authService.login(username, password).subscribe(
result => this.router.navigate(['/videos/list']),
this.router.navigate(['/videos/list']);
},
error => { error => {
console.error(error.json); console.error(error.json);

View File

@ -1 +0,0 @@
export * from './url.validator';

View File

@ -0,0 +1,24 @@
import { FormGroup } from '@angular/forms';
export abstract class FormReactive {
abstract form: FormGroup;
abstract formErrors: Object;
abstract validationMessages: Object;
abstract buildForm(): void;
protected onValueChanged(data?: any) {
for (const field in this.formErrors) {
// clear previous error message (if any)
this.formErrors[field] = '';
const control = this.form.get(field);
if (control && control.dirty && !control.valid) {
const messages = this.validationMessages[field];
for (const key in control.errors) {
this.formErrors[field] += messages[key] + ' ';
}
}
}
}
}

View File

@ -0,0 +1,3 @@
export * from './url.validator';
export * from './user';
export * from './video';

View File

@ -0,0 +1,17 @@
import { Validators } from '@angular/forms';
export const USER_USERNAME = {
VALIDATORS: [ Validators.required, Validators.minLength(3), Validators.maxLength(20) ],
MESSAGES: {
'required': 'Username is required.',
'minlength': 'Username must be at least 3 characters long.',
'maxlength': 'Username cannot be more than 20 characters long.'
}
};
export const USER_PASSWORD = {
VALIDATORS: [ Validators.required, Validators.minLength(6) ],
MESSAGES: {
'required': 'Password is required.',
'minlength': 'Password must be at least 6 characters long.',
}
};

View File

@ -0,0 +1,25 @@
import { Validators } from '@angular/forms';
export const VIDEO_NAME = {
VALIDATORS: [ Validators.required, Validators.minLength(3), Validators.maxLength(50) ],
MESSAGES: {
'required': 'Video name is required.',
'minlength': 'Video name must be at least 3 characters long.',
'maxlength': 'Video name cannot be more than 50 characters long.'
}
};
export const VIDEO_DESCRIPTION = {
VALIDATORS: [ Validators.required, Validators.minLength(3), Validators.maxLength(250) ],
MESSAGES: {
'required': 'Video description is required.',
'minlength': 'Video description must be at least 3 characters long.',
'maxlength': 'Video description cannot be more than 250 characters long.'
}
};
export const VIDEO_TAGS = {
VALIDATORS: [ Validators.pattern('^[a-zA-Z0-9]{2,10}$') ],
MESSAGES: {
'pattern': 'A tag should be between 2 and 10 alphanumeric characters long.'
}
};

View File

@ -0,0 +1,2 @@
export * from './form-validators';
export * from './form-reactive';

View File

@ -1,5 +1,5 @@
export * from './auth'; export * from './auth';
export * from './form-validators'; export * from './forms';
export * from './rest'; export * from './rest';
export * from './search'; export * from './search';
export * from './users'; export * from './users';

View File

@ -2,31 +2,31 @@
<div *ngIf="error" class="alert alert-danger">{{ error }}</div> <div *ngIf="error" class="alert alert-danger">{{ error }}</div>
<form novalidate (ngSubmit)="upload()" [formGroup]="videoForm"> <form novalidate (ngSubmit)="upload()" [formGroup]="form">
<div class="form-group"> <div class="form-group">
<label for="name">Name</label> <label for="name">Name</label>
<input <input
type="text" class="form-control" name="name" id="name" type="text" class="form-control" id="name"
[(ngModel)]="video.name" formControlName="name"
> >
<div [hidden]="videoForm.controls.name.valid || videoForm.controls.name.pristine" class="alert alert-warning"> <div *ngIf="formErrors.name" class="alert alert-danger">
A name is required and should be between 3 and 50 characters long {{ formErrors.name }}
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="tags">Tags</label> <label for="tags">Tags</label>
<input <input
type="text" class="form-control" name="tags" id="tags" type="text" class="form-control" id="currentTag"
[disabled]="isTagsInputDisabled" (keyup)="onTagKeyPress($event)" [(ngModel)]="currentTag" formControlName="currentTag" (keyup)="onTagKeyPress($event)"
> >
<div [hidden]="videoForm.controls.tags.valid || videoForm.controls.tags.pristine" class="alert alert-warning"> <div *ngIf="formErrors.currentTag" class="alert alert-danger">
A tag should be between 2 and 10 characters (alphanumeric) long {{ formErrors.currentTag }}
</div> </div>
</div> </div>
<div class="tags"> <div class="tags">
<div class="label label-primary tag" *ngFor="let tag of video.tags"> <div class="label label-primary tag" *ngFor="let tag of tags">
{{ tag }} {{ tag }}
<span class="remove" (click)="removeTag(tag)">x</span> <span class="remove" (click)="removeTag(tag)">x</span>
</div> </div>
@ -53,12 +53,12 @@
<div class="form-group"> <div class="form-group">
<label for="description">Description</label> <label for="description">Description</label>
<textarea <textarea
name="description" id="description" class="form-control" placeholder="Description..." id="description" class="form-control" placeholder="Description..."
[(ngModel)]="video.description" formControlName="description"
> >
</textarea> </textarea>
<div [hidden]="videoForm.controls.description.valid || videoForm.controls.description.pristine" class="alert alert-warning"> <div *ngIf="formErrors.description" class="alert alert-danger">
A description is required and should be between 3 and 250 characters long {{ formErrors.description }}
</div> </div>
</div> </div>
@ -69,7 +69,7 @@
<div class="form-group"> <div class="form-group">
<input <input
type="submit" value="Upload" class="btn btn-default form-control" [title]="getInvalidFieldsTitle()" type="submit" value="Upload" class="btn btn-default form-control" [title]="getInvalidFieldsTitle()"
[disabled]="!videoForm.valid || video.tags.length === 0 || filename === null" [disabled]="!form.valid || tags.length === 0 || filename === null"
> >
</div> </div>
</form> </form>

View File

@ -1,10 +1,10 @@
import { Component, ElementRef, OnInit } from '@angular/core'; import { Component, ElementRef, OnInit } from '@angular/core';
import { FormControl, FormGroup, Validators } from '@angular/forms'; import { FormBuilder, FormGroup } from '@angular/forms';
import { Router } from '@angular/router'; import { Router } from '@angular/router';
import { FileUploader } from 'ng2-file-upload/ng2-file-upload'; import { FileUploader } from 'ng2-file-upload/ng2-file-upload';
import { AuthService } from '../../shared'; import { AuthService, FormReactive, VIDEO_NAME, VIDEO_DESCRIPTION, VIDEO_TAGS } from '../../shared';
@Component({ @Component({
selector: 'my-videos-add', selector: 'my-videos-add',
@ -12,22 +12,31 @@ import { AuthService } from '../../shared';
template: require('./video-add.component.html') template: require('./video-add.component.html')
}) })
export class VideoAddComponent implements OnInit { export class VideoAddComponent extends FormReactive implements OnInit {
currentTag: string; // Tag the user is writing in the input tags: string[] = [];
error: string = null;
videoForm: FormGroup;
uploader: FileUploader; uploader: FileUploader;
video = {
error: string = null;
form: FormGroup;
formErrors = {
name: '', name: '',
tags: [], description: '',
description: '' currentTag: ''
};
validationMessages = {
name: VIDEO_NAME.MESSAGES,
description: VIDEO_DESCRIPTION.MESSAGES,
currentTag: VIDEO_TAGS.MESSAGES
}; };
constructor( constructor(
private authService: AuthService, private authService: AuthService,
private elementRef: ElementRef, private elementRef: ElementRef,
private formBuilder: FormBuilder,
private router: Router private router: Router
) {} ) {
super();
}
get filename() { get filename() {
if (this.uploader.queue.length === 0) { if (this.uploader.queue.length === 0) {
@ -37,20 +46,26 @@ export class VideoAddComponent implements OnInit {
return this.uploader.queue[0].file.name; return this.uploader.queue[0].file.name;
} }
get isTagsInputDisabled () { buildForm() {
return this.video.tags.length >= 3; this.form = this.formBuilder.group({
name: [ '', VIDEO_NAME.VALIDATORS ],
description: [ '', VIDEO_DESCRIPTION.VALIDATORS ],
currentTag: [ '', VIDEO_TAGS.VALIDATORS ]
});
this.form.valueChanges.subscribe(data => this.onValueChanged(data));
} }
getInvalidFieldsTitle() { getInvalidFieldsTitle() {
let title = ''; let title = '';
const nameControl = this.videoForm.controls['name']; const nameControl = this.form.controls['name'];
const descriptionControl = this.videoForm.controls['description']; const descriptionControl = this.form.controls['description'];
if (!nameControl.valid) { if (!nameControl.valid) {
title += 'A name is required\n'; title += 'A name is required\n';
} }
if (this.video.tags.length === 0) { if (this.tags.length === 0) {
title += 'At least one tag is required\n'; title += 'At least one tag is required\n';
} }
@ -66,13 +81,6 @@ export class VideoAddComponent implements OnInit {
} }
ngOnInit() { ngOnInit() {
this.videoForm = new FormGroup({
name: new FormControl('', [ <any>Validators.required, <any>Validators.minLength(3), <any>Validators.maxLength(50) ]),
description: new FormControl('', [ <any>Validators.required, <any>Validators.minLength(3), <any>Validators.maxLength(250) ]),
tags: new FormControl('', <any>Validators.pattern('^[a-zA-Z0-9]{2,10}$'))
});
this.uploader = new FileUploader({ this.uploader = new FileUploader({
authToken: this.authService.getRequestHeaderValue(), authToken: this.authService.getRequestHeaderValue(),
queueLimit: 1, queueLimit: 1,
@ -81,26 +89,37 @@ export class VideoAddComponent implements OnInit {
}); });
this.uploader.onBuildItemForm = (item, form) => { this.uploader.onBuildItemForm = (item, form) => {
form.append('name', this.video.name); const name = this.form.value['name'];
form.append('description', this.video.description); const description = this.form.value['description'];
for (let i = 0; i < this.video.tags.length; i++) { form.append('name', name);
form.append(`tags[${i}]`, this.video.tags[i]); form.append('description', description);
for (let i = 0; i < this.tags.length; i++) {
form.append(`tags[${i}]`, this.tags[i]);
} }
}; };
this.buildForm();
} }
onTagKeyPress(event: KeyboardEvent) { onTagKeyPress(event: KeyboardEvent) {
const currentTag = this.form.value['currentTag'];
// Enter press // Enter press
if (event.keyCode === 13) { if (event.keyCode === 13) {
// Check if the tag is valid and does not already exist // Check if the tag is valid and does not already exist
if ( if (
this.currentTag !== '' && currentTag !== '' &&
this.videoForm.controls['tags'].valid && this.form.controls['currentTag'].valid &&
this.video.tags.indexOf(this.currentTag) === -1 this.tags.indexOf(currentTag) === -1
) { ) {
this.video.tags.push(this.currentTag); this.tags.push(currentTag);
this.currentTag = ''; this.form.patchValue({ currentTag: '' });
if (this.tags.length >= 3) {
this.form.get('currentTag').disable();
}
} }
} }
} }
@ -110,7 +129,7 @@ export class VideoAddComponent implements OnInit {
} }
removeTag(tag: string) { removeTag(tag: string) {
this.video.tags.splice(this.video.tags.indexOf(tag), 1); this.tags.splice(this.tags.indexOf(tag), 1);
} }
upload() { upload() {