Ajax is a must these days for websites. It is used in almost all applications and in many cases is used for the wrong reasons. One of those cases is however used for the right reason, Ajax search.

In this tutorial I will be using the acts_as_ferret plugin to implement Ajax search into your view to return similar titles of posts. If you are unfamiliar with acts_as_ferret please read my acts_as_ferret Tutorial post to setup the plugin for you models.

Using the same model (Post) as my tutorial, I am going to implement AJAX search to search for similar post titles.

Javascript defaults

Ensure that in your layout.rhtml file you have a line to include the javascript defaults for Ruby on Rails.

1
2
# application.rhtml
  <%= javascript_include_tag :defaults %>

View

In your view you need to create a text field, and a observe_field Prototype helper.

1
2
3
4
5
6
7
8
# post/new.html.erb
...
<%= text_field('post', 'title')  %>
 
<%= observe_field('post_title',  :frequency => 2, 
    :update => 'similar_posts', :url => 
    { :controller => 'posts', :action=> 'ajax_search' }, 
    :with => "'search=' + escape(value)") %>

Controller

In your controller add a method to handle the Ajax request. In this method use the find_with_ferret method to return a list of posts found by the search. Make sure you add render :layout => false.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# controllers/posts_controller.rb
...
  def ajax_search
    if params['search']
      query = ''
      params['search'].split(' ').each {|token| 
        if(query != '')
          query = query + ' OR ' + token.strip
        else
          query = query + token.strip
        end
      }
      @posts = Post.find_with_ferret(query, :limit => 5)
      render :layout => false
    end
  end

Ajax Partial

This is the HTML that will be generated by the ajax_search method in your controller.

1
2
3
4
5
# views/questions/ajax_search.html.erb
<strong>Similar Posts:</strong><br/>
<% for post in @posts%>
    <%= link_to(post.title, post_url(post)) %> - posted <%= time_ago_in_words(post.created_at)%> ago<br/>
<% end%>

Thats it! Not much to get Ajax searching for your web application! Please post a comment if you have any problems, or send me an email.