twitter-bootstraptypeahead.jssearch-box

How to improve typeahead suggestions in search box


I am newbie to front-end development. I have implemented search box in one of our old legacy .net application. It is working fine but it needs to be improved. My search result basically return 'a href' tag. So users can directly click on it and do their work.

Issue:

For e.g:

If I type 'test report' it shows me correct suggestions, but I can see tag while scrolling down.

enter image description here

What I am looking for:

For e.g: in above case I want to see 'Test Report PSC' in text box but at the same time 'Test Report PSC' should be clickable.

Please point me in correct direction here, thank you.

Code: HTML file

<div class="app-header-icons pull-right">
   <div class="app-header-icon app-search-icon">
      <div class="app-header-search-container">
           <label for="search" class="sr-only">Search</label>
           <input class="typeahead form-control"  id="search" type="search" autocomplete="off" placeholder="Start Searching..."/>
       </div>
       <i class="tem tem-search"></i>
    </div>
</div>

JS file

 $(document).ready(function () {      

    var substringMatcher = function (reportNames) {
        return function findMatches(inputString, callbackFunc) {
            var matches = [];
            var substrRegex = new RegExp(inputString, "i");
            $.each(reportNames, function (i, reportName) {
                if (substrRegex.test(reportName)) {
                    matches.push({ value: reportName });
                }
            });
            callbackFunc(matches);
        };
    };

    //reportNames is an array
    // reportName[0] = <a href="blah" title="blah"> Actual Value </a>
    var reportNames = getReportSearchLists(); 

    $("#search").typeahead({
        hint: true,
        highlight: true,
        minLength: 3,
        order: "asc"
    },
    {
        name: "reportNames",
        displayKey: "value",
        source: substringMatcher(reportNames)
    }).bind('typeahead:selected', function (obj, datum) {
        $('.typeahead').typeahead('val', '');
    });});

Solution

  • The typeahead will display exactly the values you give it. In this case, because the value is <a href="blah" title="blah"> Actual Value </a> that is exactly what you will see in the suggestion list.

    I don't know if you will be able to get all the behavior you are after, but this should point you in the right direction.

    Modify getReportSearchLists() to return objects instead of strings, such as:

    [
      { "title":"My Report","url":"/my/url/to/report" },
      { "title":"Other Report","url":"/my/url/to/report" },
      { "title":"Something Report","url":"/my/url/to/report" }
    ]
    

    Update substringMatcher to return objects:

    var substringMatcher = function (reportNames) {
        return function findMatches(inputString, callbackFunc) {
            var matches = [];
            var substrRegex = new RegExp(inputString, "i");
            $.each(reportNames, function (i, obj) {
                if (substrRegex.test(obj.title)) {
                    matches.push(obj);
                }
            });
            callbackFunc(matches);
        };
    };
    

    Use a template to display the suggestion:

    $('.typeahead').typeahead({
      highlight: true
    }, {
      name: 'reports',
      display: 'title',
      source: substringMatcher(reportNames),
      templates: {
        empty: [
          '<div><strong>No match found</strong></div>'
        ].join('\n'),
        suggestion: '<div class="card"><a href="' + obj.url + '"><strong>' + obj.title + '</strong></a></div>')
      }
    });