Rails - Using Autocomplete with the Scoped_search gem? - ruby-on-rails

I'm using the scoped_search gem for basic search functionality on my site. Scoped search: http://github.com/wvanbergen/scoped_search
I'm using the most basic possible implementation of this gem. I'm searching on the name attribute in a user model only. On the frontend, in users/index, the search input is a text_field_tag.
<% form_tag users_path, :method => :get do %>
<%= text_field_tag :search, params[:search], :value => 'Search' %>
<%= submit_tag "Go", :name => nil %>
<%end%>
In the user model, I have:
scoped_search :on => :name
I want to implement basic auto-complete functionality on the user model, name attribute. This would be the most basic use case if I was searching in a form element of the user model, but the scoped_search part is throwing me off.
I was planning to use DHH's auto_complete plugin, but I'm open to using whatever tool helps me accomplish this.
Auto-complete: http://github.com/rails/auto_complete
Thanks.

In the model you should replace the
line:
scoped_search :on => :name
with:
scoped_search :on => :name, :complete_value => true
In the view replace the line:
<%= text_field_tag :search, params[:search], :value => 'Search' %>
with:
<%= auto_complete_field_tag_jquery(:search, params[:search], {},{}) %>
In the controller you should add the following method:
def auto_complete_search
#items = User.complete_for(params[:search])
render :json => #items
end

did you see the demo app at https://github.com/abenari/scoped_search_demo_app ?
Alternatively, you can see how I use it in my project - https://github.com/ohadlevy/foreman
Ohad

Related

Rails - Is there a way to autocomplete with form_tag attribute?

My search bar is using a form_tag type, and I can search and enter and it will show results, but it will not give autocompletion or suggestions when typing in the search bar.
When the user starts typing, I want it to display usernames.
Here is what I have tried:
This view is my application.html.erb and it is on my navbar. I dont know if that is also important.
<%= form_tag users_path, :autocomplete => "on", :method => 'get', :id => 'users_search' do %>
<%= text_field_tag :search, params[:search], placeholder:"search members..",style:"width:300px; height:35px;"
%>
<%= submit_tag "", :name => nil, :style => "display: none;" %>
<% end %>
I also tried :autocomplete => :on in the text_field_tag. I'm just not sure how to go about this using form_tag.
Here is the rest of my code that may be important:
User_controller.rb
def index
#users = User.search(params[:search])
end
User.rb
def self.search(username)
if username
username.downcase!
where("username LIKE ?","#{username}%")
else
all
end
end

Rails 5: Two search form_tags on the same page

I'm trying to implement a two search form_tag on a the same page, each search form is placed inside dynamic bootstrap tabs. The first one which is working is basic a search form with one field. The second one which is not working has two fields, one is the same search method as the first and the other I'm trying to get the address from the other_location field and via params[:other_location].
With the current setup the other_location field form the second form does not appear!
Both of the forms are inside partials and I am rendering them inside two dynamic bootstrap tabs like this:
<%= render 'pages/search' %>
<%= render 'pages/search_other' %>
<%= form_tag search_items_path, :method => "get" do %>
<%= text_field_tag :search, params[:search], autofocus: true,
class: "search-query search_size",
placeholder: "Enter product to search" %>
<%= submit_tag "Search", name: nil, :style => "display: none;" %>
<%end%>
<%= form_for :search_other_path, :method => "get" do |form| %>
<%= form.text_field :search, autofocus: true,
class: "search-query search_size",
placeholder: "Enter keyword to search" %>
<% form.fields_for :other_location_path, :method => "get" do |f| %>
<%= f.text_field :other_location, class: "search-query search_size",
placeholder: "Enter address to search" %>
<%= form.submit "Search", name: nil, :style => "display: none;" %>
<%end%>
<%end%>
model
def self.search(search)
return where("0=1") if search !~ /\w{4}/
where("lower(title) LIKE lower(:term)", term: "%#{search}%")
end
routes.rb
get 'search' => 'pages#search', as: 'search_posts'
get 'search' => 'pages#search_other', as: 'search_other'
get 'search' => 'pages#other_location', as: 'other_location'
controller:
def search_other
if params[:search]
#posts = Post.near(other_location,10).search(params[:search]).page(params[:page])
else
#posts = []
end
end
def other_location
other_location = params[:other_location]
if params[:other_location]
Geocoder.search(params[:other_location])
end
end
def search
if params[:search]
#posts = Post.near(action,10).search(params[:search]).page(params[:page])
else
#posts = []
end
end
On your route file:
get 'search/other' => 'pages#search_other', as: 'search_other'
get 'search' => 'pages#search_other', as: 'search_other_items'
both GET requests are going to your pages_controller.rb #search_other method. So even if you have the two form_tags sending the data to different paths (search_other_path, and search_other_items_path) it would be going to the same controler method - which is redundant.
On your actual HTML you have two form tags:
<%= form_tag search_items_path, :method => "get" do %>
and
<%= form_tag search_other_items_path, :method => "get" do %>
You have not mentioned search_items_path in your routes, so I have no idea where that's pointing to. Likely its a proper controller that works since you mentioned the first form was the only one working.
Now, your mentioned controller only has a search method. So to start you are looking at the wrong controller. You should be looking at the controller methods being referenced by the form's action.
In this case, the second form is sending it's request to search_other_items_path which according to your routes, its pointing to pages_controller.rb -> #search_other method.
You should edit your question to include code that is actually relevant. Maybe then I can actually help.

Change URL by filter

I am using friendly_id so that I can create such URLs:
/search/france/weekly/toyota-95
My routes:
scope to: 'search#show' do
get '/search/:car_country_id/:rental_type_id/:car_group_id', as: 'search_country'
end
At the search#show view I have a form:
<%= form_tag search_country_path, :method => :get do %>
<%= select_tag(:car_country_id, options_from_collection_for_select(CarCountry.all, :slug, proc {|c| c.name }, {:selected => #country}), class: "Select-control u-sizeFull") %>
<%= submit_tag t('shared.search'), class: 'btn btn-primary' %>
<% end %>
And search controller:
#country = CarCountry.friendly.find(params[:car_country_id])
So ok, my intention is to change the URL as:
/search/italy/weekly/toyota-95
But the thing is, Rails params always sending france as car_country_id when I select country from select tag and submit it.
So what should I do?
Currently, two car_country_id are sent to Rails server. You can rename one of them:
<%= select_tag(:new_car_country_id, options_from_collection_for_select(CarCountry.all, :slug, proc {|c| c.name }, {:selected => #country}), class: "Select-control u-sizeFull") %>
In your controller, you should check whether new_car_country_id exists. If it does, then redirect to the corresponding path.
Another way is to make sure that the two car_country_id are the same. You should change the form's submit path once select_tag is updated with JavaScript.

Rails: collection_check_boxes to filter search results

I'm trying to implement a search view which enables users to search other users based on keyword AND multiple checkboxes for their tags. I'm still trying to figure out how to place the collection_check_boxes right, so that view is rendered correctly. Here's what I have so far:
<%= form_tag users_path, :method => 'get' do %>
<%= collection_check_boxes :options, :tag_ids, Tag.order(:name), :id, :name, {multiple: true} %>
<%= text_field_tag :search, params[:search], :placeholder => "Search", :id => "query" %>
<%= submit_tag "Search", :name => nil, :style => "float:left;"%>
<% end %>
Can you help me complete the view function above by making sure that, when a user clicks search collection_check_boxes will add something like tag=tag1&tag2&tag3 to the url?
I will try :)
Generally everything is OK. Only small correction, if you change this line:
<%= collection_check_boxes :options, :tag_ids, Tag.order(:name), :id, :name, {multiple: true} %>
to this:
<%= collection_check_boxes :tag, :ids, Tag.order(:name), :id, :name, {multiple: true} %>
after submitting request, in URL will be something like this:
&tag%5Bids%5D%5B%5D=&tag%5Bids%5D%5B%5D=3&tag%5Bids%5D%5B%5D=2&search=test
more human view:
&tag[ids][]=&tag[ids][]=3&tag[ids][]=2&search=test
and this is OK. It always look like this when sending an array. In this particular case I've checked two checkboxes (with id=2 and 3). I don't know why there is also empty element :), but this is not a problem. I think there is no way to get results exactly like tag=tag1&tag2&tag3
In your "users" model you can get to the params by (after submitting form):
params[:tag][:ids] - array of id (checked checkboxes)
params[:search] - search input value
If you want to have checked some checkboxes on start (or after submit), add to collection_check_boxes additional parameter:
options = {:checked=>tag_ids}
and deliver in variable tag_ids array of checkboxes id (which should be checked). All the code looks like this:
<%if params.has_key?(:tag)%>
<%tag_ids = params[:tag][:ids]%>
<%else%>
<%tag_ids = Array.new%>
<%end%>
<%=form_tag drons_path, :method => 'get' do %>
<%=collection_check_boxes :tag, :ids, Tag.order(:name), :id, :name, {multiple: true}, options = {:checked=>tag_ids}%>
<%=text_field_tag :search, params[:search], :placeholder => "Search", :id => "query"%>
<%=submit_tag "Search", :name => nil, :style => "float:left;"%>
<%end %>

how to get simple search in rails based on RailsCasts tutorial?

I followed the RailsCasts tutorial to do a simple search with autocomplete, but it doesn't work. :(
view/vendors/index:
<% form_tag vendors_path, :method => 'get' do %>
<%= text_field_with_auto_complete :vendor,
:name,
{},
{:method => :get, :class => 'textbox'} %>
<%= submit_tag "Search", :name => nil %>
<% end %>
</div>
<%= #searchvendor.id %>
<%= #searchterm %>
I included #searchterm and #searchvendor.id as validation steps.
So this should call the controller => vendor, action=> index:
def index
#searchterm = params[:vendor][:name]
#searchvendor = Vendor.search('checkpoint')
And the search method is created as follows for the vendor/model:
def self.search(search)
if search
find(:all, :conditions => ['name LIKE ?', "%#{search}%"])
else
find(:all)
end
The output?
#searchterm does show the value that is inputed as that shows up in the URL as vendor[name]=?
#searchvendor.id is a long string and #searchvendor.name shows an error, name not a method.
I'm stumped. Help...please?
LINK to the Tutorial:
http://railscasts.com/episodes/37-simple-search-form
Should you not be passing in your #searchterm into your Vendor.search method? Passing 'checkpoint' each time probably isn't going to do the trick.
#searchvendor is going to contain an Array as you are doing find(:all). You'll need to iterate over the array and do .name on each item.

Resources