author Angelo Gladding
category Micropub
name Species
published 2025-05-31T14:52:24.795556-07:00
type entry
updated 2025-06-16T16:31:12.431849-07:00
url /species, /2025/05/31/ug
visibility public
Content
$ req = web.tx.request $if req.method == "GET": $if web.tx.user.session.get("uid"): <label><input type=checkbox name=endpoint value=ragt.ag/posts checked> ragt.ag (this site)</label><br> $if endpoint := web.tx.user.session.get("endpoint"): <label><input type=checkbox name=endpoint value=$endpoint>$web.tx.user.session["uid"][0] your site</label><br> <form method=post action=/species> <input name=scientific_name type="text" id="species-search" placeholder="Type a species name…" autocomplete="off"> <ul id="inat-suggestions" style="border:1px solid #ccc; max-height:200px; overflow-y:auto; position:absolute; background:white; z-index:10; display:none;"> </ul> $if mp_resp := mp_get(h="species"): <ul> $for species in mp_resp.json["items"]: <li> $if common_names := species.get("common-name"): <big>$", ".join(common_names)</big><br> <a href=$species["url"][0]>$species["scientific-name"][0]</a> </li> </ul> $if endpoint := web.tx.user.session.get("endpoint"): <div><button>Create</button></div> </form> $elif req.method == "POST": $ form = web.form("scientific_name") $if mp_resp := mp_post(h="species", scientific_name=form.scientific_name): <p>$mp_resp.text</p> <p>Species posted.</p> $else: <p>Your website does not support micropub.</p> <script> const searchInput = document.getElementById('species-search') const suggestionBox = document.getElementById('inat-suggestions') let debounceTimeout = null searchInput.addEventListener('input', () => { clearTimeout(debounceTimeout) const query = searchInput.value.trim() if (query.length < 3) { suggestionBox.style.display = 'none' return } debounceTimeout = setTimeout(() => searchINat(query), 250) }) async function searchINat(query) { const url = `https://api.inaturalist.org/v1/taxa?q=$${encodeURIComponent(query)}&per_page=20` const res = await fetch(url) const data = await res.json() if (!data.results || data.results.length === 0) { suggestionBox.style.display = 'none' return } suggestionBox.innerHTML = '' data.results .filter(taxon => taxon.rank_level <= 20) .forEach(taxon => { const li = document.createElement('li') li.style.padding = '4px 8px' li.style.cursor = 'pointer' const label = taxon.preferred_common_name ? `$${taxon.name} - $${taxon.preferred_common_name}` : taxon.name li.textContent = label li.addEventListener('click', () => { searchInput.value = taxon.name suggestionBox.style.display = 'none' }) suggestionBox.appendChild(li) }) suggestionBox.style.display = 'block' } document.addEventListener('click', e => { if (!suggestionBox.contains(e.target) && e.target !== searchInput) { suggestionBox.style.display = 'none' } }) </script> |