|
2 | 2 | import { ref } from 'vue'; |
3 | 3 | const props = defineProps<{ |
4 | 4 | disabled?: boolean; |
5 | | - addFile?: (e: Event) => void; |
| 5 | + addFile?: (e: Event, id?: string) => void; |
| 6 | + removeFile?: (id: string) => void; |
6 | 7 | searchError?: boolean; |
7 | 8 | }>(); |
8 | | -const inputGroupLength = ref(1); |
| 9 | +const inputGroupLength = ref(document.querySelectorAll('.input-group input').length || 1); |
| 10 | +const uid = ref(0); |
| 11 | +const inputGroupRef = ref<HTMLElement | null>(null); |
| 12 | +const inputContainerRef = ref<HTMLElement | null>(null); |
| 13 | +const fileInputRef = ref<HTMLInputElement | null>(null); |
| 14 | +const deleteButtonRef = ref<HTMLButtonElement | null>(null); |
| 15 | +
|
| 16 | +const updateInputGroupLength = () => { |
| 17 | + inputGroupLength.value = document.querySelectorAll('.input-group input').length; |
| 18 | +}; |
| 19 | +
|
| 20 | +const createInput = (id: string) => { |
| 21 | + const input = fileInputRef.value?.cloneNode(false) as HTMLInputElement; |
| 22 | + input.id = id; |
| 23 | + input.files = new DataTransfer().files; // Clear previous files |
| 24 | + input.addEventListener('change', (e) => props.addFile(e, id)); |
| 25 | + return input; |
| 26 | +}; |
| 27 | +
|
| 28 | +const createDeletebutton = (container: HTMLElement) => { |
| 29 | + const delButton = deleteButtonRef.value?.cloneNode(true) as HTMLButtonElement; |
| 30 | + delButton.addEventListener('click', () => { |
| 31 | + props.removeFile(container.id); |
| 32 | + if (container && container.parentNode === inputGroupRef.value) { |
| 33 | + inputGroupRef.value.removeChild(container); |
| 34 | + } |
| 35 | + updateInputGroupLength(); |
| 36 | + }); |
| 37 | + return delButton; |
| 38 | +}; |
9 | 39 |
|
10 | | -// TODO: think of a vue way of doing this |
11 | 40 | const appendNewInputFile = () => { |
12 | | - const inputGroup = document.querySelector('.input-group'); |
13 | | - const div = document.createElement('div'); |
14 | | - div.className = 'is-flex is-flex-direction-row'; |
15 | | - const deleteButton = document.createElement('button'); |
16 | | - deleteButton.className = 'button'; |
17 | | - deleteButton.innerHTML = 'x'; |
18 | | - deleteButton.onclick = () => { |
19 | | - inputGroup.removeChild(div); |
20 | | - inputGroupLength.value -= 1; |
21 | | - }; |
22 | | - const input = document.createElement('input'); |
23 | | - input.id = `file-${inputGroupLength.value}`; |
24 | | - input.type = 'file'; |
25 | | - input.className = 'input'; |
26 | | - input.accept = 'application/pdf, text/*'; |
27 | | - input.placeholder = 'Enter the new file'; |
28 | | - input.setAttribute('data-testid', 'file-input'); |
29 | | - input.onchange = (e) => props.addFile(e); |
30 | | - div.appendChild(input); |
31 | | - div.appendChild(deleteButton); |
32 | | - inputGroup.appendChild(div); |
33 | | - inputGroupLength.value += 1; |
| 41 | + if (!inputGroupRef.value || !inputContainerRef.value) { |
| 42 | + console.error('Input group is not defined'); |
| 43 | + return; |
| 44 | + } |
| 45 | +
|
| 46 | + const elementId = `file_${++uid.value}`; |
| 47 | +
|
| 48 | + const container = inputContainerRef.value.cloneNode(false) as HTMLElement; |
| 49 | + container.id = elementId; |
| 50 | + const input = createInput(elementId); |
| 51 | + const delButton = createDeletebutton(container); |
| 52 | +
|
| 53 | + container.appendChild(input); |
| 54 | + container.appendChild(delButton); |
| 55 | + inputGroupRef.value.appendChild(container); |
| 56 | + updateInputGroupLength(); |
34 | 57 | }; |
35 | 58 |
|
36 | 59 | const removeFirstChild = () => { |
37 | | - const inputGroup = document.querySelector('.input-group'); |
| 60 | + const inputGroup = inputGroupRef.value; |
38 | 61 | inputGroup.removeChild(inputGroup.firstChild); |
39 | | - inputGroupLength.value -= 1; |
| 62 | + props.removeFile('file_0'); |
| 63 | + updateInputGroupLength(); |
40 | 64 | }; |
41 | 65 |
|
42 | 66 | const removeLastInputFile = () => { |
43 | 67 | const inputGroup = document.querySelector('.input-group'); |
44 | 68 | inputGroup.removeChild(inputGroup.lastChild); |
45 | | - inputGroupLength.value -= 1; |
| 69 | + props.removeFile(`file_${inputGroupLength.value}`); |
| 70 | + updateInputGroupLength(); |
46 | 71 | }; |
47 | 72 | </script> |
48 | 73 | <template> |
@@ -79,17 +104,26 @@ const removeLastInputFile = () => { |
79 | 104 | </div> |
80 | 105 | </div> |
81 | 106 | <div> |
82 | | - <div class="input-group is-flex is-flex-direction-column"> |
83 | | - <div class="is-flex is-flex-direction-row" id="first"> |
| 107 | + <div ref="inputGroupRef" class="input-group is-flex is-flex-direction-column"> |
| 108 | + <div ref="inputContainerRef" class="is-flex is-flex-direction-row" id="first"> |
84 | 109 | <input |
| 110 | + ref="fileInputRef" |
85 | 111 | class="input" |
86 | 112 | type="file" |
87 | 113 | accept="application/pdf, text/*" |
| 114 | +<<<<<<< HEAD |
88 | 115 | placeholder="Enter the new file" |
89 | 116 | data-testid="file-input" |
90 | 117 | @change="addFile" |
| 118 | +||||||| parent of aeaf9fa (feat(tutor): fix how files are handled when added, removed, replaced) |
| 119 | + placeholder="Enter the name of the file" |
| 120 | + @change="addFile" |
| 121 | +======= |
| 122 | + placeholder="Enter the name of the file" |
| 123 | + @change="(e) => addFile(e, 'file_0')" |
| 124 | +>>>>>>> aeaf9fa (feat(tutor): fix how files are handled when added, removed, replaced) |
91 | 125 | /> |
92 | | - <button class="button" @click="removeFirstChild">x</button> |
| 126 | + <button ref="deleteButtonRef" class="button" @click="removeFirstChild">x</button> |
93 | 127 | </div> |
94 | 128 | </div> |
95 | 129 | <button class="button" :disabled="inputGroupLength === 3" @click="appendNewInputFile"> |
|
0 commit comments