Ask A Question

Notifications

You’re not receiving notifications from this thread.

Ajax Search Remote True across the site

shakycode asked in General

I'm building an app in Rails 4.2.x and I'm using Ransack + Geocoder for my searches. Originally I setup a Remote: True search using Ajax in my index action and I can search no problem with the response of JS in the controller from the index view like so:

index.html.erb

<div id="mapdisplay">
    <%= render 'map' %>
</div>
<div id="results">
    <%= render 'results' %>
</div>

index.js.erb

$("#mapdisplay").html("<%= escape_javascript render("map") %>");
$("#results").html("<%= escape_javascript render("results") %>");

_map.html.erb

<script src="//maps.google.com/maps/api/js?v=3.13&amp;sensor=false&amp;libraries=geometry" type="text/javascript"></script>
<script src='//google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.14/src/markerclusterer_packed.js' type='text/javascript'></script>
<h4>Resources</h4>
<div class="form-group">
  <div class="pull-right">
  <%= search_form_for(@search, :id => "resource_search", remote: true) do |f| %>
    <%= text_field_tag :location, params[:location], placeholder: "Houston, TX", class: "input-sm form-control" %>
    <%= f.submit "Find", class:'btn btn-sm btn-info' %>
<% end %>
  </div>
</div>
<div class="pull-right">
    <%= link_to "Add", new_resource_path, class: 'btn btn-info btn-medium' %>
</div>
<div style='width: 800px;'>
  <div id="map" style='width: 800px; height: 400px;'></div>
</div>
<script>
handler = Gmaps.build('Google');
handler.buildMap({
    provider: {
      disableDefaultUI: true
      // pass in other Google Maps API options here
    },
    internal: {
      id: 'map'
    }
  },
  function(){
    markers = handler.addMarkers(<%=raw @hash.to_json %>);
    handler.bounds.extendWith(markers);
    handler.fitMapToBounds();
  }
);
</script>

_results.html.erb


  <table class="table table-striped">
    <thead>
      <tr>
        <th>Name</th>
        <th>Address</th>
        <th>Notes</th>
      </tr>
    </thead>
    <tbody>
  <% @resources.each do |r| %>
      <tr>
        <td><%= link_to "#{r.name}", r %></td><td><%= r.address %></td><td><%= r.notes %></td>
      </tr>
  <% end %>
    </tbody>
  </table>

This works fine and dandy in the index view. But I see a use case for moving the search to the application.html.erb layout file. So I did that by doing this.

application.html.erb

<%= search_form_for(@search, url:"/resources", :method => :get, remote: true) do |f| %>
              <%= text_field_tag :location, params[:location], placeholder: "Houston, TX", class: "input-sm form-control" %>
              <%= f.submit "Find", class:'btn btn-sm btn-info' %>
            <% end %>

application_controller.rb

before_action :build_search
private
  def build_search
    if params[:location].present?
        @search = Resource.near(params[:location], 100).search(params[:q])
      else
            @search = Resource.search(params[:q])
      end
  end

So i can search from any view in the app as long as there's an @resources instantiated in the respective controller action and a partial rendered. So I have this setup in my new and show actions respectively.

My main question would be, how to get the ajax search to work site-wide to where it doesn't do a page load and change the URL? This works in the index view if I keep the search box inside of the index view, but when I abstract it out to the application layout file it does a full html request, pageload, and changes the URL.

I'm sure I'm missing something simple so any advice would be greatly appreciated.

Cheers,
ShakyCode

Reply

It shouldn't change anything if you move this to application.html.erb and keep remote: true. Have you inspected your JS to make sure there are no errors causing it to fail to do a remote post?

Reply

@chris

Absolutely, I've already inspected the console/logs and I'm not throwing out any errors. Here's the same params/action being passed. 1st from the index view as js, then from the application.html.erb which is forced as html. This is from development.log

Started GET "/resources?utf8=%E2%9C%93&location=houston&commit=Find" for 127.0.0.1 at 2015-08-09 09:34:01 -0500
Processing by ResourcesController#index as JS
  Parameters: {"utf8"=>"✓", "location"=>"houston", "commit"=>"Find"}
  Resource Load (2.1ms)  SELECT DISTINCT resources.*, 3958.755864232 * 2 * ASIN(SQRT(POWER(SIN((29.7604267 - resources.latitude) * PI() / 180 / 2), 2) + COS(29.7604267 * PI() / 180) * COS(resources.latitude * PI() / 180) * POWER(SIN((-95.3698028 - resources.longitude) * PI() / 180 / 2), 2))) AS distance, MOD(CAST((ATAN2( ((resources.longitude - -95.3698028) / 57.2957795), ((resources.latitude - 29.7604267) / 57.2957795)) * 57.2957795) + 360 AS decimal), 360) AS bearing FROM "resources" WHERE (resources.latitude BETWEEN 28.313108868891522 AND 31.207744531108478 AND resources.longitude BETWEEN -97.03701125791528 AND -93.70259434208472 AND (3958.755864232 * 2 * ASIN(SQRT(POWER(SIN((29.7604267 - resources.latitude) * PI() / 180 / 2), 2) + COS(29.7604267 * PI() / 180) * COS(resources.latitude * PI() / 180) * POWER(SIN((-95.3698028 - resources.longitude) * PI() / 180 / 2), 2)))) BETWEEN 0.0 AND 100)  ORDER BY distance ASC
  Rendered resources/_search.html.erb (0.6ms)
  Rendered resources/_map.html.erb (1.9ms)
  Rendered resources/_results.html.erb (0.6ms)
  Rendered resources/index.js.erb (5.4ms)
Completed 200 OK in 582ms (Views: 25.0ms | ActiveRecord: 2.1ms)
Started GET "/resources?utf8=%E2%9C%93&location=houston&commit=Find" for 127.0.0.1 at 2015-08-09 09:34:24 -0500
Processing by ResourcesController#index as HTML
  Parameters: {"utf8"=>"✓", "location"=>"houston", "commit"=>"Find"}
  Resource Load (5.6ms)  SELECT DISTINCT resources.*, 3958.755864232 * 2 * ASIN(SQRT(POWER(SIN((29.7604267 - resources.latitude) * PI() / 180 / 2), 2) + COS(29.7604267 * PI() / 180) * COS(resources.latitude * PI() / 180) * POWER(SIN((-95.3698028 - resources.longitude) * PI() / 180 / 2), 2))) AS distance, MOD(CAST((ATAN2( ((resources.longitude - -95.3698028) / 57.2957795), ((resources.latitude - 29.7604267) / 57.2957795)) * 57.2957795) + 360 AS decimal), 360) AS bearing FROM "resources" WHERE (resources.latitude BETWEEN 28.313108868891522 AND 31.207744531108478 AND resources.longitude BETWEEN -97.03701125791528 AND -93.70259434208472 AND (3958.755864232 * 2 * ASIN(SQRT(POWER(SIN((29.7604267 - resources.latitude) * PI() / 180 / 2), 2) + COS(29.7604267 * PI() / 180) * COS(resources.latitude * PI() / 180) * POWER(SIN((-95.3698028 - resources.longitude) * PI() / 180 / 2), 2)))) BETWEEN 0.0 AND 100)  ORDER BY distance ASC
  Rendered resources/_search.html.erb (1.0ms)
  Rendered resources/_map.html.erb (3.5ms)
  Rendered resources/_results.html.erb (2.3ms)
  Rendered resources/index.html.erb within layouts/application (19.4ms)
Reply

There has to be some JS breaking it if it's submitting as HTML though. Maybe not giving you errors, but there's an issue with your jquery_ujs firing properly it seems. That's the only thing that can trigger that query.

Reply

I can't think of what might be causing it, but you'll probably want to comment out your JS requires in application.js except for jquery and jquery_ujs to see if the other files are maybe messing with it.

Reply

@chris

I commented out turbolinks, and underscore which is the only JS stuff that's being required. Still the same problem. Index view will fire JS/Ajax, application layout will fire HTML. It's a mystery :)

Reply

I even just added jquery-turbolinks to see if that might be an issue. No change in behavior. (smashes head) lol

Reply

Way late on a response here. I figured out the problem why it was forcing a HTML response on hitting search box. I had the search_form_for wrapped in a <form> tag in the application.html.erb. Removing that allowed a JS/Ajax action to fire properly.

Reply
Join the discussion
Create an account Log in

Want to stay up-to-date with Ruby on Rails?

Join 82,464+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.