Commit 35b00cd49c00adfcf89f703806b5656f6d4ef93f

Authored by Rodrigo Souto
1 parent 131516d4

[search-improvements] Add search query suggestions infra-structure

app/controllers/application_controller.rb
... ... @@ -169,6 +169,11 @@ class ApplicationController < ActionController::Base
169 169 fallback_find_by_contents(asset, scope, query, paginate_options, options)
170 170 end
171 171  
  172 + def find_suggestions(asset, query, options={})
  173 + plugins.dispatch_first(:find_suggestions, asset, query, options) ||
  174 + fallback_find_suggestions(asset, query, options)
  175 + end
  176 +
172 177 private
173 178  
174 179 def fallback_find_by_contents(asset, scope, query, paginate_options, options)
... ... @@ -177,4 +182,7 @@ class ApplicationController < ActionController::Base
177 182 {:results => scope.paginate(paginate_options)}
178 183 end
179 184  
  185 + def fallback_find_suggestions(asset, query, options)
  186 + #TODO Implement fallback suggestions solution
  187 + end
180 188 end
... ...
app/controllers/public/search_controller.rb
... ... @@ -4,11 +4,11 @@ class SearchController < PublicController
4 4 include SearchHelper
5 5 include ActionView::Helpers::NumberHelper
6 6  
7   - before_filter :redirect_asset_param, :except => :assets
8   - before_filter :load_category
9   - before_filter :load_search_assets
10   - before_filter :load_query
11   - before_filter :load_filter
  7 + before_filter :redirect_asset_param, :except => [:assets, :suggestions]
  8 + before_filter :load_category, :except => :suggestions
  9 + before_filter :load_search_assets, :except => :suggestions
  10 + before_filter :load_query, :except => :suggestions
  11 + before_filter :load_filter, :except => :suggestions
12 12  
13 13 # Backwards compatibility with old URLs
14 14 def redirect_asset_param
... ... @@ -143,6 +143,10 @@ class SearchController < PublicController
143 143 render :partial => 'events/events'
144 144 end
145 145  
  146 + def suggestions
  147 + render :text => find_suggestions(params[:term], environment, params[:asset]).to_json
  148 + end
  149 +
146 150 #######################################################
147 151 protected
148 152  
... ...
app/helpers/application_helper.rb
... ... @@ -1402,4 +1402,8 @@ module ApplicationHelper
1402 1402 content_tag('ul', article.versions.map {|v| link_to("r#{v.version}", @page.url.merge(:version => v.version))})
1403 1403 end
1404 1404  
  1405 + def search_input_with_suggestions(name, asset, default, options = {})
  1406 + text_field_tag name, default, options.merge({:id => 'search-input', 'data-asset' => asset})
  1407 + end
  1408 +
1405 1409 end
... ...
app/views/search/_search_form.html.erb
... ... @@ -8,7 +8,7 @@
8 8  
9 9 <div class="search-field">
10 10 <span class="formfield">
11   - <%= text_field_tag 'query', @query, :id => 'search-input', :size => 50 %>
  11 + <%= search_input_with_suggestions('query', @asset, @query, {:size => 50}) %>
12 12 <%= javascript_tag "jQuery('#search-input').attr('title', \"#{hint}\").hint()" if defined?(hint) %>
13 13 </span>
14 14  
... ...
lib/noosfero/plugin.rb
... ... @@ -507,6 +507,17 @@ class Noosfero::Plugin
507 507 def find_by_contents(asset, scope, query, paginate_options={}, options={})
508 508 end
509 509  
  510 + # -> Suggests terms based on asset and query
  511 + # returns = [a, b, c, ...]
  512 + def find_suggestions(query, context, asset, options={:limit => 5})
  513 + context.search_terms.
  514 + where(:asset => asset).
  515 + where("search_terms.term like ?", "#{query}%").
  516 + where('search_terms.score > 0').
  517 + order('search_terms.score DESC').
  518 + limit(options[:limit]).map(&:term)
  519 + end
  520 +
510 521 # -> Adds aditional fields for change_password
511 522 # returns = [{:field => 'field1', :name => 'field 1 name', :model => 'person'}, {...}]
512 523 def change_password_fields
... ...
public/javascripts/application.js
... ... @@ -1101,4 +1101,24 @@ jQuery(document).ready(function(){
1101 1101 jQuery("#article_has_terms_of_use").click(function(){
1102 1102 showHideTermsOfUse();
1103 1103 });
  1104 +
  1105 + // Suggestions on search inputs
  1106 + (function($) {
  1107 + var suggestions_cache = {};
  1108 + $("#search-input").autocomplete({
  1109 + minLength: 2,
  1110 + source: function(request, response) {
  1111 + var term = request.term;
  1112 + if (term in suggestions_cache) {
  1113 + response(suggestions_cache[term]);
  1114 + return;
  1115 + }
  1116 + request["asset"] = $("#search-input").data("asset");
  1117 + $.getJSON("/search/suggestions", request, function(data, status, xhr) {
  1118 + suggestions_cache[term] = data;
  1119 + response(data);
  1120 + });
  1121 + }
  1122 + });
  1123 + })(jQuery);
1104 1124 });
... ...