Advertisement
vindree

Tag Sorter

Nov 17th, 2024 (edited)
16
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
HTML 6.78 KB | Source Code | 0 0
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4.   <meta charset="UTF-8">
  5.   <meta name="viewport" content="width=device-width, initial-scale=1.0">
  6.   <title>Tag sorter</title>
  7.   <style>
  8.     body {
  9.       font-family: Arial, sans-serif;
  10.       margin: 0;
  11.       padding: 0;
  12.       display: flex;
  13.       flex-direction: column;
  14.       align-items: center;
  15.       justify-content: center;
  16.       min-height: 100vh;
  17.       background-color: #f4f4f4;
  18.     }
  19.     h1 {
  20.       color: #333;
  21.     }
  22.     textarea {
  23.       width: 90%;
  24.       max-width: 600px;
  25.       height: 100px;
  26.       margin-bottom: 10px;
  27.       padding: 10px;
  28.       font-size: 16px;
  29.       border: 1px solid #ccc;
  30.       border-radius: 5px;
  31.     }
  32.     .grid {
  33.       display: flex;
  34.       flex-wrap: wrap;
  35.       gap: 10px;
  36.       width: 90%;
  37.       max-width: 600px;
  38.       min-height: 100px;
  39.       padding: 10px;
  40.       background: #fff;
  41.       border: 1px solid #ccc;
  42.       border-radius: 5px;
  43.       margin-bottom: 10px;
  44.     }
  45.     .block {
  46.       padding: 10px 20px;
  47.       background-color: #007BFF;
  48.       color: white;
  49.       border-radius: 5px;
  50.       cursor: grab;
  51.       user-select: none;
  52.     }
  53.     .block.duplicate {
  54.       background-color: #FF5733;
  55.     }
  56.     .placeholder {
  57.       width: 40px; /* About 2 characters wide */
  58.       height: 20px; /* Matches block height */
  59.       background-color: #ffeb3b;
  60.       border-radius: 3px;
  61.     }
  62.     .controls {
  63.       display: flex;
  64.       gap: 10px;
  65.       margin-bottom: 10px;
  66.     }
  67.     .controls button {
  68.       padding: 10px 15px;
  69.       background-color: #007BFF;
  70.       color: white;
  71.       border: none;
  72.       border-radius: 5px;
  73.       cursor: pointer;
  74.     }
  75.     .controls button:hover {
  76.       background-color: #0056b3;
  77.     }
  78.     .last-moved {
  79.       width: 90%;
  80.       max-width: 600px;
  81.       padding: 10px;
  82.       background: #e8f5e9;
  83.       border: 1px solid #a5d6a7;
  84.       border-radius: 5px;
  85.       font-size: 16px;
  86.       color: #388e3c;
  87.     }
  88.   </style>
  89. </head>
  90. <body>
  91.   <h1>Tag sorter</h1>
  92.   <textarea id="input" placeholder="Enter comma-separated values here..."></textarea>
  93.   <div class="controls">
  94.     <button id="copy">Copy to Clipboard</button>
  95.     <button id="sort-alpha">Sort Alphabetically</button>
  96.     <button id="sort-length">Sort by Length</button>
  97.   </div>
  98.   <div class="grid" id="grid"></div>
  99.   <div class="last-moved" id="lastMoved">Last moved block: <span id="lastMovedText">None</span></div>
  100.  
  101.   <script>
  102.     const input = document.getElementById('input');
  103.     const grid = document.getElementById('grid');
  104.     const copyButton = document.getElementById('copy');
  105.     const sortAlphaButton = document.getElementById('sort-alpha');
  106.     const sortLengthButton = document.getElementById('sort-length');
  107.     const lastMoved = document.getElementById('lastMovedText');
  108.     let sortAlphaAscending = true;
  109.     let sortLengthAscending = true;
  110.  
  111.     input.addEventListener('input', () => {
  112.       const values = input.value.split(',').map(v => v.trim()).filter(v => v);
  113.       renderBlocks(values);
  114.     });
  115.  
  116.     const renderBlocks = (values) => {
  117.       grid.innerHTML = ''; // Clear existing blocks
  118.       values.forEach(value => {
  119.         const block = document.createElement('div');
  120.         block.className = 'block';
  121.         block.textContent = value;
  122.         block.draggable = true;
  123.  
  124.         // Drag and drop events
  125.         block.addEventListener('dragstart', handleDragStart);
  126.         block.addEventListener('dragover', handleDragOver);
  127.         block.addEventListener('drop', handleDrop);
  128.         block.addEventListener('dragend', handleDragEnd);
  129.  
  130.         grid.appendChild(block);
  131.       });
  132.       updateInput();
  133.     };
  134.  
  135.     let draggedElement = null;
  136.     let placeholder = null;
  137.     let offsetX = 0;
  138.     let offsetY = 0;
  139.  
  140.     const handleDragStart = (event) => {
  141.       draggedElement = event.target;
  142.  
  143.       // Calculate offset between mouse and block position
  144.       const rect = draggedElement.getBoundingClientRect();
  145.       offsetX = event.clientX - rect.left;
  146.       offsetY = event.clientY - rect.top;
  147.  
  148.       lastMoved.textContent = draggedElement.textContent;
  149.       findDuplicates(draggedElement.textContent);
  150.     };
  151.  
  152.     const handleDragOver = (event) => {
  153.       event.preventDefault(); // Necessary for drop to work
  154.       if (!placeholder) {
  155.         placeholder = document.createElement('div');
  156.         placeholder.className = 'placeholder';
  157.       }
  158.       const target = event.target;
  159.       if (target.className.includes('block') && target !== draggedElement) {
  160.        const rect = target.getBoundingClientRect();
  161.         const dropPosition = event.clientX - rect.left + offsetX; // Adjust for offset
  162.         if (dropPosition < rect.width / 2) {
  163.          grid.insertBefore(placeholder, target);
  164.        } else {
  165.          grid.insertBefore(placeholder, target.nextSibling);
  166.        }
  167.      }
  168.    };
  169.  
  170.    const handleDrop = (event) => {
  171.       event.preventDefault();
  172.       if (placeholder) {
  173.         grid.insertBefore(draggedElement, placeholder);
  174.         placeholder.remove();
  175.         placeholder = null;
  176.         updateInput();
  177.       }
  178.     };
  179.  
  180.     const handleDragEnd = () => {
  181.       if (placeholder) {
  182.         placeholder.remove();
  183.         placeholder = null;
  184.       }
  185.     };
  186.  
  187.     const updateInput = () => {
  188.       const blocks = Array.from(grid.children).map(block => block.textContent);
  189.       input.value = blocks.join(', ');
  190.     };
  191.  
  192.     const findDuplicates = (lastMovedText) => {
  193.       const words = lastMovedText.split(' ');
  194.       const blocks = Array.from(grid.children);
  195.       blocks.forEach(block => {
  196.         const blockWords = block.textContent.split(' ');
  197.         const hasDuplicate = words.some(word => blockWords.includes(word));
  198.         block.classList.toggle('duplicate', hasDuplicate);
  199.       });
  200.     };
  201.  
  202.     // Copy to Clipboard
  203.     copyButton.addEventListener('click', () => {
  204.       input.select();
  205.       document.execCommand('copy');
  206.       alert('Copied to clipboard!');
  207.     });
  208.  
  209.     // Sort Alphabetically (Toggle between ascending and descending)
  210.     sortAlphaButton.addEventListener('click', () => {
  211.       const values = input.value.split(',').map(v => v.trim()).filter(v => v);
  212.       values.sort((a, b) => sortAlphaAscending ? a.localeCompare(b) : b.localeCompare(a));
  213.       sortAlphaAscending = !sortAlphaAscending; // Toggle the sort order
  214.       renderBlocks(values);
  215.     });
  216.  
  217.     // Sort by Length (Toggle between ascending and descending)
  218.     sortLengthButton.addEventListener('click', () => {
  219.       const values = input.value.split(',').map(v => v.trim()).filter(v => v);
  220.       values.sort((a, b) => sortLengthAscending ? a.length - b.length : b.length - a.length);
  221.       sortLengthAscending = !sortLengthAscending; // Toggle the sort order
  222.       renderBlocks(values);
  223.     });
  224. </script>
  225.  
  226. </body>
  227. </html>
Tags: html text tool
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement