Holmes – Fast and Easy searching inside a Page

Holmes

Detective Holmes filters and seeks your page content based of a value (from an input field, for example) in just 2KB! But the official Detective Author (which works also as developed at the search engine script and service Algolia) restricts the functionality of Holmes to a “limited amount of items”, which are already visible on the page! The script itself also cannot handle typos or incorrect punctuations or spaces.

I just wanted to publish this script like any other, but I had to know what “limited amount of items” means. So I wrote a small script with some demo content, which I use for such purposes. “Some” means in this case more then 900 items. And What should I say… It works. Okay sometimes it hangs a bit while filtering, which may also be due to the enabled mark option. But it works really well, at least in Firefox.

But try it out on your own: https://www.web-scripts.net/demo/holmes-test/

Download the latest version of Holmes as .ZIP or as .TAR package!

npm i holmes.js --save

yarn add holmes.js --save

bower install holmes.js --save

Instructions

The Detective just comes as a unminified JavaScript file, without any Stylesheet. A alternative ECMAScript 6 (ES6) Module-written Script is also available.

 

Load Holmes

Even if Holmes doesn’t offer a Stylesheet, he still requires at least a single option to hide elements. Something like .hidden{ display: none; } within your stylesheet (or within a style attribute, as shown below) is enough!

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        
        <!-- Required Style -->
        <style type="text/css">
            .hidden{
                display: none;
            }
        </style>
    </head>
    <body>
        <!-- Required JavaScript -->
        <script type="text/javascript" src="/js/holmes.js"></script>
        
        <!-- Example HTML Structure -->
        <input type="search" class="holmes-search">
        <div class="holmes-list">
            <div class="item"><!-- Any Content --></div>
            <div class="item"><!-- Any Content --></div>
            <div class="item"><!-- Any Content --></div>
            <div class="item"><!-- Any Content --></div>
            <div class="item"><!-- Any Content --></div>
        </div>
        
        <!-- Example JavaScript -->
        <script type="text/javascript">
            holmes({
                input:  'input[type=search].holmes-search',
                find:   '.holmes-list > .item',
            });
        </script>
    </body>
</html>

 

Configure Holmes

Holmes hooks itself within the DOMContentLoaded per default, so you just need to init Holmes as shown below. It is also highly recommended to read the official documentation about the available methods and functions!

holmes({
    input:              'input[type=search]',
    find:               '',
    placeholder:        false,
    mark:               false,
    class:  {
        visible:    false,
        hidden:     "hidden"
    },
    dynamic:            false,
    contenteditable:    false,
    instant:            false,
    minCharacters:      0,
    hiddenAttr:         true,
    onHidden:           function(){},
    onVisible:          function(){},
    onEmpty:            function(){},
    onFound:            function(){},
    onInput:            function(){}
});

 

Configure: Options

input
A querySelector String to find the responsible input search field.
find
A querySelectorAll String rule to find each of the find terms.
placeholder
Text to show when there are no results (innerHTML).
mark
Whether to <mark></mark> the matching text Text to show when there are no results (innerHTML).
class.visible
The class to add to matched items
class.hidden
The class to add to non-matched items
dynamic
Whether to query for the content of the elements on every input. If this is false, then only when initializing the script will fetch the content of the elements to search in. If this is true then it will refresh on every input event.
contenteditable
DEPRECATED (now handled automatically) whether the input is a contenteditable or not. By default it’s assumed that it’s <input>, true here will use <div contenteditable>
instant
DEPRECATED (after v1.13.3) use holmes({}).start(); instead By default Holmes waits for the DOMContentLoaded event to fire before listening. This is to make sure that all content is available. However if you exactly know when all your content is available (ajax, your own event or other situations), you can put this option on true.
minCharacters
The minimum amount of characters to be typed before Holmes starts searching. Beware that this also counts when backspacing.
hiddenAttr
Adds hidden="true" to hidden elements. interesting link explaining its use.
onHidden
Callback for when an item is hidden.
onVisible
Callback for when an item is visible again
onEmpty
Callback for when an item is visible again
onFound
Callback for when items are found after being empty.
onInput
Callback for every input.

Leave a Reply

Top