script.js 6.4 KB

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