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 提交的版本。查看 最新版本

// ==UserScript==
// @name         Autosave form Inputs and Display 15-Item History
// @namespace    http://tampermonkey.net/
// @version      2024-08-08
// @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.
// @author       Lawrence d'Aniello
// @match        https://example.com/* // Customize to match your target website
// @license      MIT
// @grant        none
// @website      https://www.comune.roma.it/web/it/istituzione-biblioteche-di-roma-uffici-e-contatti.page?contentId=UFF36376
// ==/UserScript==

(function() {
    'use strict';

    // Example selectors - change these to match the specific site
    const inputField = document.querySelector('input[type="text"]'); // Change CSS selector to match your input field
    const searchButton = document.querySelector('button'); // Change CSS selector to match your search button

    inputField.setAttribute('autocomplete', 'off');

    let savedInputEntries = JSON.parse(localStorage.getItem('savedInputEntries')) || [];

    function updateSavedInputEntries(newEntry) {
        if (newEntry.trim() !== "" && !savedInputEntries.includes(newEntry)) {
            savedInputEntries.push(newEntry);
            if (savedInputEntries.length > 15) {
                savedInputEntries.shift();
            }
            localStorage.setItem('savedInputEntries', JSON.stringify(savedInputEntries));
            displaySavedInputEntries();
        }
    }

    function deleteEntry(entryToDelete) {
        savedInputEntries = savedInputEntries.filter(entry => entry !== entryToDelete);
        localStorage.setItem('savedInputEntries', JSON.stringify(savedInputEntries));
        displaySavedInputEntries();
    }

    function displaySavedInputEntries() {
        let existingDropdown = document.getElementById('savedInputEntriesDropdown');
        if (existingDropdown) {
            existingDropdown.remove();
        }

        const dropdown = document.createElement('ul');
        dropdown.id = 'savedInputEntriesDropdown';
        dropdown.style.listStyleType = 'none';
        dropdown.style.padding = '5px';
        dropdown.style.border = '1px solid #ccc';
        dropdown.style.position = 'absolute';
        dropdown.style.backgroundColor = '#fff';
        dropdown.style.zIndex = '1000';
        dropdown.style.maxHeight = '150px';
        dropdown.style.overflowY = 'auto';

        const inputRect = inputField.getBoundingClientRect();
        dropdown.style.left = `${inputRect.left}px`;
        dropdown.style.top = `${inputRect.bottom + window.scrollY}px`;
        dropdown.style.width = `${inputRect.width}px`;

        const uniqueEntries = new Set(savedInputEntries);

        Array.from(uniqueEntries).reverse().forEach(entry => {
            const listItem = document.createElement('li');
            listItem.style.display = 'flex';
            listItem.style.justifyContent = 'space-between';
            listItem.style.padding = '5px';
            listItem.style.cursor = 'pointer';
            listItem.style.position = 'relative';
            listItem.style.transition = 'background-color 0.3s, color 0.3s';
            listItem.textContent = entry;

            // Hover styles
            listItem.addEventListener('mouseover', function() {
                listItem.style.backgroundColor = '#f0f0f0';
                listItem.style.color = '#333';
                deleteButton.style.display = 'inline';
            });
            listItem.addEventListener('mouseout', function() {
                listItem.style.backgroundColor = '#fff';
                listItem.style.color = '#000';
                deleteButton.style.display = 'none';
            });

            const deleteButton = document.createElement('button');
            deleteButton.textContent = '✖';
            deleteButton.style.display = 'none';
            deleteButton.style.background = 'none';
            deleteButton.style.border = 'none';
            deleteButton.style.color = 'red';
            deleteButton.style.cursor = 'pointer';
            deleteButton.style.position = 'absolute';
            deleteButton.style.right = '10px';
            deleteButton.style.top = '50%';
            deleteButton.style.transform = 'translateY(-50%)';
            deleteButton.addEventListener('click', function(event) {
                event.stopPropagation();
                deleteEntry(entry);
            });

            listItem.appendChild(deleteButton);

            listItem.addEventListener('click', function() {
                inputField.value = entry;
                hideSavedInputEntries();
                inputField.focus();
            });
            dropdown.appendChild(listItem);
        });

        document.body.appendChild(dropdown);
    }

    function hideSavedInputEntries() {
        let existingDropdown = document.getElementById('savedInputEntriesDropdown');
        if (existingDropdown) {
            existingDropdown.remove();
        }
    }

    function handleClick(event) {
        if (event.target !== inputField && !inputField.contains(event.target)) {
            hideSavedInputEntries();
        } else if (event.target === inputField) {
            displaySavedInputEntries();
        }
    }

    inputField.addEventListener('focus', function() {
        // Debounce the display function to prevent flickering
        setTimeout(displaySavedInputEntries, 100);
    });

    document.addEventListener('click', handleClick);

    inputField.addEventListener('input', function() {
        hideSavedInputEntries();
    });

    inputField.addEventListener('keydown', function(event) {
        if (event.key === 'Enter') {
            updateSavedInputEntries(inputField.value);
            hideSavedInputEntries();
        }
    });

    searchButton.addEventListener('click', function() {
        updateSavedInputEntries(inputField.value);
        hideSavedInputEntries();
    });

    window.addEventListener('resize', function() {
        let dropdown = document.getElementById('savedInputEntriesDropdown');
        if (dropdown) {
            const inputRect = inputField.getBoundingClientRect();
            dropdown.style.left = `${inputRect.left}px`;
            dropdown.style.top = `${inputRect.bottom + window.scrollY}px`;
            dropdown.style.width = `${inputRect.width}px`;
        }
    });
})();