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

369 views Asked by At

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.

2

There are 2 answers

0
Aaron Chambers On BEST ANSWER

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.

3
dbuthay On

You probably want to use InstantLinks instead.

If you really want to tweak autocomplete, you should change the _renderItem property of the jQuery UI widget associated with Indextank Autocomplete.

$("#query").data("autocomplete")._renderItem = function(ul, item) { .. }

See jQuery UI Autocomplete documentation for an example.