Skip to content

creating accessible search¤

this post explores searching documents with https://lunrjs.com to be added to the blog.

    import pandas, importlib.metadata, tonyfast.utils, json
%%
## initializing lunr

load in [lunrjs](https://lunrjs.com)

    display\
```html
<script src="https://unpkg.com/lunr/lunr.js"></script>
```

create the source code load in some actual data to search.


    template =\
~~~javascript
var documents = %s;
var index = lunr(function () {
  this.ref('Name')
  this.field('Summary')
  this.metadataWhitelist = ['position']


  documents.forEach(function (doc) {
    this.add(doc)
  }, this)
})
~~~

for sample data we'll use the python distributions on the machine this was created on.

    distributions =  pandas.Series(importlib.metadata.distributions())

    dist = distributions.attrgetter("metadata").methodcaller("items").apply(dict).series()[
        "Name Summary Home-page".split()
    ]
    search_index = dist.to_dict(orient="records")
    display({"text/html": "<script>%s</script>" % (template % json.dumps(search_index))}, raw=True)
%%
## an accessible form

wip

https://adrianroselli.com/2015/12/responsive-progressive-accessible-vanilla-search.html

an accessible search form

    display\
```html
<form method="post" name="searcher">
<div role="search">
<input name="query" placeholder="Search…" type="text" value=""/>
<button type="submit">perform search</button>
</div>
</form>
<section aria-labelledby="results-label" id="results">
<h2 id="results-label">search results</h2>
<output form="searcher" name="summary"></output>
<ol></ol>
</section>
<script>
var search = document.forms.searcher;
search.addEventListener("submit", (x)=>{
    event.preventDefault();
    var results = index.search(document.forms.searcher.query.value);
    var refs = results.map((x)=>x.ref)    ;
    var original = refs.slice(0, 10).map((x) => documents.find((y) => y.Name === x));
    var ol = document.getElementById("results").querySelector("ol");
    var summary = document.getElementById("results").querySelector("output");
    summary.innerHTML = `${results.length} results found`
    ol.innerHTML = "";
    original.forEach((x)=>{
        var li = document.createElement("li");
        li.innerHTML = `<b>${x.Name}</b> ${x.Summary}`;
        ol.appendChild(li);
    })
    return true; // dont redirect
})
</script>
```