Turbolinks 5, Rails 5, not that bad!

I used to remove turbolinks from every rails project I started. Now I leave it in there. The things you need to learn to use turbolinks effectively PALE IN COMPARISON to what you need to do to learn a front end framework like react.

I’ve spent the past year learning React and all the other bullshit that comes with it. I created http://www.decideyournight.com with React which I use regularly to find new resturants… It has a fairly complex form, and DAMN it was a LOT LOT LOT of work. Would have been difficult with turbolinks too.

But when you DON’T need a massively complex interface, TURBOLINKS 5 AIN’T THAT BAD!. Server rendered html + Turbolinks + sprinkled jquery ISN’T THAT BAD. NOT THAT BAD. WAY EASIER THAN LEARNING REACT (React can be simple, but it’s almost impossible not to get roped into redux, jsx, es6, HORRIBLE DOCUMENTATION, ROUTING [HORRIBLE DOCUMENTATION], node.js, NPM, two dev servers). Just know if you venture down the JAVASCRIPT route, you’re in for a disasterous experience.

Github uses turbolinks. Turbolinks has been around the block.

1) Put javascript include tag in the <head></head> so it will only load once.

<!DOCTYPE html>
<html>
    <head>
        <title>Dawg</title>
        <%= javascript_include_tag 'application', 'data-turbolinks-track': 'reload' %>
    </head>

    <body>
        <%= yield %>
    </body>
</html>

2) Writing jquery needs to go in a special document ready tag

<script>
  // GOOD WITH TURBOLINKS
  $(document).on('turbolinks:load', function () {
    console.log("This will run when dom is loaded!");
  });
</script>

Normal JAVASCRIPT you’ll see is

<script>
  // BAD WITH TURBOLINKS
  $(document).on(ready, function () {
    console.log("This will fuck up!");
  });
</script>

3) Disabling Turbolinks from the link tag. Turbolinks 5 uses different method to disable it. This will cause a full page refresh when the link is clicked.

<%= link_to "Foo", new_rabbit_path(@rabbit), data: { turbolinks: false } %>

Since Google Maps gets loaded in the body, it’s important to only load it once. To do that, you can try and figure out how to Jam these answers into your application… http://stackoverflow.com/questions/9228958/how-to-check-if-google-maps-api-is-loaded

OR

1) Add var isMapsApiLoaded = false to bottom of app/assets/javascripts/application.js 2) Then add the following wherever you want the map to load.

<div id="map_canvas_home"></div>
<script>
$(document).on('turbolinks:load', function () {

    // only do this if you find the map_canvas_home, otherwise we don't need no maps
    if (document.getElementById("map_canvas_home") !== null) {

        // check to see if google map is loaded, if so, just init that map! Otherwise, create the script tag
        if (isMapsApiLoaded) {
            initMap();
        } else {
            var script = document.createElement("script");
            script.type = "text/javascript";
            script.src = "http://maps.google.com/maps/api/js?key=[YOUR_API+KEY]&sensor=false&callback=initMap";
            document.body.appendChild(script);
        }
    }
});

function initMap() {
    isMapsApiLoaded = true;
  // load map!
  var locations = <%= raw @properties %>
  var center = {lat: locations[0].lat, lng: locations[0].lng};
  var map = new google.maps.Map(document.getElementById('map_canvas_home'), {
    zoom: 8,
    center: center
  });

  var infowindow = new google.maps.InfoWindow();

  var marker, i;

  for (i = 0; i < locations.length; i++) {
    marker = new google.maps.Marker({
      position: new google.maps.LatLng(locations[i].lat, locations[i].lng),
      map: map
    });
    google.maps.event.addListener(marker, 'click', (function(marker, i) {
      return function() {
        infowindow.setContent("<div class='info-window'>\
            <table class='table table-responsive'>\
            <thead>\
            <tr>\
            <td colspan='2'><h2>Property Details</h2></td>\
            </tr>\
            </thead>\
            <tbody>\
            <tr>\
            <td>Address</td>\
            <td>"+ locations[i].address +"</td>\
            </tr>\
            <tr>\
            <td>Price</td>\
            <td>"+ locations[i].price +"</td>\
            </tr>\
            <tr>\
            <td>Beds</td>\
            <td>"+ locations[i].bedrooms +"</td>\
            </tr>\
            <tr>\
            <td>Baths</td>\
            <td>"+ locations[i].baths +"</td>\
            </tr>\
            <tr>\
            <td>Square Feet</td>\
            <td>"+ locations[i].livingArea +"</td>\
            </tr>\
            </tbody>\
            </table>\
            </div>");
        infowindow.open(map, marker);
      }
    })(marker, i));
  }
}
</script>

Post Content