Skip to content

Commit e228f0d

Browse files
committed
feat(Form): add components to handle TextInput and FileInput
1 parent c124218 commit e228f0d

File tree

2 files changed

+168
-0
lines changed

2 files changed

+168
-0
lines changed

components/Input/FileInput.vue

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
<template>
2+
<ValidationProvider ref="fileObserver" :tag="tag" :rules="rules" :name="name" :vid="vid" v-slot="{ errors }">
3+
<slot></slot>
4+
<input :id="name" name="archive" ref="inputFile" @change="selectedFile" class="input--secondary-color input__file"
5+
type="file">
6+
<label :for="name">
7+
<Icon type="archive" theme="theme--white"/>
8+
{{labelFileText}}</label>
9+
<span class="error-message">{{errors[0]}}</span>
10+
<slot name="footer"></slot>
11+
<span class="message message--red" v-if="filename"
12+
style="text-decoration: underline; cursor: pointer;"
13+
@click="deleteFile">Supprimer le fichier</span>
14+
</ValidationProvider>
15+
</template>
16+
17+
<script lang="ts">
18+
import {ValidationProvider} from 'vee-validate';
19+
import {Component, Emit, Prop, Ref, Vue} from "vue-property-decorator";
20+
import Icon from "~/components/Symbols/Icon.vue";
21+
22+
@Component({
23+
components: {
24+
Icon,
25+
ValidationProvider
26+
}
27+
})
28+
export default class TextInput extends Vue {
29+
30+
@Prop({type: [String, Object], default: ''}) rules!: string | object;
31+
@Prop({type: String, default: ''}) name!: string;
32+
@Prop({type: String, default: undefined}) vid!: string | undefined;
33+
@Prop({type: String, default: 'div'}) tag!: string;
34+
@Prop({type:String, default: ''}) defaultFilename!:string;
35+
36+
/**
37+
* Observer for the input file element
38+
*/
39+
@Ref() inputFile!: HTMLInputElement;
40+
/**
41+
* Validation Observer for the zip archive and the url
42+
*/
43+
@Ref() fileObserver!: InstanceType<typeof ValidationProvider>;
44+
45+
/**
46+
* The name of the uploaded file
47+
* Default is null
48+
*/
49+
filename: string | null = null;
50+
51+
/**
52+
* Returns the name of the uploaded file or a default message instead
53+
*/
54+
protected get labelFileText() {
55+
if (this.filename !== null) {
56+
if (this.filename.length > 18) {
57+
return this.filename.slice(0, 18) + '...'
58+
}
59+
60+
return this.filename
61+
}
62+
63+
return 'Choisir un fichier...'
64+
}
65+
66+
67+
@Emit()
68+
input(file: File | null) {
69+
return file;
70+
}
71+
72+
/**
73+
* Get the file from the input file element
74+
*/
75+
file(): File | null {
76+
const inputFile: any = this.fileObserver.value;
77+
if (!inputFile) {
78+
return null;
79+
}
80+
return inputFile
81+
}
82+
83+
/**
84+
* Event for the changed state of the input file
85+
*/
86+
async selectedFile() {
87+
const inputElement: HTMLInputElement = this.inputFile;
88+
const files = inputElement.files;
89+
if (files !== null) {
90+
const file: File | null = files.item(0);
91+
this.filename = file !== null ? file.name : null;
92+
await this.fileObserver.validate(file);
93+
this.input(file);
94+
}
95+
}
96+
97+
/**
98+
* Delete file from input and reset the filename
99+
*/
100+
deleteFile() {
101+
this.$nextTick(async () => {
102+
this.filename = null;
103+
this.inputFile.files = null;
104+
this.inputFile.value = '';
105+
this.fileObserver.value = undefined;
106+
this.fileObserver.reset();
107+
this.input(null);
108+
});
109+
}
110+
111+
mounted() {
112+
this.filename = this.defaultFilename === '' ? null : this.defaultFilename;
113+
}
114+
115+
}
116+
</script>
117+
118+
119+
<style lang="scss" scoped>
120+
label {
121+
align-self: flex-start;
122+
}
123+
</style>

components/Input/TextInput.vue

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<template>
2+
<ValidationProvider :tag="tag" :rules="rules" :name="name" :vid="vid" v-slot="{ errors }">
3+
<slot></slot>
4+
<input class="input--grey" :type="type" :placeholder="placeholder" v-model="currentValue">
5+
<span class="error-message">{{ errors[0] }}</span>
6+
</ValidationProvider>
7+
</template>
8+
9+
<script lang="ts">
10+
import {ValidationProvider} from 'vee-validate';
11+
import {Component, Emit, Prop, Vue, Watch} from "vue-property-decorator";
12+
13+
@Component({
14+
components: {
15+
ValidationProvider
16+
}
17+
})
18+
export default class TextInput extends Vue {
19+
20+
@Prop({type: [String, Object], default: ''}) rules!: string | object;
21+
@Prop({type: String, default: ''}) name!: string;
22+
@Prop({type: String, default: undefined}) vid!: string | undefined;
23+
@Prop({type: String, default: 'text'}) type!: string;
24+
@Prop({type: String, default: 'div'}) tag!: string;
25+
@Prop({type:String, default: ''}) defaultValue!:string;
26+
@Prop({type:String, default: ''}) placeholder!:string;
27+
28+
currentValue: string = '';
29+
30+
@Watch('currentValue')
31+
OnCurrentValueChange(val: string) {
32+
this.input(val);
33+
}
34+
35+
@Emit()
36+
input(value: string) {
37+
return value;
38+
}
39+
40+
mounted() {
41+
this.currentValue = this.defaultValue;
42+
}
43+
44+
}
45+
</script>

0 commit comments

Comments
 (0)