aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--app/controllers/public_body_controller.rb12
-rw-r--r--app/controllers/request_controller.rb6
-rw-r--r--app/views/layouts/default.rhtml5
-rw-r--r--app/views/public_body/_search_ahead.rhtml18
-rw-r--r--app/views/public_body/show.rhtml3
-rw-r--r--app/views/request/select_authority.rhtml49
-rw-r--r--config/routes.rb7
-rw-r--r--public/stylesheets/main.css24
-rw-r--r--spec/controllers/public_body_controller_spec.rb35
9 files changed, 153 insertions, 6 deletions
diff --git a/app/controllers/public_body_controller.rb b/app/controllers/public_body_controller.rb
index 05acf4868..ea1ffb619 100644
--- a/app/controllers/public_body_controller.rb
+++ b/app/controllers/public_body_controller.rb
@@ -168,5 +168,17 @@ class PublicBodyController < ApplicationController
:filename => 'all-authorities.csv',
:disposition =>'attachment', :encoding => 'utf8')
end
+
+ # Type ahead search
+ def search_typeahead
+ # Since acts_as_xapian doesn't support the Partial match flag, we work around it
+ # by making the last work a wildcard, which is quite the same
+ query = params[:q] + '*'
+
+ query = query.split(' ').join(' OR ') # XXX: HACK for OR instead of default AND!
+ @xapian_requests = perform_search([PublicBody], query, 'relevant', 'request_collapse', 5)
+
+ render :partial => "public_body/search_ahead"
+ end
end
diff --git a/app/controllers/request_controller.rb b/app/controllers/request_controller.rb
index f36fae463..d39b78f36 100644
--- a/app/controllers/request_controller.rb
+++ b/app/controllers/request_controller.rb
@@ -22,6 +22,10 @@ class RequestController < ApplicationController
rescue MissingSourceFile, NameError
end
+ def select_authority
+ medium_cache
+ end
+
def show
medium_cache
@locale = self.locale_from_params()
@@ -66,7 +70,7 @@ class RequestController < ApplicationController
@last_info_request_event_id = @info_request.last_event_id_needing_description
@new_responses_count = @info_request.events_needing_description.select {|i| i.event_type == 'response'}.size
-1
+
# Sidebar stuff
# ... requests that have similar imporant terms
behavior_cache :tag => ['similar', @info_request.id] do
diff --git a/app/views/layouts/default.rhtml b/app/views/layouts/default.rhtml
index a14dfcf8e..97462fc91 100644
--- a/app/views/layouts/default.rhtml
+++ b/app/views/layouts/default.rhtml
@@ -80,11 +80,12 @@
<%= submit_tag _("Search") %>
</p>
<% end %>
-
</div>
+
<div id="topnav">
<ul id="navigation">
- <li><%= link_to _("Make request"), frontpage_url %></li>
+ <li><%= link_to _("Home"), frontpage_url %></li>
+ <li><%= link_to _("Make request"), select_authority_url %></li>
<li><%= link_to _("View requests"), request_list_successful_url %></li>
<li><%= link_to _("View authorities"), list_public_bodies_default %></li>
<% if @user %>
diff --git a/app/views/public_body/_search_ahead.rhtml b/app/views/public_body/_search_ahead.rhtml
new file mode 100644
index 000000000..19c7eb4e8
--- /dev/null
+++ b/app/views/public_body/_search_ahead.rhtml
@@ -0,0 +1,18 @@
+<p>
+ <% if @xapian_requests.results.size > 0 %>
+ <h3><%= _('Top search results:') %></h3>
+ <p>
+ <%= _('Select one to see more information about the authority.')%>
+ </p>
+ <% else %>
+ <h3><%= _('No results found.') %></h3>
+ <% end %>
+ <div id="authority_search_ahead_results">
+ <% for result in @xapian_requests.results %>
+ <%= render :partial => 'body_listing_single', :locals => { :public_body => result[:model] } %>
+ <% end %>
+ </div>
+</p>
+
+
+
diff --git a/app/views/public_body/show.rhtml b/app/views/public_body/show.rhtml
index 3d325e2b8..78a326d72 100644
--- a/app/views/public_body/show.rhtml
+++ b/app/views/public_body/show.rhtml
@@ -21,6 +21,7 @@
<%= link_to _('View FOI email address'), view_public_body_email_url(@public_body.url_name) %><br>
</div>
+<div id="main_content">
<h1><%=h(@public_body.name)%></h1>
<p class="subtitle">
@@ -99,4 +100,4 @@
<% end %>
<p> <%= _('The search index is currently offline, so we can\'t show the Freedom of Information requests that have been made to this authority.')%></p>
<% end %>
-
+</div>
diff --git a/app/views/request/select_authority.rhtml b/app/views/request/select_authority.rhtml
new file mode 100644
index 000000000..024cc162f
--- /dev/null
+++ b/app/views/request/select_authority.rhtml
@@ -0,0 +1,49 @@
+<script type="text/javascript" src="/javascripts/ba-throttle-debounce.js"></script>
+<script>
+ $(document).ready(function(){
+ $("#authority_preview").hide();
+
+ // Avoid triggering too often (on each keystroke) by using the debounce jQuery plugin:
+ // http://benalman.com/projects/jquery-throttle-debounce-plugin/
+ $("#query").keypress($.debounce( 300, function() {
+ // Do a type ahead search and display results
+ $("#typeahead_response").load("<%=search_ahead_bodies_url%>?q="+encodeURI(this.value), function() {
+ $("#authority_preview").hide(); // Hide the preview, since results have changed
+
+ // We're using the existing body list: we intercept the clicks on the titles to
+ // display a preview on the right hand side of the screen
+ $("#typeahead_response a").click(function() {
+ $("#authority_preview").load(this.href+" #main_content", function() {
+ $("#authority_preview").show();
+ });
+ return false;
+ });
+ });
+ }));
+ });
+</script>
+
+<% @title = _("Select the authority to write to") %>
+
+ <h1 style="clear: left"><%= _('1. Select an authority') %></h1>
+
+ <div>
+ <% form_tag({:controller => "general", :action => "search_redirect"}, {:id => "search_form"}) do %>
+ <p>
+ <p>
+ <%= _('First, type in the <strong>name of the UK public authority</strong> you\'d
+ <br>like information from. <strong>By law, they have to respond</strong>
+ (<a href="{{url}}">why?</a>).', :url=>help_about_url) %>
+ </p>
+ <%= text_field_tag 'query', params[:query], { :size => 30 } %>
+ <%= hidden_field_tag 'bodies', 1 %>
+ <%= submit_tag _('Search') %>
+ </p>
+ <% end %>
+ <div id="typeahead_response">
+ </div>
+ </div>
+
+ <div id="authority_preview">
+ </div>
+ \ No newline at end of file
diff --git a/config/routes.rb b/config/routes.rb
index 7da279002..24af73229 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -35,9 +35,13 @@ ActionController::Routing::Routes.draw do |map|
request.request_list_successful '/list/successful', :action => 'list', :view => 'successful'
request.request_list '/list', :action => 'list'
+ request.select_authority '/select_authority', :action => 'select_authority'
+
request.new_request '/new', :action => 'new'
request.new_request_to_body '/new/:url_name', :action => 'new'
+ request.search_ahead '/request/search_ahead', :action => 'search_typeahead'
+
request.show_request '/request/:url_title.:format', :action => 'show'
request.show_new_request '/request/:url_title/new', :action => 'show'
request.details_request '/details/request/:url_title', :action => 'details'
@@ -52,8 +56,6 @@ ActionController::Routing::Routes.draw do |map|
request.info_request_event '/request_event/:info_request_event_id', :action => 'show_request_event'
request.upload_response "/upload/request/:url_title", :action => 'upload_response'
-
- request.search_ahead '/request_search_ahead', :action => 'search_typeahead'
end
# Use /profile for things to do with the currently signed in user.
@@ -81,6 +83,7 @@ ActionController::Routing::Routes.draw do |map|
end
map.with_options :controller => 'public_body' do |body|
+ body.search_ahead_bodies '/body/search_ahead', :action => 'search_typeahead'
body.list_public_bodies "/body", :action => 'list'
body.list_public_bodies "/body/list/:tag", :action => 'list'
body.list_public_bodies_redirect "/local/:tag", :action => 'list_redirect'
diff --git a/public/stylesheets/main.css b/public/stylesheets/main.css
index 0c669e8ef..b6e7c1b1a 100644
--- a/public/stylesheets/main.css
+++ b/public/stylesheets/main.css
@@ -312,6 +312,7 @@ h1, h2, h3
line-height: 1em;
letter-spacing: 0em;
color: #555;
+ clear: left;
}
h1 { font-size: 1.8em;}
h2 { font-size: 1.4em;}
@@ -927,6 +928,29 @@ a img.attachment_image {
#body_sidebar a { text-decoration: none; }
+/*------------------------------------------------ selecting an authority */
+
+#authority_search_ahead_results
+{
+ width: 26em;
+ float: left;
+}
+
+#authority_preview
+{
+ width: 26em;
+ float: right;
+ background-color: #FFFFE0;
+ padding-left: 1em;
+ padding-right: 1em;
+}
+
+ #authority_preview #stepwise_make_request
+ {
+ margin: 0;
+ }
+
+
/*------------------------------------------------ making a request / sign up / sign in */
#request_advice
diff --git a/spec/controllers/public_body_controller_spec.rb b/spec/controllers/public_body_controller_spec.rb
index d15482e51..f157d4ac4 100644
--- a/spec/controllers/public_body_controller_spec.rb
+++ b/spec/controllers/public_body_controller_spec.rb
@@ -139,6 +139,41 @@ describe PublicBodyController, "when showing JSON version for API" do
end
+describe PublicBodyController, "when doing type ahead searches" do
+ fixtures :info_requests, :info_request_events, :public_bodies, :public_body_translations, :users, :incoming_messages, :raw_emails, :outgoing_messages, :comments
+ it "should return nothing for the empty query string" do
+ get :search_typeahead, :q => ""
+ response.should render_template('public_body/_search_ahead')
+ assigns[:xapian_requests].results.size.should == 0
+ end
+
+ it "should return a body matching the given keyword, but not users with a matching description" do
+ get :search_typeahead, :q => "Geraldine"
+ response.should render_template('public_body/_search_ahead')
+ assigns[:xapian_requests].results.size.should == 1
+ assigns[:xapian_requests].results[0][:model].name.should == public_bodies(:geraldine_public_body).name
+ end
+ it "should return all requests matching any of the given keywords" do
+ get :search_typeahead, :q => "Geraldine Humpadinking"
+ response.should render_template('public_body/_search_ahead')
+ assigns[:xapian_requests].results.size.should == 2
+ assigns[:xapian_requests].results[0][:model].name.should == public_bodies(:humpadink_public_body).name
+ assigns[:xapian_requests].results[1][:model].name.should == public_bodies(:geraldine_public_body).name
+ end
+ it "should return requests matching the given keywords in any of their locales" do
+ get :search_typeahead, :q => "baguette" # part of the spanish notes
+ response.should render_template('public_body/_search_ahead')
+ assigns[:xapian_requests].results.size.should == 1
+ assigns[:xapian_requests].results[0][:model].name.should == public_bodies(:humpadink_public_body).name
+ end
+
+ it "should return partial matches" do
+ get :search_typeahead, :q => "geral" # 'geral' for 'Geraldine'
+ response.should render_template('public_body/_search_ahead')
+ assigns[:xapian_requests].results.size.should == 1
+ assigns[:xapian_requests].results[0][:model].name.should == public_bodies(:geraldine_public_body).name
+ end
+end