Technical Background
data-no-turbolink
Please note, just adding the attribute data-no-turbolink="true"
to a link does suppress turbolinks for that link. Clicking on that link does load the entire page rather than replacing the content with turbolinks.
But there are several ways to use turbolinks with gmaps4rails without suppressing turbolinks.
Turbolinks Callbacks
The key to getting something to work with turbolinks, is to use the provided callbacks. In this case, one has to tell gmaps4rails to perform the map loading when turbolinks has loaded a new page.
In general, one can use $(document).on('page:load', function ... )
as, for example, shown in Railscast #390.
JavaScript's Same-Origin Policy
The google api script included by the gmap4rails gem requests another script from a google static server. But if the api is dynamically included by turbolinks, the single-origin policy prevents the request to the google static server.
The single-origin policy itself is a useful thing. Although there are a couple of ways to circumvent it, this appears not to be a natural thing to do. Instead, the "right way" to do it is to "prove" that the web page really wants to execute the remote script (the google api) and that the remote script is not requested by a malicious script. This is done by including the script tag that requests the google api directly in the html tree.
Including the google api script tag directly in the html tree is only possible on the first request, when using turbolinks, since all later changes are dynamically injected into the tree by turbolinks. That means that, when using turbolinks, the google api has to be included even on pages that do not show a map.
Solution 1 (Recommended): Use fork for gmaps4rails
I've made a pull request, hopefully adding Turbolinks support for gmaps4rails.
Demo
If you'd like, have a look at this demo first that shows the use of gmaps4rails with turbolinks:
How to use this in your project
You can try this out and check if it's working for your project by adding the fork to your Gemfile:
# Gemfile
# ...
gem 'turbolinks'
gem 'gmaps4rails', '~> 2.0.1', git: 'https://github.com/fiedl/Google-Maps-for-Rails.git'
# ...
Furthermore, you need to modify your layout file to include the api in the html head:
<!-- app/views/layouts/application.html.erb -->
<html>
<head>
...
<%= stylesheet_link_tag "application", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= gmaps4rails_api_script_tags # <-- THIS IS NEW ----------------- %>
<%= csrf_meta_tags %>
</head>
<body>
...
<%= yield %>
<%= yield :scripts %>
</body>
</html>
If, for some reason, you do not want to use this fork, I see two alternatives to use gmaps4rails together with turbolinks:
Solution 2: Do it manually
Basically doing the same thing as the fork (Solution 1), one can manually add the api scripts to the head in the layout file. Then, when loading a page via turbolinks, one can configure and activate the map using javascript.
This is demonstrated generally for the use with UJS in the gmaps4rails wiki:
https://github.com/apneadiving/Google-Maps-for-Rails/wiki/Using-with-UJS
Solution 3: Include the api statics manually
If you do not want to add the api scripts globally, there is a way to get around the single-origin policy and load the api dynamically.
I have prepared a gist for that: https://gist.github.com/fiedl/6573175
You would have to add a javascript file that does two things:
- Load the google maps api itself.
- Load the statics file, which is loaded by the api.
You can find out the url to the statics file by opening the api script in a browser and copying the url from the getScript
call at the bottom.
But: Doing this fixes the static api request to your locale, which is probably not a good thing if your app is used internationally.