mirror of
https://github.com/kennethreitz/kjvstudy.org.git
synced 2026-06-21 14:50:58 +00:00
3336863a4d
- Add KJVNav.initGridNav for standardized 2D grid navigation - Migrate books.html, topics.html, resources.html to use initGridNav - Add sidebarActive check to all templates with custom keyboard handlers - Add [ and ] shortcuts for prev/next chapter on chapter pages - Add [ and ] shortcuts for prev/next book on book pages - Update accessibility page with comprehensive keyboard shortcut docs - Add honest note about keyboard navigation complexity - Fix sidebar nav conflicting with main content selection 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
115 lines
4.4 KiB
HTML
115 lines
4.4 KiB
HTML
{% extends "base.html" %}
|
|
|
|
{% block title %}Search Family Tree - KJV Study{% endblock %}
|
|
{% block description %}Search the biblical family tree from Adam to Jesus Christ.{% endblock %}
|
|
|
|
{% block content %}
|
|
<h1>Search Family Tree</h1>
|
|
<p class="subtitle">Find individuals in the biblical genealogy</p>
|
|
|
|
<form method="get" action="/family-tree/search" style="margin: 1.5rem 0;">
|
|
<input
|
|
type="text"
|
|
name="q"
|
|
value="{{ query }}"
|
|
placeholder="Enter a name..."
|
|
list="person-names"
|
|
style="width: 100%; max-width: 55%; padding: 0.75rem; font-size: 1.1rem; border: 1px solid #ccc;"
|
|
autofocus
|
|
autocomplete="off"
|
|
>
|
|
<datalist id="person-names">
|
|
{% for name in all_names %}
|
|
<option value="{{ name }}">
|
|
{% endfor %}
|
|
</datalist>
|
|
<br>
|
|
<button type="submit" style="margin-top: 1rem; padding: 0.75rem 1.5rem; background: #111; color: #fff; border: none; cursor: pointer;">Search</button>
|
|
</form>
|
|
|
|
{% if query %}
|
|
<div style="margin: 1.5rem 0;">
|
|
<h2>Results</h2>
|
|
|
|
{% if results %}
|
|
<p>Found {{ results|length }} individual{% if results|length != 1 %}s{% endif %} matching "{{ query }}"</p>
|
|
|
|
{% for result in results %}
|
|
<div style="margin: 1.5rem 0; padding-left: 1rem; border-left: 2px solid #ccc;">
|
|
<h3><a href="/family-tree/person/{{ result.id }}">{{ result.name }}</a></h3>
|
|
<p>
|
|
{% if result.generation %}Generation {{ result.generation }}{% endif %}
|
|
{% if result.birth_year != "Unknown" %}<br>Born: {{ result.birth_year }}{% endif %}
|
|
{% if result.death_year != "Unknown" %}<br>Died: {{ result.death_year }}{% endif %}
|
|
</p>
|
|
</div>
|
|
{% endfor %}
|
|
{% else %}
|
|
<p>No results found for "{{ query }}"</p>
|
|
{% endif %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
<p style="margin: 1.5rem 0;"><a href="/family-tree">← Back to Family Tree</a></p>
|
|
|
|
<script>
|
|
(function() {
|
|
const results = Array.from(document.querySelectorAll('[style*="border-left: 2px solid #ccc"]'));
|
|
if (results.length === 0) return;
|
|
|
|
let selectedIndex = -1;
|
|
|
|
function selectResult(index) {
|
|
if (selectedIndex >= 0 && selectedIndex < results.length) {
|
|
results[selectedIndex].style.outline = '';
|
|
results[selectedIndex].style.outlineOffset = '';
|
|
results[selectedIndex].classList.remove('selected');
|
|
}
|
|
selectedIndex = Math.max(0, Math.min(index, results.length - 1));
|
|
results[selectedIndex].style.outline = '2px solid #4a7c59';
|
|
results[selectedIndex].style.outlineOffset = '4px';
|
|
results[selectedIndex].classList.add('selected');
|
|
results[selectedIndex].scrollIntoView({ behavior: 'auto', block: 'center' });
|
|
}
|
|
|
|
document.addEventListener('keydown', function(e) {
|
|
if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;
|
|
if (KJVNav.sidebarActive) return;
|
|
|
|
if (e.key === 'ArrowDown' || e.key === 'j') {
|
|
e.preventDefault();
|
|
if (KJVNav.isSelectionOffScreen(results, selectedIndex)) {
|
|
selectResult(KJVNav.findFirstVisibleIndex(results));
|
|
} else {
|
|
selectResult(selectedIndex < 0 ? 0 : selectedIndex + 1);
|
|
}
|
|
} else if (e.key === 'ArrowUp' || e.key === 'k') {
|
|
e.preventDefault();
|
|
if (KJVNav.isSelectionOffScreen(results, selectedIndex)) {
|
|
selectResult(KJVNav.findFirstVisibleIndex(results));
|
|
} else if (selectedIndex <= 0) {
|
|
selectResult(0);
|
|
} else {
|
|
selectResult(selectedIndex - 1);
|
|
}
|
|
} else if (e.key === 'ArrowLeft' || e.key === 'h') {
|
|
e.preventDefault();
|
|
history.back();
|
|
} else if (e.key === 'Enter' && selectedIndex >= 0) {
|
|
e.preventDefault();
|
|
const link = results[selectedIndex].querySelector('a');
|
|
if (link) window.location.href = link.href;
|
|
} else if (e.key === 'Escape') {
|
|
e.preventDefault();
|
|
if (selectedIndex >= 0 && selectedIndex < results.length) {
|
|
results[selectedIndex].style.outline = '';
|
|
results[selectedIndex].style.outlineOffset = '';
|
|
results[selectedIndex].classList.remove('selected');
|
|
}
|
|
selectedIndex = -1;
|
|
}
|
|
});
|
|
})();
|
|
</script>
|
|
{% endblock %}
|