BETA - Neopets SDB Item Tagger

Tag Safety Deposit Box items on Neopets

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         BETA - Neopets SDB Item Tagger
// @version      1.1
// @description  Tag Safety Deposit Box items on Neopets
// @author       Toothbrush
// @match        *://www.neopets.com/safetydeposit.phtml*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=neopets.com
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_listValues
// @namespace https://greasyfork.org/users/1315343
// ==/UserScript==

/**
 * 1.1: added dropdown menu for assigning tag colors
**/

(function() {
    'use strict';

    // Predefined colors for dropdown
    const colors = {
        'Red': '#e2bbb8',
        'Orange': '#f7d4ba',
        'Yellow': '#f5e8b0',
        'Green': '#bae0b1',
        'Cyan': '#b4edec',
        'Blue': '#b4d2ed',
        'Purple': '#d6bff2',
        'Pink': '#f4cbf5',
        'Grey': '#c4c2c4',
        'White': '#ffffff'
    };

    // Create a dropdown menu
    const colorDropdown = document.createElement('select');
    colorDropdown.innerHTML = '<option value="">Assign color to tag</option>';
    for (const [colorName, colorValue] of Object.entries(colors)) {
        const option = document.createElement('option');
        option.value = colorValue;
        option.textContent = colorName;
        colorDropdown.appendChild(option);
    }

    // Locate the search input field's parent row element
    const searchParentRow = document.querySelector('input[name="obj_name"]').closest('tr');

    // Create a new div to contain the dropdown
    const dropdownContainer = document.createElement('div');
    dropdownContainer.style.marginTop = '10px';
    dropdownContainer.style.marginLeft = '2px';

    // Insert the new div after the search parent row element
    searchParentRow.insertAdjacentElement('afterend', dropdownContainer);

    // Move the dropdown menu into the new div
    dropdownContainer.appendChild(colorDropdown);


    // Select all item rows
    const itemRows = document.querySelectorAll('tr[bgcolor="#F6F6F6"], tr[bgcolor="#FFFFFF"], tr[bgcolor="#DFEAF7"]');

    // Function to initialize tagging functionality for an item
    function initializeItemTagging(itemRow) {
        const nameCell = itemRow.querySelector('td:nth-child(2)');
        let inputField, addButton, removeButton;

        // Check if tag exists in local storage
        const itemName = nameCell.textContent.trim();
        const savedTag = GM_getValue(itemName);

        // Create Add Tag button
        addButton = document.createElement('button');
        addButton.textContent = 'Add Tag';
        addButton.style.marginLeft = '5px';
        addButton.style.marginTop = '5px';
        addButton.style.display = savedTag ? 'none' : 'inline-block';

        // Event listener for Add Tag button
        addButton.addEventListener('click', function(event) {
            event.preventDefault();
            addButton.style.display = 'none';
            inputField.style.display = 'block';
            inputField.focus();
        });

        // Create input field for tagging
        inputField = document.createElement('input');
        inputField.type = 'text';
        inputField.placeholder = 'Enter tag';
        inputField.style.width = '100px';
        inputField.style.marginTop = '5px';
        inputField.style.display = 'none';
        inputField.style.marginLeft = '5px';

        // Event listener for input field
        inputField.addEventListener('keydown', function(event) {
            if (event.key === 'Enter') {
                event.preventDefault();
                const tag = inputField.value.trim();
                if (tag !== '') {
                    addTag(itemRow, tag);
                    GM_setValue(itemName, tag);
                    addStoredTag(tag);
                    inputField.value = '';
                    inputField.style.display = 'none';
                    addButton.style.display = 'none';
                    addRemoveButton(itemRow, tag);
                }
            }
        });

        // Create remove button for the tag
        removeButton = document.createElement('span');
        removeButton.textContent = 'x';
        removeButton.style.cursor = 'pointer';
        removeButton.style.marginLeft = '5px';
        removeButton.style.display = savedTag ? 'inline-block' : 'none';

        // Event listener for remove button
        removeButton.addEventListener('click', function() {
            const tagSpan = nameCell.querySelector('.tag');
            if (tagSpan) {
                tagSpan.remove();
            }
            removeButton.remove();
            GM_setValue(itemName, '');
            addButton.style.display = 'inline-block';
            inputField.style.display = 'none';
        });

        // Append line break only for wearables
        if (itemRow.getAttribute('bgcolor') === '#DFEAF7') {
            nameCell.appendChild(document.createElement('br'));
        }

        // Append elements to item name cell
        nameCell.appendChild(addButton);
        nameCell.appendChild(inputField);
        if (savedTag) {
            addTag(itemRow, savedTag);
            nameCell.appendChild(removeButton);
        }
    }

    // Function to add a tag next to the item name
    function addTag(itemRow, tag) {
        const tagSpan = document.createElement('span');
        tagSpan.textContent = '⌦ ' + tag;
        tagSpan.style.marginLeft = '5px';
        tagSpan.style.marginTop = '5px';
        tagSpan.classList.add('tag');

        // Default to white background if no predefined color
        tagSpan.style.backgroundColor = GM_getValue('tagColor_' + tag, '#ffffff');
        tagSpan.style.border = '1px solid #000435';
        tagSpan.style.padding = '2px 5px';
        tagSpan.style.display = 'inline-flex';
        tagSpan.style.alignItems = 'center';
        tagSpan.style.justifyContent = 'center';
        tagSpan.style.borderRadius = '5px';
        itemRow.querySelector('td:nth-child(2)').appendChild(tagSpan);
    }

    // Function to add a stored tag to the list
    function addStoredTag(tag) {
        let storedTags = GM_getValue('storedTags', []);
        if (!storedTags.includes(tag)) {
            storedTags.push(tag);
            GM_setValue('storedTags', storedTags);
        }
    }

    // Event listener for the color dropdown
    if (colorDropdown) {
        colorDropdown.addEventListener('change', function() {
            const selectedColor = colorDropdown.value;
            const storedTags = GM_getValue('storedTags', []);
            const selectedTag = prompt('Enter the tag to assign this color to:');

            if (selectedTag && storedTags.includes(selectedTag)) {
                GM_setValue('tagColor_' + selectedTag, selectedColor);
                document.querySelectorAll('.tag').forEach(tagSpan => {
                    if (tagSpan.textContent.includes(selectedTag)) {
                        tagSpan.style.backgroundColor = selectedColor;
                    }
                });
            }
            colorDropdown.value = ''; // Reset dropdown after selection
        });
    }

    // Function to add remove button next to the tag
    function addRemoveButton(itemRow, tag) {
        const nameCell = itemRow.querySelector('td:nth-child(2)');
        const removeButton = document.createElement('span');
        removeButton.textContent = 'x';
        removeButton.style.cursor = 'pointer';
        removeButton.style.marginLeft = '5px';
        removeButton.addEventListener('click', function() {
            const tagSpan = nameCell.querySelector('.tag');
            if (tagSpan) {
                tagSpan.remove();
            }
            removeButton.remove();
            GM_setValue(nameCell.textContent.trim(), '');
        });
        nameCell.appendChild(removeButton);
    }

    // Function to initialize tagging functionality for all items
    function initializeTagging() {
        itemRows.forEach(function(itemRow) {
            initializeItemTagging(itemRow);
        });
    }

    // Call the initialization function
    initializeTagging();
})();