main.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. // log htmx on dev
  2. // htmx.logAll();
  3. // add text/html accept header to receive html instead of json for the requests
  4. document.body.addEventListener('htmx:configRequest', function(evt) {
  5. evt.detail.headers["Accept"] = "text/html,*/*";
  6. });
  7. // an htmx extension to use the specifed params in the path instead of the query or body
  8. htmx.defineExtension("path-params", {
  9. onEvent: function(name, evt) {
  10. if (name === "htmx:configRequest") {
  11. evt.detail.path = evt.detail.path.replace(/{([^}]+)}/g, function(_, param) {
  12. var val = evt.detail.parameters[param]
  13. delete evt.detail.parameters[param]
  14. return val === undefined ? '{' + param + '}' : encodeURIComponent(val)
  15. })
  16. }
  17. }
  18. })
  19. // find closest element
  20. function closest(selector) {
  21. let element = this;
  22. while (element && element.nodeType === 1) {
  23. if (element.matches(selector)) {
  24. return element;
  25. }
  26. element = element.parentNode;
  27. }
  28. return null;
  29. };
  30. // copy the link to clipboard
  31. function handleCopyLink(element) {
  32. navigator.clipboard.writeText(element.dataset.url);
  33. }
  34. // copy the link and toggle copy button style
  35. function handleShortURLCopyLink(element) {
  36. handleCopyLink(element);
  37. const parent = document.querySelector("#shorturl");
  38. if (!parent || parent.classList.contains("copied")) return;
  39. parent.classList.add("copied");
  40. setTimeout(function() {
  41. parent.classList.remove("copied");
  42. }, 1000);
  43. }
  44. // TODO: make it an extension
  45. // open and close dialog
  46. function openDialog(id) {
  47. const dialog = document.getElementById(id);
  48. if (!dialog) return;
  49. dialog.classList.add("open");
  50. }
  51. function closeDialog() {
  52. const dialog = document.querySelector(".dialog");
  53. if (!dialog) return;
  54. dialog.classList.remove("open");
  55. }
  56. window.addEventListener("click", function(event) {
  57. const dialog = document.querySelector(".dialog");
  58. if (dialog && event.target === dialog) {
  59. closeDialog();
  60. }
  61. });
  62. // handle navigation in the table of links
  63. function setLinksLimit(event) {
  64. const buttons = Array.from(document.querySelectorAll('table .nav .limit button'));
  65. const limitInput = document.querySelector('#limit');
  66. if (!limitInput || !buttons || !buttons.length) return;
  67. limitInput.value = event.target.textContent;
  68. buttons.forEach(b => {
  69. b.disabled = b.textContent === event.target.textContent;
  70. });
  71. }
  72. function setLinksSkip(event, action) {
  73. const buttons = Array.from(document.querySelectorAll('table .nav .pagination button'));
  74. const limitElm = document.querySelector('#limit');
  75. const totalElm = document.querySelector('#total');
  76. const skipElm = document.querySelector('#skip');
  77. if (!buttons || !limitElm || !totalElm || !skipElm) return;
  78. const skip = parseInt(skipElm.value);
  79. const limit = parseInt(limitElm.value);
  80. const total = parseInt(totalElm.value);
  81. skipElm.value = action === "next" ? skip + limit : Math.max(skip - limit, 0);
  82. document.querySelectorAll('.pagination .next').forEach(elm => {
  83. elm.disabled = total <= parseInt(skipElm.value) + limit;
  84. });
  85. document.querySelectorAll('.pagination .prev').forEach(elm => {
  86. elm.disabled = parseInt(skipElm.value) <= 0;
  87. });
  88. }
  89. function updateLinksNav() {
  90. const totalElm = document.querySelector('#total');
  91. const skipElm = document.querySelector('#skip');
  92. const limitElm = document.querySelector('#limit');
  93. if (!totalElm || !skipElm || !limitElm) return;
  94. const total = parseInt(totalElm.value);
  95. const skip = parseInt(skipElm.value);
  96. const limit = parseInt(limitElm.value);
  97. document.querySelectorAll('.pagination .next').forEach(elm => {
  98. elm.disabled = total <= skip + limit;
  99. });
  100. document.querySelectorAll('.pagination .prev').forEach(elm => {
  101. elm.disabled = skip <= 0;
  102. });
  103. }
  104. function resetLinkNav() {
  105. const totalElm = document.querySelector('#total');
  106. const skipElm = document.querySelector('#skip');
  107. const limitElm = document.querySelector('#limit');
  108. if (!totalElm || !skipElm || !limitElm) return;
  109. skipElm.value = 0;
  110. limitElm.value = 10;
  111. const skip = parseInt(skipElm.value);
  112. const limit = parseInt(limitElm.value);
  113. document.querySelectorAll('.pagination .next').forEach(elm => {
  114. elm.disabled = total <= skip + limit;
  115. });
  116. document.querySelectorAll('.pagination .prev').forEach(elm => {
  117. elm.disabled = skip <= 0;
  118. });
  119. document.querySelectorAll('table .nav .limit button').forEach(b => {
  120. b.disabled = b.textContent === limit.toString();
  121. });
  122. }