aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/videos
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2016-09-09 22:16:51 +0200
committerChocobozzz <florian.bigard@gmail.com>2016-09-09 22:16:51 +0200
commit4b2f33f3c6d109365090b08244d7f99ad4e69025 (patch)
tree700d3e8e14efc4172f754d75c041ec507100e897 /client/src/app/videos
parentab32b0fc805b92c5a1d7ac5901cb1a38e94622ca (diff)
downloadPeerTube-4b2f33f3c6d109365090b08244d7f99ad4e69025.tar.gz
PeerTube-4b2f33f3c6d109365090b08244d7f99ad4e69025.tar.zst
PeerTube-4b2f33f3c6d109365090b08244d7f99ad4e69025.zip
Client: reactive forms
Diffstat (limited to 'client/src/app/videos')
-rw-r--r--client/src/app/videos/video-add/video-add.component.html30
-rw-r--r--client/src/app/videos/video-add/video-add.component.ts83
2 files changed, 66 insertions, 47 deletions
diff --git a/client/src/app/videos/video-add/video-add.component.html b/client/src/app/videos/video-add/video-add.component.html
index 76bb61f7d..64320cae7 100644
--- a/client/src/app/videos/video-add/video-add.component.html
+++ b/client/src/app/videos/video-add/video-add.component.html
@@ -2,31 +2,31 @@
2 2
3<div *ngIf="error" class="alert alert-danger">{{ error }}</div> 3<div *ngIf="error" class="alert alert-danger">{{ error }}</div>
4 4
5<form novalidate (ngSubmit)="upload()" [formGroup]="videoForm"> 5<form novalidate (ngSubmit)="upload()" [formGroup]="form">
6 <div class="form-group"> 6 <div class="form-group">
7 <label for="name">Name</label> 7 <label for="name">Name</label>
8 <input 8 <input
9 type="text" class="form-control" name="name" id="name" 9 type="text" class="form-control" id="name"
10 [(ngModel)]="video.name" 10 formControlName="name"
11 > 11 >
12 <div [hidden]="videoForm.controls.name.valid || videoForm.controls.name.pristine" class="alert alert-warning"> 12 <div *ngIf="formErrors.name" class="alert alert-danger">
13 A name is required and should be between 3 and 50 characters long 13 {{ formErrors.name }}
14 </div> 14 </div>
15 </div> 15 </div>
16 16
17 <div class="form-group"> 17 <div class="form-group">
18 <label for="tags">Tags</label> 18 <label for="tags">Tags</label>
19 <input 19 <input
20 type="text" class="form-control" name="tags" id="tags" 20 type="text" class="form-control" id="currentTag"
21 [disabled]="isTagsInputDisabled" (keyup)="onTagKeyPress($event)" [(ngModel)]="currentTag" 21 formControlName="currentTag" (keyup)="onTagKeyPress($event)"
22 > 22 >
23 <div [hidden]="videoForm.controls.tags.valid || videoForm.controls.tags.pristine" class="alert alert-warning"> 23 <div *ngIf="formErrors.currentTag" class="alert alert-danger">
24 A tag should be between 2 and 10 characters (alphanumeric) long 24 {{ formErrors.currentTag }}
25 </div> 25 </div>
26 </div> 26 </div>
27 27
28 <div class="tags"> 28 <div class="tags">
29 <div class="label label-primary tag" *ngFor="let tag of video.tags"> 29 <div class="label label-primary tag" *ngFor="let tag of tags">
30 {{ tag }} 30 {{ tag }}
31 <span class="remove" (click)="removeTag(tag)">x</span> 31 <span class="remove" (click)="removeTag(tag)">x</span>
32 </div> 32 </div>
@@ -53,12 +53,12 @@
53 <div class="form-group"> 53 <div class="form-group">
54 <label for="description">Description</label> 54 <label for="description">Description</label>
55 <textarea 55 <textarea
56 name="description" id="description" class="form-control" placeholder="Description..." 56 id="description" class="form-control" placeholder="Description..."
57 [(ngModel)]="video.description" 57 formControlName="description"
58 > 58 >
59 </textarea> 59 </textarea>
60 <div [hidden]="videoForm.controls.description.valid || videoForm.controls.description.pristine" class="alert alert-warning"> 60 <div *ngIf="formErrors.description" class="alert alert-danger">
61 A description is required and should be between 3 and 250 characters long 61 {{ formErrors.description }}
62 </div> 62 </div>
63 </div> 63 </div>
64 64
@@ -69,7 +69,7 @@
69 <div class="form-group"> 69 <div class="form-group">
70 <input 70 <input
71 type="submit" value="Upload" class="btn btn-default form-control" [title]="getInvalidFieldsTitle()" 71 type="submit" value="Upload" class="btn btn-default form-control" [title]="getInvalidFieldsTitle()"
72 [disabled]="!videoForm.valid || video.tags.length === 0 || filename === null" 72 [disabled]="!form.valid || tags.length === 0 || filename === null"
73 > 73 >
74 </div> 74 </div>
75</form> 75</form>
diff --git a/client/src/app/videos/video-add/video-add.component.ts b/client/src/app/videos/video-add/video-add.component.ts
index f0695d768..16a8409be 100644
--- a/client/src/app/videos/video-add/video-add.component.ts
+++ b/client/src/app/videos/video-add/video-add.component.ts
@@ -1,10 +1,10 @@
1import { Component, ElementRef, OnInit } from '@angular/core'; 1import { Component, ElementRef, OnInit } from '@angular/core';
2import { FormControl, FormGroup, Validators } from '@angular/forms'; 2import { FormBuilder, FormGroup } from '@angular/forms';
3import { Router } from '@angular/router'; 3import { Router } from '@angular/router';
4 4
5import { FileUploader } from 'ng2-file-upload/ng2-file-upload'; 5import { FileUploader } from 'ng2-file-upload/ng2-file-upload';
6 6
7import { AuthService } from '../../shared'; 7import { AuthService, FormReactive, VIDEO_NAME, VIDEO_DESCRIPTION, VIDEO_TAGS } from '../../shared';
8 8
9@Component({ 9@Component({
10 selector: 'my-videos-add', 10 selector: 'my-videos-add',
@@ -12,22 +12,31 @@ import { AuthService } from '../../shared';
12 template: require('./video-add.component.html') 12 template: require('./video-add.component.html')
13}) 13})
14 14
15export class VideoAddComponent implements OnInit { 15export class VideoAddComponent extends FormReactive implements OnInit {
16 currentTag: string; // Tag the user is writing in the input 16 tags: string[] = [];
17 error: string = null;
18 videoForm: FormGroup;
19 uploader: FileUploader; 17 uploader: FileUploader;
20 video = { 18
19 error: string = null;
20 form: FormGroup;
21 formErrors = {
21 name: '', 22 name: '',
22 tags: [], 23 description: '',
23 description: '' 24 currentTag: ''
25 };
26 validationMessages = {
27 name: VIDEO_NAME.MESSAGES,
28 description: VIDEO_DESCRIPTION.MESSAGES,
29 currentTag: VIDEO_TAGS.MESSAGES
24 }; 30 };
25 31
26 constructor( 32 constructor(
27 private authService: AuthService, 33 private authService: AuthService,
28 private elementRef: ElementRef, 34 private elementRef: ElementRef,
35 private formBuilder: FormBuilder,
29 private router: Router 36 private router: Router
30 ) {} 37 ) {
38 super();
39 }
31 40
32 get filename() { 41 get filename() {
33 if (this.uploader.queue.length === 0) { 42 if (this.uploader.queue.length === 0) {
@@ -37,20 +46,26 @@ export class VideoAddComponent implements OnInit {
37 return this.uploader.queue[0].file.name; 46 return this.uploader.queue[0].file.name;
38 } 47 }
39 48
40 get isTagsInputDisabled () { 49 buildForm() {
41 return this.video.tags.length >= 3; 50 this.form = this.formBuilder.group({
51 name: [ '', VIDEO_NAME.VALIDATORS ],
52 description: [ '', VIDEO_DESCRIPTION.VALIDATORS ],
53 currentTag: [ '', VIDEO_TAGS.VALIDATORS ]
54 });
55
56 this.form.valueChanges.subscribe(data => this.onValueChanged(data));
42 } 57 }
43 58
44 getInvalidFieldsTitle() { 59 getInvalidFieldsTitle() {
45 let title = ''; 60 let title = '';
46 const nameControl = this.videoForm.controls['name']; 61 const nameControl = this.form.controls['name'];
47 const descriptionControl = this.videoForm.controls['description']; 62 const descriptionControl = this.form.controls['description'];
48 63
49 if (!nameControl.valid) { 64 if (!nameControl.valid) {
50 title += 'A name is required\n'; 65 title += 'A name is required\n';
51 } 66 }
52 67
53 if (this.video.tags.length === 0) { 68 if (this.tags.length === 0) {
54 title += 'At least one tag is required\n'; 69 title += 'At least one tag is required\n';
55 } 70 }
56 71
@@ -66,13 +81,6 @@ export class VideoAddComponent implements OnInit {
66 } 81 }
67 82
68 ngOnInit() { 83 ngOnInit() {
69 this.videoForm = new FormGroup({
70 name: new FormControl('', [ <any>Validators.required, <any>Validators.minLength(3), <any>Validators.maxLength(50) ]),
71 description: new FormControl('', [ <any>Validators.required, <any>Validators.minLength(3), <any>Validators.maxLength(250) ]),
72 tags: new FormControl('', <any>Validators.pattern('^[a-zA-Z0-9]{2,10}$'))
73 });
74
75
76 this.uploader = new FileUploader({ 84 this.uploader = new FileUploader({
77 authToken: this.authService.getRequestHeaderValue(), 85 authToken: this.authService.getRequestHeaderValue(),
78 queueLimit: 1, 86 queueLimit: 1,
@@ -81,26 +89,37 @@ export class VideoAddComponent implements OnInit {
81 }); 89 });
82 90
83 this.uploader.onBuildItemForm = (item, form) => { 91 this.uploader.onBuildItemForm = (item, form) => {
84 form.append('name', this.video.name); 92 const name = this.form.value['name'];
85 form.append('description', this.video.description); 93 const description = this.form.value['description'];
94
95 form.append('name', name);
96 form.append('description', description);
86 97
87 for (let i = 0; i < this.video.tags.length; i++) { 98 for (let i = 0; i < this.tags.length; i++) {
88 form.append(`tags[${i}]`, this.video.tags[i]); 99 form.append(`tags[${i}]`, this.tags[i]);
89 } 100 }
90 }; 101 };
102
103 this.buildForm();
91 } 104 }
92 105
93 onTagKeyPress(event: KeyboardEvent) { 106 onTagKeyPress(event: KeyboardEvent) {
107 const currentTag = this.form.value['currentTag'];
108
94 // Enter press 109 // Enter press
95 if (event.keyCode === 13) { 110 if (event.keyCode === 13) {
96 // Check if the tag is valid and does not already exist 111 // Check if the tag is valid and does not already exist
97 if ( 112 if (
98 this.currentTag !== '' && 113 currentTag !== '' &&
99 this.videoForm.controls['tags'].valid && 114 this.form.controls['currentTag'].valid &&
100 this.video.tags.indexOf(this.currentTag) === -1 115 this.tags.indexOf(currentTag) === -1
101 ) { 116 ) {
102 this.video.tags.push(this.currentTag); 117 this.tags.push(currentTag);
103 this.currentTag = ''; 118 this.form.patchValue({ currentTag: '' });
119
120 if (this.tags.length >= 3) {
121 this.form.get('currentTag').disable();
122 }
104 } 123 }
105 } 124 }
106 } 125 }
@@ -110,7 +129,7 @@ export class VideoAddComponent implements OnInit {
110 } 129 }
111 130
112 removeTag(tag: string) { 131 removeTag(tag: string) {
113 this.video.tags.splice(this.video.tags.indexOf(tag), 1); 132 this.tags.splice(this.tags.indexOf(tag), 1);
114 } 133 }
115 134
116 upload() { 135 upload() {