0
Skip to Content
Cradle Cincinnati
Home
Programs
Community Resources
The Issues
Safe Sleep
About Us
2025 Cradling Cincinnati Summit
Upcoming Events
Community Partner Meetings
Latest Updates
Donate
Cradle Cincinnati
Home
Programs
Community Resources
The Issues
Safe Sleep
About Us
2025 Cradling Cincinnati Summit
Upcoming Events
Community Partner Meetings
Latest Updates
Donate
Home
Folder: Programs
Back
Programs
Community Resources
Folder: The Issues
Back
The Issues
Safe Sleep
About Us
Folder: Calendar
Back
2025 Cradling Cincinnati Summit
Upcoming Events
Community Partner Meetings
Latest Updates
Donate

New Parent? Get Connected to a Community Health Worker

Read our blog to learn more about our work

2025 Annual Report
2025 Program Report

Community Resources

Donate
Event Calendar
Terms and Conditions

For media inquiries, please contact Jessica Seeberger

CONTACT

3333 Burnet Avenue, MLC 7009
Cincinnati, OH 45229
Phone: 513 803 4822

info@cradlecincinnati.org

(function () { const CSV_URL = "https://docs.google.com/spreadsheets/d/e/2PACX-1vQfTCwqOfxAXF9BmT4bTwhjrXgmY_8IGjDVPMmcDTRWX-vGBBzOd75lf6LlVWS5nbfaGzNzPkxMJ8S2/pub?gid=0&single=true&output=csv"; function initResourceFinder() { const root = document.getElementById("rf-directory"); if (!root || root.dataset.initialized === "true") return; root.dataset.initialized = "true"; const search = root.querySelector("#rf-search"); const category = root.querySelector("#rf-category"); const clear = root.querySelector("#rf-clear"); const results = root.querySelector("#rf-results"); const status = root.querySelector("#rf-status"); let resources = []; // Parse CSV while respecting commas and quotes. function parseCSV(text) { const rows = []; let row = []; let cell = ""; let quoted = false; text = text.replace(/^\uFEFF/, ""); for (let i = 0; i < text.length; i++) { const ch = text[i]; if (ch === '"' && quoted && text[i + 1] === '"') { cell += '"'; i++; } else if (ch === '"') { quoted = !quoted; } else if (ch === "," && !quoted) { row.push(cell); cell = ""; } else if ((ch === "\n" || ch === "\r") && !quoted) { if (ch === "\r" && text[i + 1] === "\n") i++; row.push(cell); if (row.some(v => v.trim() !== "")) rows.push(row); row = []; cell = ""; } else { cell += ch; } } row.push(cell); if (row.some(v => v.trim() !== "")) rows.push(row); if (!rows.length) return []; const headers = rows.shift().map(v => v.trim().toLowerCase()); return rows.map(row => { const item = {}; headers.forEach((header, i) => { item[header] = (row[i] || "").trim(); }); return item; }); } function escapeHTML(value) { return String(value || "").replace(/[&<>"']/g, ch => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[ch]); } function safeURL(value) { try { const url = new URL(value); return ["https:", "http:"].includes(url.protocol) ? url.href : ""; } catch { return ""; } } function populateCategories() { const names = [...new Set( resources.map(r => r.category).filter(Boolean) )].sort((a, b) => a.localeCompare(b)); category.innerHTML = '' + names.map(name => `` ).join(""); } function render() { const term = search.value.trim().toLowerCase(); const selected = category.value.toLowerCase(); const filtered = resources.filter(resource => { const matchesCategory = !selected || resource.category.toLowerCase() === selected; const searchable = [ resource.name, resource.category, resource.description, resource.tags, resource.address ].join(" ").toLowerCase(); return matchesCategory && (!term || searchable.includes(term)); }); status.textContent = `${filtered.length} resource${filtered.length === 1 ? "" : "s"} found`; if (!filtered.length) { results.innerHTML = '

No matching resources

' + '

Try another search or clear your filters.

'; return; } results.innerHTML = filtered.map(resource => { const website = safeURL(resource.website); const phone = String(resource.phone || "").trim(); const phoneHref = phone.replace(/[^\d+]/g, ""); const details = [ website ? `
Visit website ↗
` : "", phone ? `
${escapeHTML(phone)}
` : "", resource.address ? `
${escapeHTML(resource.address)}
` : "" ].filter(Boolean).join(""); return `
${resource.category ? `${escapeHTML(resource.category)}` : ""}

${escapeHTML(resource.name || "Untitled resource")}

${resource.description ? `

${escapeHTML(resource.description)}

` : ""} ${details ? `
${details}
` : ""}
`; }).join(""); } search.addEventListener("input", render); category.addEventListener("change", render); clear.addEventListener("click", () => { search.value = ""; category.value = ""; render(); search.focus(); }); fetch(CSV_URL) .then(response => { if (!response.ok) throw new Error("Could not load resource data."); return response.text(); }) .then(csv => { resources = parseCSV(csv).filter(r => r.name); populateCategories(); render(); }) .catch(error => { console.error("Resource Finder:", error); status.textContent = "Resources could not be loaded. Please try again later."; results.innerHTML = ""; }); } // Support initial page load and Squarespace navigation. if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", initResourceFinder); } else { initResourceFinder(); } document.addEventListener("mercury:load", initResourceFinder); })();