script.js 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. // Select the file input element
  2. const fileInput = document.querySelector('input[type="file"]');
  3. const dropZone = document.getElementById("dropzone");
  4. const fileNames = [];
  5. let fileType;
  6. dropZone.addEventListener("dragover", () => {
  7. dropZone.classList.add("dragover");
  8. });
  9. dropZone.addEventListener("dragleave", () => {
  10. dropZone.classList.remove("dragover");
  11. });
  12. dropZone.addEventListener("drop", () => {
  13. dropZone.classList.remove("dragover");
  14. });
  15. const selectContainer = document.querySelector("form .select_container");
  16. const updateSearchBar = () => {
  17. const convertToInput = document.querySelector(
  18. "input[name='convert_to_search']",
  19. );
  20. const convertToPopup = document.querySelector(".convert_to_popup");
  21. const convertToGroupElements = document.querySelectorAll(".convert_to_group");
  22. const convertToGroups = {};
  23. const convertToElement = document.querySelector("select[name='convert_to']");
  24. const convertButton = document.querySelector("input[type='submit']");
  25. const showMatching = (search) => {
  26. for (const [targets, groupElement] of Object.values(convertToGroups)) {
  27. let matchingTargetsFound = 0;
  28. for (const target of targets) {
  29. if (target.dataset.target.includes(search)) {
  30. matchingTargetsFound++;
  31. target.classList.remove("hidden");
  32. target.classList.add("flex");
  33. } else {
  34. target.classList.add("hidden");
  35. target.classList.remove("flex");
  36. }
  37. }
  38. if (matchingTargetsFound === 0) {
  39. groupElement.classList.add("hidden");
  40. groupElement.classList.remove("flex");
  41. } else {
  42. groupElement.classList.remove("hidden");
  43. groupElement.classList.add("flex");
  44. }
  45. }
  46. };
  47. for (const groupElement of convertToGroupElements) {
  48. const groupName = groupElement.dataset.converter;
  49. const targetElements = groupElement.querySelectorAll(".target");
  50. const targets = Array.from(targetElements);
  51. for (const target of targets) {
  52. target.onmousedown = () => {
  53. convertToElement.value = target.dataset.value;
  54. convertToInput.value = `${target.dataset.target} using ${target.dataset.converter}`;
  55. convertButton.disabled = false;
  56. showMatching("");
  57. };
  58. }
  59. convertToGroups[groupName] = [targets, groupElement];
  60. }
  61. convertToInput.addEventListener("input", (e) => {
  62. showMatching(e.target.value.toLowerCase());
  63. });
  64. convertToInput.addEventListener("search", () => {
  65. // when the user clears the search bar using the 'x' button
  66. convertButton.disabled = true;
  67. });
  68. convertToInput.addEventListener("blur", (e) => {
  69. // Keep the popup open even when clicking on a target button
  70. // for a split second to allow the click to go through
  71. if (e?.relatedTarget?.classList?.contains("target")) {
  72. convertToPopup.classList.add("hidden");
  73. convertToPopup.classList.remove("flex");
  74. return;
  75. }
  76. convertToPopup.classList.add("hidden");
  77. convertToPopup.classList.remove("flex");
  78. });
  79. convertToInput.addEventListener("focus", () => {
  80. convertToPopup.classList.remove("hidden");
  81. convertToPopup.classList.add("flex");
  82. });
  83. };
  84. // const convertFromSelect = document.querySelector("select[name='convert_from']");
  85. // Add a 'change' event listener to the file input element
  86. fileInput.addEventListener("change", (e) => {
  87. // console.log(e.target.files);
  88. // Get the selected files from the event target
  89. const files = e.target.files;
  90. // Select the file-list table
  91. const fileList = document.querySelector("#file-list");
  92. // Loop through the selected files
  93. for (const file of files) {
  94. // Create a new table row for each file
  95. const row = document.createElement("tr");
  96. row.innerHTML = `
  97. <td>${file.name}</td>
  98. <td>${(file.size / 1024).toFixed(2)} kB</td>
  99. <td><a onclick="deleteRow(this)">Remove</a></td>
  100. `;
  101. if (!fileType) {
  102. fileType = file.name.split(".").pop();
  103. fileInput.setAttribute("accept", `.${fileType}`);
  104. setTitle();
  105. // choose the option that matches the file type
  106. // for (const option of convertFromSelect.children) {
  107. // console.log(option.value);
  108. // if (option.value === fileType) {
  109. // option.selected = true;
  110. // }
  111. // }
  112. fetch("/conversions", {
  113. method: "POST",
  114. body: JSON.stringify({ fileType: fileType }),
  115. headers: {
  116. "Content-Type": "application/json",
  117. },
  118. })
  119. .then((res) => res.text())
  120. .then((html) => {
  121. selectContainer.innerHTML = html;
  122. updateSearchBar();
  123. })
  124. .catch((err) => console.log(err));
  125. }
  126. // Append the row to the file-list table
  127. fileList.appendChild(row);
  128. // Append the file to the hidden input
  129. fileNames.push(file.name);
  130. }
  131. uploadFiles(files);
  132. });
  133. const setTitle = () => {
  134. const title = document.querySelector("h1");
  135. title.textContent = `Convert ${fileType ? `.${fileType}` : ""}`;
  136. };
  137. // Add a onclick for the delete button
  138. // eslint-disable-next-line @typescript-eslint/no-unused-vars
  139. const deleteRow = (target) => {
  140. const filename = target.parentElement.parentElement.children[0].textContent;
  141. const row = target.parentElement.parentElement;
  142. row.remove();
  143. // remove from fileNames
  144. const index = fileNames.indexOf(filename);
  145. fileNames.splice(index, 1);
  146. // if fileNames is empty, reset fileType
  147. if (fileNames.length === 0) {
  148. fileType = null;
  149. fileInput.removeAttribute("accept");
  150. setTitle();
  151. }
  152. fetch("/delete", {
  153. method: "POST",
  154. body: JSON.stringify({ filename: filename }),
  155. headers: {
  156. "Content-Type": "application/json",
  157. },
  158. })
  159. .then((res) => res.json())
  160. .then((data) => {
  161. console.log(data);
  162. })
  163. .catch((err) => console.log(err));
  164. };
  165. const uploadFiles = (files) => {
  166. const formData = new FormData();
  167. for (const file of files) {
  168. formData.append("file", file, file.name);
  169. }
  170. fetch("/upload", {
  171. method: "POST",
  172. body: formData,
  173. })
  174. .then((res) => res.json())
  175. .then((data) => {
  176. console.log(data);
  177. })
  178. .catch((err) => console.log(err));
  179. };
  180. const formConvert = document.querySelector("form[action='/convert']");
  181. formConvert.addEventListener("submit", () => {
  182. const hiddenInput = document.querySelector("input[name='file_names']");
  183. hiddenInput.value = JSON.stringify(fileNames);
  184. });
  185. updateSearchBar();