If a search only finds one result then jump straight to it instead of
authorTom Hughes <tom@compton.nu>
Fri, 24 Aug 2007 17:38:36 +0000 (17:38 +0000)
committerTom Hughes <tom@compton.nu>
Fri, 24 Aug 2007 17:38:36 +0000 (17:38 +0000)
opening a list of results.

app/controllers/geocoder_controller.rb
app/views/geocoder/_results.rhtml [moved from app/views/geocoder/search.rhtml with 93% similarity]
app/views/site/_search.rhtml
public/stylesheets/site.css

index 69c35e0e3c23e2fc36ba254946d69bb2dbb79f8d..f557668b69e812628e72f4eb12b44f023ea235da 100644 (file)
@@ -4,18 +4,30 @@ class GeocoderController < ApplicationController
   require 'rexml/document'
 
   def search
-    @query = params[:query]
-    @results = Array.new
-
-    if @query.match(/^\d{5}(-\d{4})?$/)
-      @results.push search_us_postcode(@query)
-    elsif @query.match(/(GIR 0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]|[A-HK-Y][0-9]([0-9]|[ABEHMNPRV-Y]))|[0-9][A-HJKS-UW])\s*[0-9][ABD-HJLNP-UW-Z]{2})/i)
-      @results.push search_uk_postcode(@query)
-    elsif @query.match(/[A-Z]\d[A-Z]\s*\d[A-Z]\d/i)
-      @results.push search_ca_postcode(@query)
+    query = params[:query]
+    results = Array.new
+
+    if query.match(/^\d{5}(-\d{4})?$/)
+      results.push search_us_postcode(query)
+    elsif query.match(/(GIR 0AA|[A-PR-UWYZ]([0-9]{1,2}|([A-HK-Y][0-9]|[A-HK-Y][0-9]([0-9]|[ABEHMNPRV-Y]))|[0-9][A-HJKS-UW])\s*[0-9][ABD-HJLNP-UW-Z]{2})/i)
+      results.push search_uk_postcode(query)
+    elsif query.match(/[A-Z]\d[A-Z]\s*\d[A-Z]\d/i)
+      results.push search_ca_postcode(query)
     else
-      @results.push search_osm_namefinder(@query)
-      @results.push search_geonames(@query)
+      results.push search_osm_namefinder(query)
+      results.push search_geonames(query)
+    end
+
+    results_count = count_results(results)
+
+    render :update do |page|
+      if results_count == 1
+        position = results.collect { |s| s[:results] }.compact.flatten[0]
+        page.call "setPosition", position[:lat], position[:lon], position[:zoom]
+      else
+        page.replace_html :search_results_content, :partial => 'results', :object => results
+        page.call "openSearchResults"
+      end
     end
   end
 
@@ -162,4 +174,14 @@ private
     return "north-west" if bearing >= 292.5 and bearing < 337.5
     return "west"
   end
+
+  def count_results(results)
+    count = 0
+
+    results.each do |source|
+      count += source[:results].length if source[:results]
+    end
+
+    return count
+  end
 end
similarity index 93%
rename from app/views/geocoder/search.rhtml
rename to app/views/geocoder/_results.rhtml
index 7ffde3194b8117a8557ed3a82d100ff700352019..477f2a0bcb4f56a7a87a44ecefc4525d68895f5e 100644 (file)
@@ -1,4 +1,4 @@
-<% @results.each do |source| %>
+<% results.each do |source| %>
 <p class="search_results_heading">Results from <%= link_to source[:source], source[:url] %></p>
 <% if source[:results] %>
 <% if source[:results].empty? %>
index a9a3385c37d2fdf3b0a9333e8d57aaf8352cdcd5..aa9294236e10e65a1b298127363ae1aad26c15f3 100644 (file)
 
 <script type="text/javascript">
 <!--
+  function startSearch() {
+    $("search_field").style.display = "none";
+    $("search_active").style.display = "inline";
+  }
+
+  function endSearch() {
+    $("search_field").style.display = "inline";
+    $("search_active").style.display = "none";
+  }
+
   function openSearchResults() {
     $("search_results").style.display = "block";
-    $("search_results_content").innerHTML = "<p class='search_results_entry'>Searching...</p>";
     <%= onopen %>
   }
 
@@ -23,8 +32,8 @@
   }
 
   <% if params[:query] %>
-  <%= remote_function(:update => :search_results_content, 
-                      :loading => "openSearchResults()",
+  <%= remote_function(:loading => "startSearch()",
+                      :complete => "endSearch()",
                       :url => { :controller => :geocoder, :action => :search, :query => params[:query] }) %>
   <% end %>
 // -->
 <% content_for "optionals" do %>
   <div class="optionalbox">
     <span class="oboxheader">Search</span>
-    <% form_remote_tag(:update => :search_results_content, 
-                       :loading => "openSearchResults()",
+    <div class="search_form">
+    <span id="search_field">
+    <% form_remote_tag(:loading => "startSearch()",
+                       :complete => "endSearch()",
                        :url => { :controller => :geocoder, :action => :search }) do %>
       <%= text_field_tag :query, params[:query] %>
     <% end %>
+    </span>
+    <p id="search_active">Searching...</p>
+    </div>
     <p class="search_help">
       examples: 'Alkmaar', 'Regent Street, Cambridge', 'CB2 5AQ',
       or 'post offices near L√ľnen'
index feb32318f962ac8da5172883b536f8a1e10dcff0..4d02c1c72dd5101b0e3ccf4296805ceb8a5b543c 100644 (file)
@@ -351,6 +351,16 @@ hides rule from IE5-Mac \*/
   width: 100%;
 }
 
+.search_form {
+  height: 16px;
+  padding-bottom: 2px;
+}
+
+#search_active {
+  display: none;
+  color: red;
+}
+
 .rsssmall {
   position: relative;
   top: 4px;