I have a button in my views in test.html.erb
as follows
<button id="Todo_full" onclick="showFullscreen(this);">Full size</button>
and its javascript is as follows:
function showFullscreen(event)
{
var elem = document.getElementById('card_' + event.id);
if (elem.requestFullscreen) {
return elem.requestFullscreen();
}
else if (elem.mozRequestFullScreen)
{
/* Firefox */
return elem.mozRequestFullScreen();
}
}
When I keep the javascript code at the below of the test.html.erb
file it works fine.
And when I convert this code into coffeescript through http://js2.coffee/ and keep the code in app/assets/javascript/test.coffee
which is as follows:
showFullscreen = (event) ->
elem = document.getElementById('card_' + event.id)
if elem.requestFullscreen
return elem.requestFullscreen()
else if elem.mozRequestFullScreen
### Firefox ###
return elem.mozRequestFullScreen()
return
It shows an error in console
Uncaught ReferenceError: showFullscreen is not defined
at HTMLButtonElement.onclick ((index):384)
Even when I use window.onload = ->
at the top of coffeescript's code I get the same error in console.
Thank you
The issue you're running into is the different scoping between JS and CoffeeScript. To get your code working, you need to scope your function globally on window
or the CoffeeScript shorthand @
.
From the CoffeeScript docs:
If you’d like to create top-level variables for other scripts to use, attach them as properties on
window
.
Which for your function would look like:
# Using window
window.showFullscreen = (event) ->
elem = document.getElementById('card_' + event.id)
...
# Or using @
@showFullscreen = (event) ->
elem = document.getElementById('card_' + event.id)
...
The CoffeeScript @
is shorthand for this
in JavaScript. So, in your example, because you're defining the function at the top level window scope window == @
. Keep in mind that within your functions the scope will be different and window != @
, and instead @
will be scoped to whatever this
is inside of your function. This blog post has a nice explanation:
Speaking of
this
, CoffeeScript has a shortcut for it, the@
symbol. It's easy to write this off as meaningless syntactical sugar, but it is useful. First, constructor parameters prefixed with@
are converted into properties:# CoffeeScript class User constructor: (@id) ->
// JavaScript function User(id) { this.id = id; }
Beyond this though, it's a nice way to define class method:
# CoffeeScript class User constructor: (@id) -> @findById: (id) => ...
// JavaScript function User(id) { this.id = id; } User.findById = function() {};
Neither
@
nor the fat arrow=>
mean that you don't have to worry about the current meaning ofthis
(or its alias@
). They aren't silver bullets, which isn't to say that they don't add value.