Bird Watching Log Generator
Structured Field Observation Sheet
Species Richness:
0
BIRD WATCHING FIELD REPORT
Location: Central Park, NY | Date: ---
Observer: N/A | Start Time: N/A
Summary Metrics
Duration:
Weather:
Total Individuals: 0
Species Richness (S): 0
Detailed Sighting Log
| Time | Species (Common Name) | Count | Specific Habitat | Behavior / Notes |
|---|---|---|---|---|
| TOTAL INDIVIDUALS RECORDED | 0 | |||
Generated by Bird Watching Log Generator. Data compatible with citizen science platforms (e.g., eBird).
Observation Context
Log a New Bird Sighting
Enter the details for each unique observation.
Current Sighting Log
Log is empty.
"; return; } const sortedSightings = [...bwlData.sightings].sort((a, b) => a.time.localeCompare(b.time)); sortedSightings.forEach(sighting => { const row = document.createElement('div'); row.className = 'bwl-sighting-row'; row.innerHTML = `
[${sighting.time}] ${sighting.species} (Qty: ${sighting.count})
`;
outputs.sightingListEditor.appendChild(row);
});
}
// --- 5. EVENT LISTENERS & ACTIONS ---
function attachListeners() {
// Meta Inputs
const metaInputs = Object.values(inputs).filter(i => !i.id.includes('inp-'));
metaInputs.forEach(inp => inp.addEventListener('input', renderAll));
// Add Sighting Button
document.getElementById('btn-add-sighting').addEventListener('click', addSighting);
}
function addSighting() {
const time = inputs.time.value;
const species = inputs.species.value.trim();
const count = parseInt(inputs.count.value) || 0;
const habitat = inputs.habitat.value.trim();
const notes = inputs.notes.value.trim();
if (!time || !species || count <= 0) {
alert("Time, Species, and Count (> 0) are required.");
return;
}
const newSighting = {
id: Date.now(),
time: time,
species: species,
count: count,
habitat: habitat || "N/A",
notes: notes || "N/A"
};
bwlData.sightings.push(newSighting);
// Clear inputs for next entry
inputs.species.value = "";
inputs.count.value = "1";
inputs.habitat.value = "";
inputs.notes.value = "";
renderAll();
}
window.removeSighting = function(id) {
if(confirm("Remove this sighting entry?")) {
bwlData.sightings = bwlData.sightings.filter(s => s.id !== id);
renderAll();
}
};
// --- 6. TAB NAVIGATION ---
window.bwlSwitchTab = function(tabId) {
document.querySelectorAll('.bwl-tab-pane').forEach(p => p.classList.remove('active'));
document.querySelectorAll('.bwl-tab-btn').forEach(b => b.classList.remove('active'));
document.getElementById(tabId).classList.add('active');
document.querySelector(`.bwl-tab-btn[data-tab="${tabId}"]`).classList.add('active');
document.getElementById('bird-log-tool').scrollIntoView({behavior: 'smooth'});
};
document.querySelectorAll('.bwl-tab-btn').forEach(btn => {
btn.addEventListener('click', function() { bwlSwitchTab(this.dataset.tab); });
});
// --- 7. PDF EXPORT ---
const btnDown = document.getElementById('bwl-download-btn');
if(btnDown) {
btnDown.addEventListener('click', function() {
renderAll();
const element = document.getElementById('bwl-render-area');
const filename = (inputs.location.value || 'Bird_Log').replace(/\s+/g,'_');
const opt = {
margin: 0.4,
filename: `${filename}_Bird_Log.pdf`,
image: { type: 'jpeg', quality: 0.98 },
html2canvas: { scale: 2, useCORS: true },
jsPDF: { unit: 'in', format: 'letter', orientation: 'landscape' } // Landscape for wide table
};
const origText = btnDown.innerText;
btnDown.innerText = "Generating Log Sheet...";
html2pdf().set(opt).from(element).save().then(() => {
document.getElementById('bwl-download-btn').innerText = origText;
});
});
}
// Start
init();
});
