// Render helper descriptions for YOLOX settings and handle form submission window.addEventListener('DOMContentLoaded', () => { // Get the form element at the top const form = document.getElementById('settings-form'); // Auto-set num_classes from training_project classes array const urlParams = new URLSearchParams(window.location.search); const projectId = urlParams.get('id'); if (projectId && form) { fetch('/api/training-projects') .then(res => res.json()) .then(projects => { const project = projects.find(p => p.project_id == projectId || p.id == projectId); if (project && project.classes) { let classesArr = project.classes; // If classes is a stringified JSON, parse it if (typeof classesArr === 'string') { try { classesArr = JSON.parse(classesArr); } catch (e) { classesArr = []; } } let numClasses = 0; if (Array.isArray(classesArr)) { numClasses = classesArr.length; } else if (typeof classesArr === 'object' && classesArr !== null) { numClasses = Object.keys(classesArr).length; } // Fix: Only set num_classes if input exists const numClassesInput = form.querySelector('[name="num_classes"]'); if (numClassesInput) { numClassesInput.value = numClasses; numClassesInput.readOnly = true; numClassesInput.dispatchEvent(new Event('input')); } } }); } // Handle form submission form.addEventListener('submit', function(e) { console.log("Form submitted"); e.preventDefault(); const formData = new FormData(form); const settings = {}; let fileToUpload = null; for (const [key, value] of formData.entries()) { if (key === 'model_upload' && form.elements[key].files.length > 0) { fileToUpload = form.elements[key].files[0]; continue; } if (key === 'ema' || key === 'enable_mixup') { settings[key] = form.elements[key].checked; } else if (key === 'scale' || key === 'mosaic_scale') { settings[key] = value.split(',').map(v => parseFloat(v.trim())); } else if (!isNaN(value) && value !== '') { settings[key] = parseFloat(value); } else { settings[key] = value; } } // Attach project id from URL const urlParams = new URLSearchParams(window.location.search); const projectId = urlParams.get('id'); if (projectId) settings.project_id = Number(projectId); // First, send settings JSON (without file) fetch('/api/yolox-settings', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(settings) }) .then(res => res.json()) .then(data => { // If file selected, send it as binary if (fileToUpload) { const reader = new FileReader(); reader.onload = function(e) { fetch(`/api/yolox-settings/upload?project_id=${settings.project_id}`, { method: 'POST', headers: { 'Content-Type': 'application/octet-stream' }, body: e.target.result }) .then(res => res.json()) .then(data2 => { alert('YOLOX settings and model file saved!'); window.location.href = `/overview-training.html?id=${settings.project_id}`; }) .catch(err => { alert('Error uploading model file'); console.error(err); }); }; reader.readAsArrayBuffer(fileToUpload); } else { alert('YOLOX settings saved!'); window.location.href = `/overview-training.html?id=${settings.project_id}`; } }) .catch(err => { alert('Error saving YOLOX settings'); console.error(err); }); }); });