Ajax Search Remote True across the site
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&sensor=false&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
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?
@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)
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.
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.
@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 :)
I even just added jquery-turbolinks to see if that might be an issue. No change in behavior. (smashes head) lol