Client: use ng2-tag-input for forms with video tags
This commit is contained in:
parent
ad42bea3a5
commit
3758da9489
|
@ -58,7 +58,7 @@
|
||||||
"ng-router-loader": "^1.0.2",
|
"ng-router-loader": "^1.0.2",
|
||||||
"ng2-file-upload": "^1.1.4-2",
|
"ng2-file-upload": "^1.1.4-2",
|
||||||
"ng2-smart-table": "1.0.3",
|
"ng2-smart-table": "1.0.3",
|
||||||
"ng2-tag-input": "1.0.1",
|
"ng2-tag-input": "^1.0.5",
|
||||||
"ngc-webpack": "1.1.0",
|
"ngc-webpack": "1.1.0",
|
||||||
"ngx-bootstrap": "1.6.6",
|
"ngx-bootstrap": "1.6.6",
|
||||||
"node-sass": "^4.1.1",
|
"node-sass": "^4.1.1",
|
||||||
|
|
|
@ -38,8 +38,9 @@ export const VIDEO_DESCRIPTION = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const VIDEO_TAGS = {
|
export const VIDEO_TAGS = {
|
||||||
VALIDATORS: [ Validators.maxLength(10) ],
|
VALIDATORS: [ Validators.minLength(2), Validators.maxLength(10) ],
|
||||||
MESSAGES: {
|
MESSAGES: {
|
||||||
|
'minlength': 'A tag should be more than 2 characters long.',
|
||||||
'maxlength': 'A tag should be less than 10 characters long.'
|
'maxlength': 'A tag should be less than 10 characters long.'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -59,25 +59,11 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="tags">Tags</label> <span class="little-information">(press enter to add the tag)</span>
|
<label for="tags" class="label-tags">Tags</label> <span class="little-information">(press enter to add the tag)</span>
|
||||||
<input
|
<tag-input
|
||||||
type="text" class="form-control" id="currentTag"
|
[ngModel]="tags" [validators]="tagValidators" [errorMessages]="tagValidatorsMessages"
|
||||||
formControlName="currentTag" (keyup)="onTagKeyPress($event)"
|
formControlName="tags" maxItems="3" modelAsStrings="true"
|
||||||
>
|
></tag-input>
|
||||||
<div *ngIf="formErrors.currentTag" class="alert alert-danger">
|
|
||||||
{{ formErrors.currentTag }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="tags">
|
|
||||||
<div class="label label-primary tag" *ngFor="let tag of tags">
|
|
||||||
{{ tag }}
|
|
||||||
<span class="remove" (click)="removeTag(tag)">x</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div *ngIf="tagsError" class="alert alert-danger">
|
|
||||||
{{ tagsError }}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
|
@ -30,6 +30,9 @@ export class VideoAddComponent extends FormReactive implements OnInit {
|
||||||
videoLicences = [];
|
videoLicences = [];
|
||||||
videoLanguages = [];
|
videoLanguages = [];
|
||||||
|
|
||||||
|
tagValidators = VIDEO_TAGS.VALIDATORS;
|
||||||
|
tagValidatorsMessages = VIDEO_TAGS.MESSAGES;
|
||||||
|
|
||||||
error: string = null;
|
error: string = null;
|
||||||
form: FormGroup;
|
form: FormGroup;
|
||||||
formErrors = {
|
formErrors = {
|
||||||
|
@ -37,20 +40,17 @@ export class VideoAddComponent extends FormReactive implements OnInit {
|
||||||
category: '',
|
category: '',
|
||||||
licence: '',
|
licence: '',
|
||||||
language: '',
|
language: '',
|
||||||
description: '',
|
description: ''
|
||||||
currentTag: ''
|
|
||||||
};
|
};
|
||||||
validationMessages = {
|
validationMessages = {
|
||||||
name: VIDEO_NAME.MESSAGES,
|
name: VIDEO_NAME.MESSAGES,
|
||||||
category: VIDEO_CATEGORY.MESSAGES,
|
category: VIDEO_CATEGORY.MESSAGES,
|
||||||
licence: VIDEO_LICENCE.MESSAGES,
|
licence: VIDEO_LICENCE.MESSAGES,
|
||||||
language: VIDEO_LANGUAGE.MESSAGES,
|
language: VIDEO_LANGUAGE.MESSAGES,
|
||||||
description: VIDEO_DESCRIPTION.MESSAGES,
|
description: VIDEO_DESCRIPTION.MESSAGES
|
||||||
currentTag: VIDEO_TAGS.MESSAGES
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Special error messages
|
// Special error messages
|
||||||
tagsError = '';
|
|
||||||
fileError = '';
|
fileError = '';
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -80,7 +80,7 @@ export class VideoAddComponent extends FormReactive implements OnInit {
|
||||||
licence: [ '', VIDEO_LICENCE.VALIDATORS ],
|
licence: [ '', VIDEO_LICENCE.VALIDATORS ],
|
||||||
language: [ '', VIDEO_LANGUAGE.VALIDATORS ],
|
language: [ '', VIDEO_LANGUAGE.VALIDATORS ],
|
||||||
description: [ '', VIDEO_DESCRIPTION.VALIDATORS ],
|
description: [ '', VIDEO_DESCRIPTION.VALIDATORS ],
|
||||||
currentTag: [ '', VIDEO_TAGS.VALIDATORS ]
|
tags: [ '']
|
||||||
});
|
});
|
||||||
|
|
||||||
this.form.valueChanges.subscribe(data => this.onValueChanged(data));
|
this.form.valueChanges.subscribe(data => this.onValueChanged(data));
|
||||||
|
@ -105,6 +105,7 @@ export class VideoAddComponent extends FormReactive implements OnInit {
|
||||||
const licence = this.form.value['licence'];
|
const licence = this.form.value['licence'];
|
||||||
const language = this.form.value['language'];
|
const language = this.form.value['language'];
|
||||||
const description = this.form.value['description'];
|
const description = this.form.value['description'];
|
||||||
|
const tags = this.form.value['tags'];
|
||||||
|
|
||||||
form.append('name', name);
|
form.append('name', name);
|
||||||
form.append('category', category);
|
form.append('category', category);
|
||||||
|
@ -118,8 +119,8 @@ export class VideoAddComponent extends FormReactive implements OnInit {
|
||||||
|
|
||||||
form.append('description', description);
|
form.append('description', description);
|
||||||
|
|
||||||
for (let i = 0; i < this.tags.length; i++) {
|
for (let i = 0; i < tags.length; i++) {
|
||||||
form.append(`tags[${i}]`, this.tags[i]);
|
form.append(`tags[${i}]`, tags[i]);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -133,33 +134,18 @@ export class VideoAddComponent extends FormReactive implements OnInit {
|
||||||
this.fileError = 'You did not add a file.';
|
this.fileError = 'You did not add a file.';
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.form.valid === true && this.tagsError === '' && this.fileError === '';
|
return this.form.valid === true && this.fileError === '';
|
||||||
}
|
}
|
||||||
|
|
||||||
fileChanged() {
|
fileChanged() {
|
||||||
this.fileError = '';
|
this.fileError = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
onTagKeyPress(event: KeyboardEvent) {
|
|
||||||
// Enter press
|
|
||||||
if (event.keyCode === 13) {
|
|
||||||
this.addTagIfPossible();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
removeFile() {
|
removeFile() {
|
||||||
this.uploader.clearQueue();
|
this.uploader.clearQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
removeTag(tag: string) {
|
|
||||||
this.tags.splice(this.tags.indexOf(tag), 1);
|
|
||||||
this.form.get('currentTag').enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
upload() {
|
upload() {
|
||||||
// Maybe the user forgot to press "enter" when he filled the field
|
|
||||||
this.addTagIfPossible();
|
|
||||||
|
|
||||||
if (this.checkForm() === false) {
|
if (this.checkForm() === false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -206,25 +192,4 @@ export class VideoAddComponent extends FormReactive implements OnInit {
|
||||||
|
|
||||||
this.uploader.uploadAll();
|
this.uploader.uploadAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
private addTagIfPossible() {
|
|
||||||
const currentTag = this.form.value['currentTag'];
|
|
||||||
if (currentTag === undefined) return;
|
|
||||||
|
|
||||||
// Check if the tag is valid and does not already exist
|
|
||||||
if (
|
|
||||||
currentTag.length >= 2 &&
|
|
||||||
this.form.controls['currentTag'].valid &&
|
|
||||||
this.tags.indexOf(currentTag) === -1
|
|
||||||
) {
|
|
||||||
this.tags.push(currentTag);
|
|
||||||
this.form.patchValue({ currentTag: '' });
|
|
||||||
|
|
||||||
if (this.tags.length >= 3) {
|
|
||||||
this.form.get('currentTag').disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.tagsError = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,3 +50,7 @@ div.file-to-upload {
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.label-tags {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
|
@ -59,25 +59,11 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="tags">Tags</label> <span class="little-information">(press enter to add the tag)</span>
|
<label for="tags" class="label-tags">Tags</label> <span class="little-information">(press enter to add the tag)</span>
|
||||||
<input
|
<tag-input
|
||||||
type="text" class="form-control" id="currentTag"
|
[ngModel]="tags" [validators]="tagValidators" [errorMessages]="tagValidatorsMessages"
|
||||||
formControlName="currentTag" (keyup)="onTagKeyPress($event)"
|
formControlName="tags" maxItems="3" modelAsStrings="true"
|
||||||
>
|
></tag-input>
|
||||||
<div *ngIf="formErrors.currentTag" class="alert alert-danger">
|
|
||||||
{{ formErrors.currentTag }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="tags">
|
|
||||||
<div class="label label-primary tag" *ngFor="let tag of tags">
|
|
||||||
{{ tag }}
|
|
||||||
<span class="remove" (click)="removeTag(tag)">x</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div *ngIf="tagsError" class="alert alert-danger">
|
|
||||||
{{ tagsError }}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
|
|
|
@ -30,6 +30,9 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
|
||||||
videoLanguages = [];
|
videoLanguages = [];
|
||||||
video: Video;
|
video: Video;
|
||||||
|
|
||||||
|
tagValidators = VIDEO_TAGS.VALIDATORS;
|
||||||
|
tagValidatorsMessages = VIDEO_TAGS.MESSAGES;
|
||||||
|
|
||||||
error: string = null;
|
error: string = null;
|
||||||
form: FormGroup;
|
form: FormGroup;
|
||||||
formErrors = {
|
formErrors = {
|
||||||
|
@ -37,20 +40,16 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
|
||||||
category: '',
|
category: '',
|
||||||
licence: '',
|
licence: '',
|
||||||
language: '',
|
language: '',
|
||||||
description: '',
|
description: ''
|
||||||
currentTag: ''
|
|
||||||
};
|
};
|
||||||
validationMessages = {
|
validationMessages = {
|
||||||
name: VIDEO_NAME.MESSAGES,
|
name: VIDEO_NAME.MESSAGES,
|
||||||
category: VIDEO_CATEGORY.MESSAGES,
|
category: VIDEO_CATEGORY.MESSAGES,
|
||||||
licence: VIDEO_LICENCE.MESSAGES,
|
licence: VIDEO_LICENCE.MESSAGES,
|
||||||
language: VIDEO_LANGUAGE.MESSAGES,
|
language: VIDEO_LANGUAGE.MESSAGES,
|
||||||
description: VIDEO_DESCRIPTION.MESSAGES,
|
description: VIDEO_DESCRIPTION.MESSAGES
|
||||||
currentTag: VIDEO_TAGS.MESSAGES
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Special error messages
|
|
||||||
tagsError = '';
|
|
||||||
fileError = '';
|
fileError = '';
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -73,7 +72,7 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
|
||||||
licence: [ '', VIDEO_LICENCE.VALIDATORS ],
|
licence: [ '', VIDEO_LICENCE.VALIDATORS ],
|
||||||
language: [ '', VIDEO_LANGUAGE.VALIDATORS ],
|
language: [ '', VIDEO_LANGUAGE.VALIDATORS ],
|
||||||
description: [ '', VIDEO_DESCRIPTION.VALIDATORS ],
|
description: [ '', VIDEO_DESCRIPTION.VALIDATORS ],
|
||||||
currentTag: [ '', VIDEO_TAGS.VALIDATORS ]
|
tags: [ '' ]
|
||||||
});
|
});
|
||||||
|
|
||||||
this.form.valueChanges.subscribe(data => this.onValueChanged(data));
|
this.form.valueChanges.subscribe(data => this.onValueChanged(data));
|
||||||
|
@ -99,33 +98,7 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
checkForm() {
|
|
||||||
this.forceCheck();
|
|
||||||
|
|
||||||
return this.form.valid === true && this.tagsError === '' && this.fileError === '';
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
onTagKeyPress(event: KeyboardEvent) {
|
|
||||||
// Enter press
|
|
||||||
if (event.keyCode === 13) {
|
|
||||||
this.addTagIfPossible();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
removeTag(tag: string) {
|
|
||||||
this.tags.splice(this.tags.indexOf(tag), 1);
|
|
||||||
this.form.get('currentTag').enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
// Maybe the user forgot to press "enter" when he filled the field
|
|
||||||
this.addTagIfPossible();
|
|
||||||
|
|
||||||
if (this.checkForm() === false) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.video.patch(this.form.value);
|
this.video.patch(this.form.value);
|
||||||
|
|
||||||
this.videoService.updateVideo(this.video)
|
this.videoService.updateVideo(this.video)
|
||||||
|
@ -143,27 +116,6 @@ export class VideoUpdateComponent extends FormReactive implements OnInit {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private addTagIfPossible() {
|
|
||||||
const currentTag = this.form.value['currentTag'];
|
|
||||||
if (currentTag === undefined) return;
|
|
||||||
|
|
||||||
// Check if the tag is valid and does not already exist
|
|
||||||
if (
|
|
||||||
currentTag.length >= 2 &&
|
|
||||||
this.form.controls['currentTag'].valid &&
|
|
||||||
this.tags.indexOf(currentTag) === -1
|
|
||||||
) {
|
|
||||||
this.tags.push(currentTag);
|
|
||||||
this.form.patchValue({ currentTag: '' });
|
|
||||||
|
|
||||||
if (this.tags.length >= 3) {
|
|
||||||
this.form.get('currentTag').disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.tagsError = '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private hydrateFormFromVideo() {
|
private hydrateFormFromVideo() {
|
||||||
this.form.patchValue(this.video.toJSON());
|
this.form.patchValue(this.video.toJSON());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
|
|
||||||
// import { TagInputModule } from 'ng2-tag-input';
|
import { TagInputModule } from 'ng2-tag-input';
|
||||||
|
|
||||||
import { VideosRoutingModule } from './videos-routing.module';
|
import { VideosRoutingModule } from './videos-routing.module';
|
||||||
import { VideosComponent } from './videos.component';
|
import { VideosComponent } from './videos.component';
|
||||||
|
@ -18,7 +18,7 @@ import { SharedModule } from '../shared';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
// TagInputModule,
|
TagInputModule,
|
||||||
|
|
||||||
VideosRoutingModule,
|
VideosRoutingModule,
|
||||||
SharedModule
|
SharedModule
|
||||||
|
|
Loading…
Reference in New Issue