Search code examples
rubyherokuindextank

IndexTank autocomplete: modifying the autocomplete field text for each result returned


I have a Ruby/Sinatra application deployed on Heroku and I am using the IndexTank plugin to provide Full Text Search capability.

I am currently using the out of the box autocomplete functionality as per the IndexTank Autocomplete Documentation

Currently I have indexed my documents such that the default :text field contains the city name and country name of a document. ie:

@index.document("1").add({:text => "London England"})

When I do a search in the default autocomplete field it does in fact work and return a result, however not what I would have expected, or liked.

When I type in 'lon' into the field, it returns 'london'. This is indeed the correct document but I was hoping that it would actually return me 'London England'.

Does anybody know how I go about modifying the data that is rendered in the autocomplete field dropdown so that it displays 'London England' when I search for 'lon'?


UPDATE

I have also tried the InstantLinks functionality as suggested in the comments but this also does not quite do what I need to do. It seems that both solutions do about 80% of what I need, but unfortunately I need something extra.

The two things about InstantLinks that don't work as I need is:

  • While I can select which field from the index to display in the drop down (which is what I couldn't do with the Autocomplete functionality), when I use the arrow keys to select the options in the drop down, the selected option does not display in the text field.

  • When I do select an entry from the drop down, I am taken to another page, the URL of which is supposed to have been pulled from the index. All I want to happen is the value of the entry selected to be populated into the original text field.

So, unfortunately I can't see how InstantLinks is going to give me the functionality I am after either.


Solution

  • Ok, so I finally worked out a way to solve my problem however, I was not able to use either the Autocomplete or InstantLinks functionality provided by IndexTank.

    In short what I did was use the out of the box jQuery autocomplete widget (which I know the IndexTank Autocomplete uses under the covers) to call a restful service I created which queries the IndexTank index.

    First I created the restful service in my Sinatra Application

    get '/index/' do
        term = params['term']
    
        #Query IndexTank index using the IndexTank::Client
    
        #Parse index search results and return an array of the suggestions as JSON
    end
    

    Next, I used the jQuery autocomplete widget to use my restful service as a remote source. First there is my HTML input:

    <form id="search_form" action="/" method="POST">
        <input id="search_field" name="search_field" type="text">
    </form>
    

    Then the javascript to bind the autocomplete widget to the input:

    $(document).ready(function(){
        $("#search_field").autocomplete({
          source: function(request, response) {
            $.ajax({
              url: "/index/",
              dataType: 'json',
              data: { term: request.term },
              success: function(data) {
                response($.map(data, function(item) {
                  return {label: __highlight(item, request.term),
                    value: item};
                }));
              }
            });
          },
          minLength: 2
        })
        .data( "autocomplete" )._renderItem = function( ul, item ) {
          // only change here was to replace .text() with .html()
          return $( "<li></li>" )
            .data( "item.autocomplete", item )
            .append( $( "<a></a>" ).html(item.label) )
            .appendTo( ul );
        };
      });
    
      function __highlight(s, t) {
        var matcher = new RegExp("("+$.ui.autocomplete.escapeRegex(t)+")", "ig" );
        return s.replace(matcher, "<strong>$1</strong>");
      }
    

    And there you have it, an autocomplete field that queries an IndexTank index and displays the desired index field in the suggestions drop down.