If you need a search for offline pages or simple static pages, may be it is a good solution to do this in Javascript. There are solutions like jQuery Autocomplete to do it well. But if you like Solr, than may be elasticlunr.js is a solution for you.
Elasticlunr.js is a bit like Solr, but much smaller and not as bright, but also provide flexible configuration, query-time boosting, field search and other features.
My case was a static FAQ page with not so much content, but in 9 different languages. So I don’t wan’t to make lists of stop words for every language, like ‘and’, ‘but’, ‘the’ and so on. Also I wanted to boost the words in the questions a little bit compared to the answers. best match should be on top.
So I tried elasticlunr and it works fine. But the examples in the package are a little bit over complicated (the example works local only in Firefox or in a web server – the json calls). So here a few easy steps to the core functionality. So download the package from https://github.com/weixsong/elasticlunr.js.
The html part
It’s not a big deal and looks like this:
<form>
<div class="search-wrapper">
<input type="search" id="search-input">
<div id="search-results"></div>
</div>
</form>
<div class="faqs">
<div class="faq-question">
<div class="faq-headline" id="q-1"></div>
<div class="faq-answer"></div>
<input type="hidden" value="q-1" class="qid">
</div>
</dl>
The Javascript part
We need elasticlunr.js (in production the minified version) and jquery (2.1. or newer) – loading before we can do the search. FaqSearch contains the language of the page. English is default, if you dont need it than just delete lang and the value.
<script src="jquery.js"></script>
<script src="elasticlunr.js"></script>
<script type="text/javascript">FaqSearch("de");</script>
Now we have to do these steps inside the FaqSearch function:
1. Indexing the content of the page and writing it in an array. And than we initialize Elasticlunar with search.addDoc()
function FaqSearch(lang) {
/* Indexing the FAQ content */
var search = elasticlunr(function () {
this.addField('title');
this.addField('body');
this.setRef('id');
});
$(".faq-question").each(function (index, element) {
var $q = $(element);
var question = $q.find(".faq-headline").text();
var answer = $q.find(".faq-answer").text();
var $qid = $q.find(".qid").val();
/* init ElasticLunar */
var docid = {
id: $q.attr('id'),
title: question,
body: answer
};
search.addDoc(docid);
});
2. Listen to the input field. On keyup we looking for the answers from ElasticLunar. if there one, we construct the link and append it in our result list.
$( "#search-faq" ).keyup(function() {
var searchCtrl = $( "#search-input" ).val();
var searchResult = search.search(searchCtrl) || [];
$('#search-results').empty(); /* celar old results */
for (var i = 0; i < searchResult.length; i++) {
var qId = searchResult[i]['ref'];
var q = $('#' + qId + ' .question-content').text();
$('#search-results').append("" + q + " ");
/* open the suggestion list */
$('#search-results').addClass('is-active');
};
$('#search-results').slideDown();
});
}
3. Bring it together. On click jump to the result, hide the suggestion box and optional highlight the result (or open it if you have an accordeon)
$('#search-results').on('click', '.search-result', function() {
$('.faq-question').removeClass('is-active');
$('#search-results').slideUp();
$('.faq-question', $(this).attr("href")).addClass('is-active');
});
} /* closing function FaqSearch(lang) */
Thats it.
Leave a Reply