At first, all the javascript bounded are running pretty well.
However, from the moment I navigate to another page, any event is being fired multiple times. If I refresh the page, everything is back to normal.
In the jquery.turbolink docs, there is an alert about binding the document events inside a $(function()) block. However, seems like the coffescript works like this by default. So, what should I do?
This is my environment:
Gemfile:
gem 'turbolinks'
gem 'jquery-turbolinks'
application.js
//= require jquery
//= require jquery.turbolinks
//..app js
//= require turbolinks
application.html.erb
<html>
<head>
<meta charset="utf-8">
<title><%= t 'brand' %> </title>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %>
<%= javascript_include_tag 'application', 'data-turbolinks-track' => true %>
<%= yield :head %>
<%= csrf_meta_tags %>
<meta name="description" content="<%= yield :page_description %>">
<meta name="keywords" content="<%= yield :page_keywords %>">
</head>
controller.js.coffee
$(document).ready ->
$(document).on 'click', '.addition .label i', (e) ->
console.log ".addition .label i 'click' fired!"
The thing is, apparently the javascript file generated by coffeescript IS inside a block by default. Check it out:
controller.js (generated by coffeescript)
function() {
$(document).ready(function() {
$(document).on('click', '.addition .label i', function(e) {
console.log(".addition .label i 'click' fired!");
});
...
So, what should I do to use coffeescript + JQuery Turbolinks properly? Should I make a different configuration?
Cheers.
The problem is in controller.js.coffee.
You wrote this:
$(document).ready ->
$(document).on 'click', '.addition .label i', (e) ->
console.log ".addition .label i 'click' fired!"
But since you're using jQuery Turbolinks, you need to move the event handlers outside the $(document).ready function:
$(document).ready ->
# Other code can go here, but not binding event handlers
$(document).on 'click', '.addition .label i', (e) ->
console.log ".addition .label i 'click' fired!"
Take a look at the jQuery Turbolinks README. It mentions this problem and solution. (Search the readme for "Events firing twice or more.")
Well, it turned out that I've changed the approach completely.
Now, I've got exactly the same environment, but I'm using classes to represent the javascript for each controller. Here is one example:
foo.js.coffee:
window.App or= {}
class App.Foo
constructor: ->
@$foo_container = $('.foo')
@bind()
bind: ->
console.log 'App.Foo.bind has been fired!'
@$foo_container.on 'click', '.label i', @foo_clicked
foo_clicked: (e) =>
console.log 'App.Foo.foo_clicked has been fired!'
alert '.label i has been clicked!'
create_foo = ->
window.app.foo = new App.Foo()
console.log 'App.Foo has been created!'
$(document).ready create_foo
Now, it works like a charm. :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With