Jason Carty
Jason Carty

Reputation: 1247

Rails javascript only works after reload

The problem is exactly what the heading says. The javaScript is in the asset pipeline i.e assets/javascripts/myfile.js.coffee In the application.js I have:

//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require jquery.ui.all
//= requier twitter/bootstrap
//= require jasny-bootstrap
//= require_tree .

This is the coffeescript

$(document).ready ->
  $("#close").click ->
    $(this).parent().parent().slideUp("slow")




  $( "#datepicker" ).datepicker
    dateFormat : "yy-mm-dd"


  player_count = $("#player option").length


  $('#btn-add').click ->
    $('#users option:selected').each ->
      if player_count >= 8
        $('#select-reserve').append("<option      value='"+$(this).val()+"'>"+$(this).text()+"</option>")
        $(this).remove()    
      else
        $('#player').append("<option value='"+$(this).val()+"'>"+$(this).text()+"</option>")
        $(this).remove()
        player_count++


  $('#btn-remove').click ->
    $('#player option:selected').each ->
      $('#users').append("<option value='"+$(this).val()+"'>"+$(this).text()+"</option>")
      $(this).remove()
      player_count--


  $('#btn-remove-reserve').click ->
    $('#select-reserve option:selected').each ->
      $('#users').append("<option value='"+$(this).val()+"'>"+$(this).text()+"</option>")
      $(this).remove()


  $("#submit").click ->
   $("select option").prop("selected", "selected")

I can see in the source code on the browser that the javaScript has been loaded, but it only works after I reload the page.

Upvotes: 58

Views: 33942

Answers (8)

StanisLove Sid
StanisLove Sid

Reputation: 322

If you work with JQuery plugins such as Clock Time Picker, firstly use jQuery document ready function, which causes your script to wait until the entire page is loaded before attempting to run and then you can use turbolinks:load event.

JQuery(function($) {
  $(document).on('turbolinks:load', function() {
    $('.time').clockTimePicker();
  });
});

It is good to be situated in your app/assets/javascripts/... js file

Upvotes: 2

6ft Dan
6ft Dan

Reputation: 2445

I'm trying Rails 5.2 and found that 'turbolinks:load' wasn't getting loaded the first time a page loads. This is what I needed to do in my CoffeeScript file.

document.addEventListener('turbolinks:load', ->
  # ... CoffeeScript code here
)

if !Turbolinks?
  location.reload

Turbolinks.dispatch("turbolinks:load")

Upvotes: 0

Brad
Brad

Reputation: 8698

Rails 5 Use the jquery.turbolinks gem and using

$( document ).on('turbolinks:load', function() {
  // your code
}

Upvotes: 7

M. Luisa Carri&#243;n
M. Luisa Carri&#243;n

Reputation: 1281

For turbolinks 5.0 you must use the turbolinks:load event, which is called the first time on page load and every time on a turbolink visit. More info: https://github.com/turbolinks/turbolinks#running-javascript-when-a-page-loads

CoffeeScript code:

$(document).on 'turbolinks:load', ->
  my_func()

JavaScript code:

document.addEventListener("turbolinks:load", function() {
  my_func();
})

Upvotes: 75

Peak Sornpaisarn
Peak Sornpaisarn

Reputation: 975

You can have your jquery.turbolink place at the right position like this

 //= require jquery 
 //= require jquery.turbolinks 
 //= require jquery_ujs 
 //= require bootstrap-sprockets 
 //= require turbolinks

And in the Gemfile you can install the jquery-turbolinks gem

gem 'jquery-turbolinks'

Upvotes: 9

Songhua Hu
Songhua Hu

Reputation: 301

You can install the jquery.turbolinks gem to solve the problem without changing your Javascript.

Upvotes: 19

Jason Carty
Jason Carty

Reputation: 1247

This was a turbolinks problem. Thanks to @zwippie for leading me in the right direction! The solution was to wrap my coffeescript in this:

ready = ->
// functions

$(document).ready(ready)
$(document).on('page:load', ready)

Upvotes: 29

zwippie
zwippie

Reputation: 15525

I guess this is a turbolinks issue.

Either remove turbolinks from your project or modify your script to something like:

$(function() {
  initPage();
});
$(window).bind('page:change', function() {
  initPage();
});
function initPage() {
  // Page ready code...
}

As mentioned here.

Upvotes: 25

Related Questions