Upload files to "ICS"
This commit is contained in:
@@ -0,0 +1,472 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Incident Status Report (Packet Radio)</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; }
|
||||
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, monospace; background: #eef2f7; color: #222; padding: 20px; margin: 0; }
|
||||
.container { max-width: 960px; margin: 0 auto; background: #fff; padding: 24px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }
|
||||
.header { background: #1a237e; color: white; padding: 12px; border-radius: 6px; text-align: center; margin-bottom: 18px; }
|
||||
.header h2 { margin: 0; font-size: 1.3rem; letter-spacing: 1px; }
|
||||
.header p { margin: 4px 0 0 0; font-size: 0.85rem; opacity: 0.9; }
|
||||
fieldset { border: 1px solid #c5cae9; border-radius: 6px; padding: 14px; margin-bottom: 14px; background: #fafbff; }
|
||||
legend { font-weight: bold; padding: 0 8px; font-size: 0.85rem; color: #1a237e; }
|
||||
.row { display: flex; flex-wrap: wrap; gap: 12px; margin-bottom: 10px; }
|
||||
.col { flex: 1; min-width: 140px; display: flex; flex-direction: column; }
|
||||
.label-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 4px; }
|
||||
label { font-size: 0.8rem; font-weight: 600; color: #333; }
|
||||
input[type="text"], select, textarea { padding: 7px 8px; font-size: 0.88rem; border: 1px solid #999; border-radius: 4px; font-family: inherit; width: 100%; }
|
||||
textarea { resize: vertical; min-height: 70px; }
|
||||
.checkbox-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; font-size: 0.85rem; margin-top: 4px; }
|
||||
.btn-now { background: #4a5568; color: #fff; padding: 4px 8px; font-size: 0.72rem; border-radius: 4px; border: none; cursor: pointer; }
|
||||
.btn-now:hover { background: #2d3748; }
|
||||
.actions { display: flex; gap: 10px; margin: 18px 0; }
|
||||
button.main-btn { flex: 1; padding: 12px; font-size: 0.95rem; font-weight: bold; border: none; border-radius: 6px; cursor: pointer; }
|
||||
.btn-generate { background: #1a237e; color: #fff; }
|
||||
.btn-generate:hover { background: #0d1642; }
|
||||
.btn-save { background: #5c6bc0; color: #fff; }
|
||||
.btn-save:hover { background: #3f51b5; }
|
||||
.btn-copy { background: #2e7d32; color: #fff; }
|
||||
.btn-copy:hover { background: #1b5e20; }
|
||||
.btn-clear { background: #555; color: #fff; flex: 0.35; }
|
||||
.btn-clear:hover { background: #333; }
|
||||
pre { background: #181c20; color: #39ff14; padding: 14px; border-radius: 6px; overflow-x: auto; font-family: "Courier New", Courier, monospace; font-size: 0.82rem; line-height: 1.32; min-height: 150px; }
|
||||
.nav-bar { margin-bottom: 12px; font-size: 0.85rem; }
|
||||
.nav-bar a { color: #1a237e; text-decoration: none; font-weight: bold; }
|
||||
|
||||
/* Modal Save Dialog Window */
|
||||
.save-modal-backdrop {
|
||||
display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%;
|
||||
background: rgba(0,0,0,0.55); z-index: 99999; justify-content: center; align-items: center;
|
||||
}
|
||||
.save-modal-backdrop.active { display: flex; }
|
||||
.save-modal-window {
|
||||
background: #ffffff; padding: 24px 28px; border-radius: 10px; width: 92%; max-width: 480px;
|
||||
box-shadow: 0 10px 30px rgba(0,0,0,0.3); border: 1px solid #cbd5e1; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
||||
}
|
||||
.save-modal-window h3 { margin: 0 0 8px 0; font-size: 1.25rem; color: #1e293b; font-weight: bold; }
|
||||
.save-modal-window p { margin: 0 0 16px 0; font-size: 0.88rem; color: #64748b; line-height: 1.4; }
|
||||
.save-modal-window input[type="text"] {
|
||||
width: 100%; padding: 10px 12px; font-size: 0.95rem; border: 2px solid #94a3b8; border-radius: 6px;
|
||||
margin-bottom: 20px; font-family: inherit; box-sizing: border-box; text-transform: none;
|
||||
}
|
||||
.save-modal-window input[type="text"]:focus { border-color: #2563eb; outline: none; }
|
||||
.save-modal-actions { display: flex; gap: 10px; justify-content: flex-end; }
|
||||
.save-modal-btn { padding: 9px 18px; font-size: 0.9rem; font-weight: bold; border-radius: 6px; border: none; cursor: pointer; }
|
||||
.save-modal-btn-confirm { background: #2563eb; color: #ffffff; }
|
||||
.save-modal-btn-confirm:hover { background: #1d4ed8; }
|
||||
.save-modal-btn-cancel { background: #e2e8f0; color: #334155; }
|
||||
.save-modal-btn-cancel:hover { background: #cbd5e1; }
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="nav-bar"><a href="../index.html">← Back to Packet Forms Hub</a></div>
|
||||
<div class="header">
|
||||
<h2>INCIDENT STATUS REPORT</h2>
|
||||
<p>Winlink Standard Emergency Operations Overview (Packet ASCII)</p>
|
||||
</div>
|
||||
|
||||
<form id="statusForm" onsubmit="event.preventDefault(); return false;">
|
||||
<fieldset>
|
||||
<legend>1-4. INCIDENT IDENTIFICATION & REPORT VERSION</legend>
|
||||
<div class="row">
|
||||
<div class="col" style="flex: 2;"><label for="incName">1. Incident Name</label><input type="text" id="incName" placeholder="e.g. TRAVIS COUNTY FLOOD"></div>
|
||||
<div class="col"><label for="webEOC">2. WebEOC Incident #</label><input type="text" id="webEOC" placeholder="e.g. EOC-2026-088"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="label-row">
|
||||
<label for="incDT">3. Incident Date / Time</label>
|
||||
<button type="button" class="btn-now" id="btnIncDT">Current UTC</button>
|
||||
</div>
|
||||
<input type="text" id="incDT" placeholder="YYYY-MM-DD HHMMZ">
|
||||
</div>
|
||||
<div class="col">
|
||||
<label for="repVersion">4. Report Version</label>
|
||||
<select id="repVersion">
|
||||
<option value="INITIAL">INITIAL</option>
|
||||
<option value="UPDATE">UPDATE</option>
|
||||
<option value="FINAL">FINAL</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>5. TYPE OF INCIDENT (Check all that apply)</legend>
|
||||
<div class="checkbox-grid">
|
||||
<label><input type="checkbox" id="t_storm" value="Severe Storm/Flood"> Severe Storm / Flood</label>
|
||||
<label><input type="checkbox" id="t_event" value="Pre-Planned Event"> Pre-Planned Event</label>
|
||||
<label><input type="checkbox" id="t_hazmat" value="HAZMAT"> HAZMAT</label>
|
||||
<label><input type="checkbox" id="t_winter" value="Severe Winter Weather"> Severe Winter Weather</label>
|
||||
<label><input type="checkbox" id="t_dam" value="Dam/Levee"> Dam / Levee</label>
|
||||
<label><input type="checkbox" id="t_util" value="Utility Disruption"> Utility Disruption</label>
|
||||
<label><input type="checkbox" id="t_health" value="Public Health"> Public Health</label>
|
||||
<label><input type="checkbox" id="t_civil" value="Civil Disturbance"> Civil Disturbance</label>
|
||||
<label><input type="checkbox" id="t_quake" value="Earthquake"> Earthquake</label>
|
||||
<label><input type="checkbox" id="t_fire" value="Fire"> Fire</label>
|
||||
<label><input type="checkbox" id="t_air" value="Aircraft Disaster"> Aircraft Disaster</label>
|
||||
<label><input type="checkbox" id="t_other_chk" value="Other"> Other (Specify below)</label>
|
||||
</div>
|
||||
<div class="row" style="margin-top: 8px;">
|
||||
<div class="col"><input type="text" id="t_other_txt" placeholder="Specify if 'Other' selected"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>6-7. SITUATION & FUTURE OUTLOOK</legend>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<label for="sitSum">6. Situation Summary as of Time of Report</label>
|
||||
<textarea id="sitSum" rows="3" placeholder="Brief summary of event impact, ongoing operations, current hazards..."></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<label for="goalsIssues">7. Future Outlook / Goals / Needs / Issues</label>
|
||||
<textarea id="goalsIssues" rows="2" placeholder="Next operational priorities, critical shortfalls, anticipated issues..."></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>8-9. EOC STATUS & LOCAL DISASTER DECLARATION</legend>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<label for="eocStatus">8. County EOC Status</label>
|
||||
<select id="eocStatus">
|
||||
<option value="CLOSED">CLOSED</option>
|
||||
<option value="ACTIVATED">ACTIVATED</option>
|
||||
<option value="MONITORING">MONITORING (Minimal Staffing)</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col"><label for="eocHours">EOC Hours of Operation</label><input type="text" id="eocHours" placeholder="e.g. 24/7 or 0700-1900"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<label for="decStatus">9. Local Disaster Declaration Status</label>
|
||||
<select id="decStatus">
|
||||
<option value="No declaration / not anticipated">No declaration / not anticipated</option>
|
||||
<option value="Declaration anticipated">Declaration anticipated</option>
|
||||
<option value="Local disaster declaration in effect">Local disaster declaration in effect</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col"><label for="decDT">Declaration Date / Time</label><input type="text" id="decDT" placeholder="YYYY-MM-DD HHMMZ"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>10-13. CASUALTIES, SHELTERS & EVACUATIONS</legend>
|
||||
<div class="row">
|
||||
<div class="col"><label for="injuries">10. Confirmed Injuries</label><input type="text" id="injuries" placeholder="0"></div>
|
||||
<div class="col"><label for="fatalities">11. Confirmed Fatalities</label><input type="text" id="fatalities" placeholder="0"></div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<label for="shelters">12. Shelters Established (Number and Locations)</label>
|
||||
<textarea id="shelters" rows="2" placeholder="e.g. 2 Shelters open: Oak Ridge Middle School (pop 110), Northside Rec Center (pop 45)"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<label for="evacStatus">13. Evacuations Implemented?</label>
|
||||
<select id="evacStatus">
|
||||
<option value="No / None anticipated">No / None anticipated</option>
|
||||
<option value="YES - Mandatory">YES - Mandatory</option>
|
||||
<option value="YES - Voluntary">YES - Voluntary</option>
|
||||
<option value="Evacuations anticipated">Evacuations anticipated</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col" style="flex: 2;"><label for="evacDesc">Evacuation Description</label><input type="text" id="evacDesc" placeholder="Boundaries, evacuation routes, population ordered..."></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<fieldset>
|
||||
<legend>14-16. SUBMISSION & CONTACT INFO</legend>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="label-row">
|
||||
<label for="repDT">14. Date / Time of Report</label>
|
||||
<button type="button" class="btn-now" id="btnRepDT">Current UTC</button>
|
||||
</div>
|
||||
<input type="text" id="repDT" placeholder="YYYY-MM-DD HHMMZ">
|
||||
</div>
|
||||
<div class="col"><label for="submittedBy">15. Report Submitted By</label><input type="text" id="submittedBy" placeholder="Name, Title, Callsign"></div>
|
||||
<div class="col"><label for="contactInfo">16. Contact Info</label><input type="text" id="contactInfo" placeholder="Phone / Radio Call / Email"></div>
|
||||
</div>
|
||||
</fieldset>
|
||||
|
||||
<div class="actions">
|
||||
<button type="button" class="main-btn btn-generate" id="btnGen">Generate Packet ASCII</button>
|
||||
<button type="button" class="main-btn btn-save" id="btnSaveHtml">Save as HTML</button>
|
||||
<button type="button" class="main-btn btn-copy" id="btnCopy">Copy ASCII</button>
|
||||
<button type="button" class="main-btn btn-clear" id="btnClear">Reset</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<label style="font-weight:bold;">Formatted ASCII for Packet / BBS Transmission:</label>
|
||||
<pre id="outputPre">Fill in the fields above and click "Generate Packet ASCII"...</pre>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
function setUTC(fldId) {
|
||||
const now = new Date();
|
||||
const y = now.getUTCFullYear();
|
||||
const m = String(now.getUTCMonth()+1).padStart(2,'0');
|
||||
const d = String(now.getUTCDate()).padStart(2,'0');
|
||||
const hh = String(now.getUTCHours()).padStart(2,'0');
|
||||
const mm = String(now.getUTCMinutes()).padStart(2,'0');
|
||||
document.getElementById(fldId).value = y + '-' + m + '-' + d + ' ' + hh + mm + 'Z';
|
||||
}
|
||||
|
||||
function clean(id) {
|
||||
const el = document.getElementById(id);
|
||||
return el ? (el.value || '').trim() : '';
|
||||
}
|
||||
|
||||
function wrapText(str, width) {
|
||||
if (!str) return [];
|
||||
let lines = [];
|
||||
str.split('\n').forEach(function(paragraph) {
|
||||
let words = paragraph.split(' ');
|
||||
let cur = '';
|
||||
words.forEach(function(w) {
|
||||
if ((cur + (cur ? ' ' : '') + w).length <= width) {
|
||||
cur += (cur ? ' ' : '') + w;
|
||||
} else {
|
||||
if (cur) lines.push(cur);
|
||||
cur = w;
|
||||
}
|
||||
});
|
||||
if (cur) lines.push(cur);
|
||||
});
|
||||
return lines;
|
||||
}
|
||||
|
||||
function generateASCII() {
|
||||
try {
|
||||
const div = '='.repeat(78);
|
||||
const sub = '-'.repeat(78);
|
||||
|
||||
const inc = clean('incName').toUpperCase() || 'N/A';
|
||||
const web = clean('webEOC').toUpperCase() || 'N/A';
|
||||
const idt = clean('incDT') || 'N/A';
|
||||
const ver = clean('repVersion').toUpperCase();
|
||||
|
||||
// Gather types
|
||||
let types = [];
|
||||
document.querySelectorAll('.checkbox-grid input[type="checkbox"]').forEach(function(cb) {
|
||||
if (cb.checked) {
|
||||
if (cb.id === 't_other_chk' && clean('t_other_txt')) {
|
||||
types.push('OTHER (' + clean('t_other_txt').toUpperCase() + ')');
|
||||
} else {
|
||||
types.push(cb.value.toUpperCase());
|
||||
}
|
||||
}
|
||||
});
|
||||
const typeStr = types.length ? types.join(', ') : 'NONE SPECIFIED';
|
||||
|
||||
const sit = clean('sitSum').toUpperCase() || 'NONE REPORTED';
|
||||
const goals = clean('goalsIssues').toUpperCase() || 'NONE REPORTED';
|
||||
|
||||
const eoc = clean('eocStatus').toUpperCase();
|
||||
const eocH = clean('eocHours').toUpperCase() || 'N/A';
|
||||
const dec = clean('decStatus').toUpperCase();
|
||||
const decD = clean('decDT') || 'N/A';
|
||||
|
||||
const inj = clean('injuries') || '0';
|
||||
const fat = clean('fatalities') || '0';
|
||||
const shlt = clean('shelters').toUpperCase() || 'NONE ESTABLISHED';
|
||||
const evac = clean('evacStatus').toUpperCase();
|
||||
const evacD = clean('evacDesc').toUpperCase();
|
||||
|
||||
const rdt = clean('repDT') || 'N/A';
|
||||
const subBy = clean('submittedBy').toUpperCase() || 'N/A';
|
||||
const cont = clean('contactInfo').toUpperCase() || 'N/A';
|
||||
|
||||
let wrappedSit = wrapText(sit, 72).map(function(l){ return ' ' + l; }).join('\n');
|
||||
let wrappedGoals = wrapText(goals, 72).map(function(l){ return ' ' + l; }).join('\n');
|
||||
let wrappedShlt = wrapText(shlt, 72).map(function(l){ return ' ' + l; }).join('\n');
|
||||
|
||||
const out = div + '\n' +
|
||||
'INCIDENT STATUS REPORT (PACKET ASCII)\n' +
|
||||
div + '\n' +
|
||||
'1. INCIDENT NAME: ' + inc + ' 2. WEBEOC #: ' + web + '\n' +
|
||||
'3. INCIDENT D/T: ' + idt + ' 4. REPORT VER: ' + ver + '\n' +
|
||||
sub + '\n' +
|
||||
'5. INCIDENT TYPE(S): ' + typeStr + '\n' +
|
||||
sub + '\n' +
|
||||
'6. SITUATION SUMMARY:\n' + wrappedSit + '\n' +
|
||||
sub + '\n' +
|
||||
'7. FUTURE OUTLOOK / GOALS / NEEDS / ISSUES:\n' + wrappedGoals + '\n' +
|
||||
sub + '\n' +
|
||||
'8. COUNTY EOC STATUS : ' + eoc + ' (HOURS: ' + eocH + ')\n' +
|
||||
'9. DISASTER DECLARATION: ' + dec + (decD !== 'N/A' ? ' [DATE/TIME: ' + decD + ']' : '') + '\n' +
|
||||
sub + '\n' +
|
||||
'10. INJURIES: ' + inj + ' 11. FATALITIES: ' + fat + '\n' +
|
||||
'12. SHELTERS ESTABLISHED:\n' + wrappedShlt + '\n' +
|
||||
'13. EVACUATIONS: ' + evac + (evacD ? ' - ' + evacD : '') + '\n' +
|
||||
sub + '\n' +
|
||||
'14. REPORT DATE/TIME: ' + rdt + '\n' +
|
||||
'15. SUBMITTED BY : ' + subBy + '\n' +
|
||||
'16. CONTACT INFO : ' + cont + '\n' +
|
||||
div;
|
||||
|
||||
document.getElementById('outputPre').textContent = out;
|
||||
} catch(err) {
|
||||
alert("Error generating text: " + err.message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function copyASCII() {
|
||||
const txt = document.getElementById('outputPre').textContent;
|
||||
if (navigator.clipboard && navigator.clipboard.writeText) {
|
||||
navigator.clipboard.writeText(txt).then(function() {
|
||||
alert("Incident Status copied to clipboard!");
|
||||
}).catch(function() {
|
||||
fallbackCopy();
|
||||
});
|
||||
} else {
|
||||
fallbackCopy();
|
||||
}
|
||||
}
|
||||
|
||||
function fallbackCopy() {
|
||||
const pre = document.getElementById('outputPre');
|
||||
const range = document.createRange();
|
||||
range.selectNode(pre);
|
||||
window.getSelection().removeAllRanges();
|
||||
window.getSelection().addRange(range);
|
||||
document.execCommand('copy');
|
||||
alert("Copied to clipboard!");
|
||||
}
|
||||
|
||||
function clearForm() {
|
||||
if(confirm("Reset Incident Status form?")) {
|
||||
document.getElementById('statusForm').reset();
|
||||
document.getElementById('outputPre').textContent = 'Fill in the fields above and click "Generate Packet ASCII"...';
|
||||
}
|
||||
}
|
||||
|
||||
document.getElementById('btnIncDT').addEventListener('click', function(){ setUTC('incDT'); });
|
||||
document.getElementById('btnRepDT').addEventListener('click', function(){ setUTC('repDT'); });
|
||||
document.getElementById('btnGen').addEventListener('click', generateASCII);
|
||||
document.getElementById('btnSaveHtml').addEventListener('click', openSaveModal);
|
||||
document.getElementById('btnCopy').addEventListener('click', copyASCII);
|
||||
document.getElementById('btnClear').addEventListener('click', clearForm);
|
||||
|
||||
|
||||
|
||||
// File Name Modal Window & HTML Exporter
|
||||
function openSaveModal() {
|
||||
var now = new Date();
|
||||
var dStr = now.toISOString().slice(0, 10);
|
||||
var defName = 'incident_status_' + dStr + '.html';
|
||||
var modal = document.getElementById('saveModalBackdrop');
|
||||
var input = document.getElementById('saveModalFileName');
|
||||
if (input) input.value = defName;
|
||||
if (modal) modal.classList.add('active');
|
||||
setTimeout(function() {
|
||||
if (input) { input.focus(); input.select(); }
|
||||
}, 50);
|
||||
}
|
||||
|
||||
function closeSaveModal() {
|
||||
var modal = document.getElementById('saveModalBackdrop');
|
||||
if (modal) modal.classList.remove('active');
|
||||
}
|
||||
|
||||
function executeSaveHTML() {
|
||||
var input = document.getElementById('saveModalFileName');
|
||||
var chosenName = input ? input.value.trim() : '';
|
||||
if (!chosenName) return;
|
||||
if (!chosenName.toLowerCase().endsWith('.html') && !chosenName.toLowerCase().endsWith('.htm')) {
|
||||
chosenName += '.html';
|
||||
}
|
||||
closeSaveModal();
|
||||
|
||||
document.querySelectorAll('input[type="text"]').forEach(function(el) { el.setAttribute('value', el.value); });
|
||||
document.querySelectorAll('input[type="checkbox"], input[type="radio"]').forEach(function(el) {
|
||||
if (el.checked) el.setAttribute('checked', 'checked');
|
||||
else el.removeAttribute('checked');
|
||||
});
|
||||
document.querySelectorAll('textarea').forEach(function(el) { el.textContent = el.value; });
|
||||
document.querySelectorAll('select').forEach(function(el) {
|
||||
Array.from(el.options).forEach(function(opt) {
|
||||
if (opt.value === el.value) opt.setAttribute('selected', 'selected');
|
||||
else opt.removeAttribute('selected');
|
||||
});
|
||||
});
|
||||
|
||||
var pre = document.getElementById('ascii-report') || document.getElementById('outputPre') || document.getElementById('preview') || document.getElementById('outputArea');
|
||||
if (pre) pre.textContent = pre.textContent;
|
||||
|
||||
var clonedDoc = document.documentElement.cloneNode(true);
|
||||
var modalInClone = clonedDoc.querySelector('#saveModalBackdrop');
|
||||
if (modalInClone) modalInClone.classList.remove('active');
|
||||
|
||||
var htmlContent = '<!DOCTYPE html>\n' + clonedDoc.outerHTML;
|
||||
var blob = new Blob([htmlContent], { type: 'text/html;charset=utf-8' });
|
||||
var url = URL.createObjectURL(blob);
|
||||
var a = document.createElement('a');
|
||||
a.href = url;
|
||||
a.download = chosenName;
|
||||
document.body.appendChild(a);
|
||||
a.click();
|
||||
document.body.removeChild(a);
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
window.addEventListener('DOMContentLoaded', function() {
|
||||
var cancelBtn = document.getElementById('saveModalCancelBtn');
|
||||
var confirmBtn = document.getElementById('saveModalSaveBtn');
|
||||
var modalInput = document.getElementById('saveModalFileName');
|
||||
var modalBackdrop = document.getElementById('saveModalBackdrop');
|
||||
|
||||
if (cancelBtn) cancelBtn.addEventListener('click', closeSaveModal);
|
||||
if (confirmBtn) confirmBtn.addEventListener('click', executeSaveHTML);
|
||||
if (modalInput) {
|
||||
modalInput.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Enter') { e.preventDefault(); executeSaveHTML(); }
|
||||
if (e.key === 'Escape') { e.preventDefault(); closeSaveModal(); }
|
||||
});
|
||||
}
|
||||
if (modalBackdrop) {
|
||||
modalBackdrop.addEventListener('click', function(e) {
|
||||
if (e.target === modalBackdrop) closeSaveModal();
|
||||
});
|
||||
}
|
||||
|
||||
var btnSaveMain = document.getElementById('btnSaveHtml');
|
||||
if (btnSaveMain) {
|
||||
// Clear existing inline handlers just in case
|
||||
btnSaveMain.onclick = null;
|
||||
btnSaveMain.addEventListener('click', openSaveModal);
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Custom File Name Modal Window -->
|
||||
<div id="saveModalBackdrop" class="save-modal-backdrop">
|
||||
<div class="save-modal-window">
|
||||
<h3>Save Form as HTML</h3>
|
||||
<p>Enter a name for the saved offline HTML file:</p>
|
||||
<input type="text" id="saveModalFileName" spellcheck="false">
|
||||
<div class="save-modal-actions">
|
||||
<button type="button" class="save-modal-btn save-modal-btn-cancel" id="saveModalCancelBtn">Cancel</button>
|
||||
<button type="button" class="save-modal-btn save-modal-btn-confirm" id="saveModalSaveBtn">Save File</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user