taggart

Simple golang tagging filesystem webapp
Log | Files | Refs

bulk-tag.js (4046B)


      1 document.addEventListener('DOMContentLoaded', function () {
      2   const fileRangeInput = document.getElementById('file_range');
      3   if (!fileRangeInput) return;
      4   const fileForm = fileRangeInput.closest('form');
      5   if (!fileForm) return;
      6 
      7   function updateValueField() {
      8     const checkedOp = fileForm.querySelector('input[name="operation"]:checked');
      9     const valueField = fileForm.querySelector('#value');
     10     const valueLabel = fileForm.querySelector('label[for="value"]');
     11     if (!checkedOp || !valueField || !valueLabel) return;
     12     if (checkedOp.value === 'add') {
     13         valueField.required = true;
     14         valueLabel.innerHTML = 'Value <span class="required">(required)</span>:';
     15     } else {
     16         valueField.required = false;
     17         valueLabel.innerHTML = 'Value:';
     18     }
     19   }
     20 
     21   function toggleSelectionMode() {
     22     const rangeMode = fileForm.querySelector('input[name="selection_mode"][value="range"]');
     23     if (!rangeMode) return;
     24 
     25     const isRangeMode = rangeMode.checked;
     26     const rangeSelection = document.getElementById('range-selection');
     27     const tagSelection = document.getElementById('tag-selection');
     28     const fileRangeField = document.getElementById('file_range');
     29     const tagQueryField = document.getElementById('tag_query');
     30 
     31     if (rangeSelection) rangeSelection.style.display = isRangeMode ? 'block' : 'none';
     32     if (tagSelection) tagSelection.style.display = isRangeMode ? 'none' : 'block';
     33 
     34     // Update required attributes
     35     if (fileRangeField) fileRangeField.required = isRangeMode;
     36     if (tagQueryField) tagQueryField.required = !isRangeMode;
     37   }
     38 
     39   // Set up event listeners for operation radio buttons
     40   fileForm.querySelectorAll('input[name="operation"]').forEach(function (radio) {
     41     radio.addEventListener('change', updateValueField);
     42   });
     43 
     44   // Set up event listeners for selection mode radio buttons
     45   fileForm.querySelectorAll('input[name="selection_mode"]').forEach(function (radio) {
     46     radio.addEventListener('change', toggleSelectionMode);
     47   });
     48 
     49   // Initialize on page load
     50   updateValueField();
     51   toggleSelectionMode();
     52 
     53   // Add form validation with selection mode awareness
     54   fileForm.addEventListener('submit', function (e) {
     55     const selectionModeRadio = fileForm.querySelector('input[name="selection_mode"]:checked');
     56     const selectionMode = selectionModeRadio ? selectionModeRadio.value : 'range';
     57 
     58     const fileRange = (fileForm.querySelector('#file_range') || { value: '' }).value.trim();
     59     const tagQuery = (fileForm.querySelector('#tag_query') || { value: '' }).value.trim();
     60     const category = (fileForm.querySelector('#category') || { value: '' }).value.trim();
     61     const value = (fileForm.querySelector('#value') || { value: '' }).value.trim();
     62     const checkedOp = fileForm.querySelector('input[name="operation"]:checked');
     63     const operation = checkedOp ? checkedOp.value : '';
     64 
     65     // Validate based on selection mode
     66     if (selectionMode === 'range') {
     67       if (!fileRange) {
     68         alert('Please enter a file ID range');
     69         e.preventDefault();
     70         return;
     71       }
     72       const rangePattern = /^[\d\s,-]+$/;
     73       if (!rangePattern.test(fileRange)) {
     74         alert('File range should only contain numbers, commas, dashes, and spaces');
     75         e.preventDefault();
     76         return;
     77       }
     78     } else if (selectionMode === 'tags') {
     79       if (!tagQuery) {
     80         alert('Please enter a tag query');
     81         e.preventDefault();
     82         return;
     83       }
     84       // Basic validation for tag query format
     85       const tagPattern = /^[^:]+:[^:]+(\s+OR\s+[^:]+:[^:]+|,[^:]+:[^:]+)*$/i;
     86       if (!tagPattern.test(tagQuery)) {
     87         alert('Tag query format should be "category:value" (e.g., "colour:blue" or "colour:blue,size:large")');
     88         e.preventDefault();
     89         return;
     90       }
     91     }
     92 
     93     if (!category) {
     94       alert('Please enter a category');
     95       e.preventDefault();
     96       return;
     97     }
     98 
     99     if (operation === 'add' && !value) {
    100       alert('Please enter a tag value when adding tags');
    101       e.preventDefault();
    102       return;
    103     }
    104   });
    105 });