Mar 03 2026: enhanced inspection and issue workflow 2
This commit is contained in:
@@ -214,9 +214,11 @@
|
||||
</div>
|
||||
<div class="d-flex gap-2 align-items-center">
|
||||
<span class="freq-badge">{{ inspection.template.frequency|title }}</span>
|
||||
<button type="submit" name="action" value="flag"
|
||||
<button type="button"
|
||||
class="btn btn-sm btn-outline-danger btn-outline-light"
|
||||
onclick="return confirm('Your current progress will be saved automatically. Continue to flag an issue?')">
|
||||
id="flagIssueBtn"
|
||||
data-flag-url="{{ url_for('inspections.save_draft_ajax', inspection_id=inspection.id) }}"
|
||||
data-flag-redirect="{{ url_for('inspections.flag_issue', inspection_id=inspection.id) }}">
|
||||
<i class="bi bi-exclamation-triangle"></i> Flag Issue
|
||||
</button>
|
||||
</div>
|
||||
@@ -674,5 +676,64 @@ document.getElementById('inspectionForm').addEventListener('submit', async funct
|
||||
alert('An error occurred. Please try again.');
|
||||
}
|
||||
});
|
||||
|
||||
// ── Flag Issue: save draft via AJAX then navigate ────────────────────────────
|
||||
(function () {
|
||||
const btn = document.getElementById('flagIssueBtn');
|
||||
if (!btn) return;
|
||||
|
||||
btn.addEventListener('click', async function () {
|
||||
const saveDraftUrl = btn.dataset.flagUrl;
|
||||
const redirectUrl = btn.dataset.flagRedirect;
|
||||
|
||||
// Collect all current form field values (non-file inputs only)
|
||||
const form = document.getElementById('inspectionForm');
|
||||
const responses = {};
|
||||
form.querySelectorAll('input, textarea, select').forEach(el => {
|
||||
if (!el.name || !el.name.startsWith('field_')) return;
|
||||
if (el.type === 'file') return; // files can't be JSON-serialised
|
||||
if (el.type === 'checkbox') {
|
||||
responses[el.name.replace('field_', '')] = el.checked ? 'true' : 'false';
|
||||
} else if (el.type === 'radio') {
|
||||
if (el.checked) responses[el.name.replace('field_', '')] = el.value;
|
||||
} else {
|
||||
responses[el.name.replace('field_', '')] = el.value;
|
||||
}
|
||||
});
|
||||
|
||||
// Flush signature canvases to their hidden inputs before reading values
|
||||
collectSignatures();
|
||||
form.querySelectorAll('input[type="hidden"]').forEach(el => {
|
||||
if (!el.name || !el.name.startsWith('field_')) return;
|
||||
responses[el.name.replace('field_', '')] = el.value;
|
||||
});
|
||||
|
||||
btn.disabled = true;
|
||||
btn.innerHTML = '<span class="spinner-border spinner-border-sm me-1"></span> Saving…';
|
||||
|
||||
try {
|
||||
const res = await fetch(saveDraftUrl, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': document.querySelector('input[name="csrf_token"]').value,
|
||||
},
|
||||
body: JSON.stringify({ responses }),
|
||||
});
|
||||
const json = await res.json();
|
||||
if (json.ok) {
|
||||
window.location.href = redirectUrl;
|
||||
} else {
|
||||
alert('Could not save draft: ' + (json.error || 'Unknown error'));
|
||||
btn.disabled = false;
|
||||
btn.innerHTML = '<i class="bi bi-exclamation-triangle"></i> Flag Issue';
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('Flag Issue draft save error:', err);
|
||||
// Fall back to navigating directly without saving
|
||||
window.location.href = redirectUrl;
|
||||
}
|
||||
});
|
||||
}());
|
||||
</script>
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user