Autosave form Inputs and Display 15-Item History

Autosaves and displays the last 15 entries of a single input field. Entries are saved on Enter or button click, and can be recovered or deleted.

当前为 2024-08-10 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Autosave form Inputs and Display 15-Item History
  3. // @namespace http://tampermonkey.net/
  4. // @version 2024-08-08
  5. // @description Autosaves and displays the last 15 entries of a single input field. Entries are saved on Enter or button click, and can be recovered or deleted.
  6. // @author Lawrence d'Aniello
  7. // @match https://example.com/* // Customize to match your target website
  8. // @license MIT
  9. // @grant none
  10. // @website https://www.comune.roma.it/web/it/istituzione-biblioteche-di-roma-uffici-e-contatti.page?contentId=UFF36376
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. // Example selectors - change these to match the specific site
  17. const inputField = document.querySelector('input[type="text"]'); // Change CSS selector to match your input field
  18. const searchButton = document.querySelector('button'); // Change CSS selector to match your search button
  19.  
  20. inputField.setAttribute('autocomplete', 'off');
  21.  
  22. let savedInputEntries = JSON.parse(localStorage.getItem('savedInputEntries')) || [];
  23.  
  24. function updateSavedInputEntries(newEntry) {
  25. if (newEntry.trim() !== "" && !savedInputEntries.includes(newEntry)) {
  26. savedInputEntries.push(newEntry);
  27. if (savedInputEntries.length > 15) {
  28. savedInputEntries.shift();
  29. }
  30. localStorage.setItem('savedInputEntries', JSON.stringify(savedInputEntries));
  31. displaySavedInputEntries();
  32. }
  33. }
  34.  
  35. function deleteEntry(entryToDelete) {
  36. savedInputEntries = savedInputEntries.filter(entry => entry !== entryToDelete);
  37. localStorage.setItem('savedInputEntries', JSON.stringify(savedInputEntries));
  38. displaySavedInputEntries();
  39. }
  40.  
  41. function displaySavedInputEntries() {
  42. let existingDropdown = document.getElementById('savedInputEntriesDropdown');
  43. if (existingDropdown) {
  44. existingDropdown.remove();
  45. }
  46.  
  47. const dropdown = document.createElement('ul');
  48. dropdown.id = 'savedInputEntriesDropdown';
  49. dropdown.style.listStyleType = 'none';
  50. dropdown.style.padding = '5px';
  51. dropdown.style.border = '1px solid #ccc';
  52. dropdown.style.position = 'absolute';
  53. dropdown.style.backgroundColor = '#fff';
  54. dropdown.style.zIndex = '1000';
  55. dropdown.style.maxHeight = '150px';
  56. dropdown.style.overflowY = 'auto';
  57.  
  58. const inputRect = inputField.getBoundingClientRect();
  59. dropdown.style.left = `${inputRect.left}px`;
  60. dropdown.style.top = `${inputRect.bottom + window.scrollY}px`;
  61. dropdown.style.width = `${inputRect.width}px`;
  62.  
  63. const uniqueEntries = new Set(savedInputEntries);
  64.  
  65. Array.from(uniqueEntries).reverse().forEach(entry => {
  66. const listItem = document.createElement('li');
  67. listItem.style.display = 'flex';
  68. listItem.style.justifyContent = 'space-between';
  69. listItem.style.padding = '5px';
  70. listItem.style.cursor = 'pointer';
  71. listItem.style.position = 'relative';
  72. listItem.style.transition = 'background-color 0.3s, color 0.3s';
  73. listItem.textContent = entry;
  74.  
  75. // Hover styles
  76. listItem.addEventListener('mouseover', function() {
  77. listItem.style.backgroundColor = '#f0f0f0';
  78. listItem.style.color = '#333';
  79. deleteButton.style.display = 'inline';
  80. });
  81. listItem.addEventListener('mouseout', function() {
  82. listItem.style.backgroundColor = '#fff';
  83. listItem.style.color = '#000';
  84. deleteButton.style.display = 'none';
  85. });
  86.  
  87. const deleteButton = document.createElement('button');
  88. deleteButton.textContent = '✖';
  89. deleteButton.style.display = 'none';
  90. deleteButton.style.background = 'none';
  91. deleteButton.style.border = 'none';
  92. deleteButton.style.color = 'red';
  93. deleteButton.style.cursor = 'pointer';
  94. deleteButton.style.position = 'absolute';
  95. deleteButton.style.right = '10px';
  96. deleteButton.style.top = '50%';
  97. deleteButton.style.transform = 'translateY(-50%)';
  98. deleteButton.addEventListener('click', function(event) {
  99. event.stopPropagation();
  100. deleteEntry(entry);
  101. });
  102.  
  103. listItem.appendChild(deleteButton);
  104.  
  105. listItem.addEventListener('click', function() {
  106. inputField.value = entry;
  107. hideSavedInputEntries();
  108. inputField.focus();
  109. });
  110. dropdown.appendChild(listItem);
  111. });
  112.  
  113. document.body.appendChild(dropdown);
  114. }
  115.  
  116. function hideSavedInputEntries() {
  117. let existingDropdown = document.getElementById('savedInputEntriesDropdown');
  118. if (existingDropdown) {
  119. existingDropdown.remove();
  120. }
  121. }
  122.  
  123. function handleClick(event) {
  124. if (event.target !== inputField && !inputField.contains(event.target)) {
  125. hideSavedInputEntries();
  126. } else if (event.target === inputField) {
  127. displaySavedInputEntries();
  128. }
  129. }
  130.  
  131. inputField.addEventListener('focus', function() {
  132. // Debounce the display function to prevent flickering
  133. setTimeout(displaySavedInputEntries, 100);
  134. });
  135.  
  136. document.addEventListener('click', handleClick);
  137.  
  138. inputField.addEventListener('input', function() {
  139. hideSavedInputEntries();
  140. });
  141.  
  142. inputField.addEventListener('keydown', function(event) {
  143. if (event.key === 'Enter') {
  144. updateSavedInputEntries(inputField.value);
  145. hideSavedInputEntries();
  146. }
  147. });
  148.  
  149. searchButton.addEventListener('click', function() {
  150. updateSavedInputEntries(inputField.value);
  151. hideSavedInputEntries();
  152. });
  153.  
  154. window.addEventListener('resize', function() {
  155. let dropdown = document.getElementById('savedInputEntriesDropdown');
  156. if (dropdown) {
  157. const inputRect = inputField.getBoundingClientRect();
  158. dropdown.style.left = `${inputRect.left}px`;
  159. dropdown.style.top = `${inputRect.bottom + window.scrollY}px`;
  160. dropdown.style.width = `${inputRect.width}px`;
  161. }
  162. });
  163. })();