Rails implementation of search with autocomplete
Use Twitter typeahead. There are some examples here:
http://twitter.github.com/typeahead.js/examples/
Twitter typeahead and all the information you need is available from https://github.com/twitter/typeahead.js/
How to use
The use depends on the data you are going to have as 'suggested'. For example, if it is static data (always going to be the same) you can implement it this way:
$('input.typeahead').typeahead({
local: ['suggestion1', 'suggestion2', 'suggestion3',...., 'suggestionN']
#The typeahead is going to load suggestions from data in local.
});
If the data changes and it came from a model or a db table then you can try:
Controller:
def load_suggestions
@suggestions = MyModel.select(:name) or MyModel.find(:all, conditions: [...]) #Select the data you want to load on the typeahead.
render json: @suggestions
end
JS file:
$('input.typeahead').typeahead([
{
prefetch: 'https://www.mipage.com/suggestion.json' #route to the method 'load_suggestions'
#This way, typeahead will prefecth the data from the remote url
}
]);
Best auto complete/suggest for a search form in rails 3
jqueryui is a great resource.
here is a demo of autocomplete, you can view the source to see how to implement on your server.
http://jqueryui.com/demos/autocomplete/
the javascript sends a term=TERM to your controller. Mine is setup like this:
def autocomplete
@movies= Movie.select("id, title").where("title LIKE ?", "#{params[:term]}%").limit(20)
@hash = []
@movies.each do |movie|
@hash << {"label" => movie.title, "id" => movie.id}
end
render :json => @hash
end
customize to how you see fit.
Ruby on Rails - Simple Form autocomplete association search
autocomplete_source is expecting an array or a URL that when called returns JSON with the results that match the query. http://api.jqueryui.com/autocomplete/#option-source
Right now you have
<%= f.input :user_name, as: :search, data:
{autocomplete_source: User.pluck(:name)} %>
Thats probably going to return a string for javascript. So you could change it to something like:
<%= f.input :user_name, as: :search, data:
{autocomplete_source: User.pluck(:name).to_json} %>
And then parse that JSON when setting up your autocomplete:
jQuery ->
$('#task_user_name').autocomplete
source: JSON.parse($('#task_user_name').data('autocomplete-source'))
In the long run though (when you have a lot of users) this will impact the load time of your page significantly. You should really instead follow that railscast and put a URL as the autocomplete source:
<%= f.input :user_name, as: :search, data:
{autocomplete_source: users_path} %>
Make sure to add the json render path to the index action on your users controller.
If your index action is used for other things too you can use respond_to
:
# users_controller
def index
@users = User.order(:name)
@users = @users.where("name like ?", "%#{params[:term]}%") if params[:term]
respond_to do |format|
format.html # index.html.erb
format.json { render :json => @users.map(&:name) }
end
end
Autocomplete multiple fields with jquery in Rails 5
I've managed to make it work using a different method with the rails-jquery-autocomplete gem:
https://github.com/risuiowa/rails-jquery-autocomplete/
Using the
autocomplete_field
turned out to be much easier to implement.
Example:
form_for @product do |f|
f.autocomplete_field :brand_name, autocomplete_brand_name_products_path
end
Implement autocomplete on MongoDB
As suggested by @Thilo, you can use several ideas including prefixing.
The most important thing is to have very quick request (because you want autocomplete to feel instaneous). So you have to use query which will use properly indexes.
With regexp : use /^prefix/
(the important thing is the ^ to specify the beginning of line which is mandatory to make the query use index).
The range query is good too : { $gt : 'jhc', $lt: 'jhd' } }
More complicated but faster : you can store prefix-trees in mongo (aka tries) with entries like :
{usrPrefix : "anna", compl : ["annaconda", "annabelle", "annather"]}
{usrPrefix : "ann", compl : ["anne", "annaconda", "annabelle", "annather"]}
This last solution is very fast (if indexes on compl of course) but not space efficient at all. You know the trade-off you have too choose.
Rails gem rails3-jquery-autocomplete: How do I query multiple fields
Your pseudo attribute works only on records already retrieved, but it has no bearing on searching for records. Probably the easiest solution is a named named scope like:
scope :search_by_name, lambda { |q|
(q ? where(["first_name LIKE ? or last_name LIKE ? or concat(first_name, ' ', last_name) like ?", '%'+ q + '%', '%'+ q + '%','%'+ q + '%' ]) : {})
}
Thus, a call like:
Person.search_by_name(params[:q])
will return an appropriate result set. It will also return all entries if no param was passed (or more specifically, this scope will add nothing extra), making it an easy drop-in for the index action.
Is it possible to get autocomplete for a rails application in text editors, not only text fields
The answer of abstraktor gave me a good starting point, but there were some missing parts. So I developed an example on github: jquery-autocomplete-inner
Here is the complete source code of the example (no HTML), and some explanation:
$().ready(function() {
// search only, if the regexp matches
var cities = [
"Amsterdam", "Stuttgart", "Singapore", "Madrid", "Barcelona", "Hamburg",
"Esslingen", "Berlin", "Frankfurt", "Essingen", "Straßburg", "London",
"Hannover", "Weil am Rhein", "Tuttlingen", "München", "Marsaille", "Paris",
"Manchester", "Rome", "Neapel", "New York", "Brasil", "Rio de Janeiro"
];
// Defines for the example the match to take which is any word (with Umlauts!!).
function _leftMatch(string, area) {
return string.substring(0, area.selectionStart).match(/[\wäöüÄÖÜß]+$/)
}
function _setCursorPosition(area, pos) {
if (area.setSelectionRange) {
area.setSelectionRange(pos, pos);
} else if (area.createTextRange) {
var range = area.createTextRange();
range.collapse(true);
range.moveEnd('character', pos);
range.moveStart('character', pos);
range.select();
}
}
$("#citites").autocomplete({
position: { my : "right top", at: "right bottom" },
source: function(request, response) {
var str = _leftMatch(request.term, $("#citites")[0]);
str = (str != null) ? str[0] : "";
response($.ui.autocomplete.filter(
cities, str));
},
//minLength: 2, // does have no effect, regexpression is used instead
focus: function() {
// prevent value inserted on focus
return false;
},
// Insert the match inside the ui element at the current position by replacing the matching substring
select: function(event, ui) {
//alert("completing "+ui.item.value);},
var m = _leftMatch(this.value, this)[0];
var beg = this.value.substring(0, this.selectionStart - m.length);
this.value = beg + ui.item.value + this.value.substring(this.selectionStart, this.value.length);
var pos = beg.length + ui.item.value.length;
_setCursorPosition(this, pos);
return false;
},
search:function(event, ui) {
var m = _leftMatch(this.value, this);
return (m != null )
}
});
})
- First the data of the examples, some cities (mostly German)
- A helper function to extract the matching substring left from the cursor, named _leftMatch
- A helper function copied mostly from jQuery Set Cursor Position in Text Area
- Then in the usage of autocomplete the following points:
- Search only when the substring (_leftMatch) before the cursor position matches the defined regexpression (in my example
/[\wäöüÄÖÜß]+$/
--> all german work characters). - Filter the source things by using the request - response variation and filtering there by the substring (as in the other examples of autocomplete with multiple values
- Replace the matching substring with the selection from the user and ensure that the cursor is positioned right after that.
- Search only when the substring (_leftMatch) before the cursor position matches the defined regexpression (in my example
If you want to take a look, download the zip-file from the GitHup repository and start the local example under examples/cities-local.html
.
Related Topics
Open and Save Base64 Encoded Image Data Uri in Ruby
How to Get the Unique Elements from an Array of Hashes in Ruby
Installing Ruby 2.3 on Wsl (Windows Subsystem for Linux)
Split Array into Sub-Arrays Based on Value
Rails 3: Call Functions Inside Controllers
Why Isn't My Cocoapods Post_Install Hook Updating My Preprocessor MACros
Converting Nested Hash Keys from Camelcase to Snake_Case in Ruby
How to Do Attr_Accessor_With_Default in Ruby
How to Start the Ruby Debugger on Exception
What Does the Operator ||= Stand for in Ruby
Polymorphic Association with Multiple Associations on the Same Model
Using the Value of a Variable as Another Variables Name in Ruby
How to Look Up Elevation Data by Lat/Lng
Get Server File Path with Paperclip
How to Recursively Require All Files in a Directory in Ruby
How to Use Ruby Metaprogramming to Add Callbacks to a Rails Model