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 });