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.
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.
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.
精彩评论