Inside of HAML, can we have a loop inside the :javascript region?
This will work:
- 10.upto(20) do |i|
:javascript
document.getElementById('aDiv').innerHTML += '#{i}';
and this will not:
:javascript
- 10.upto(20) do |i|
document.getElementById('aDiv').innerHTML += '#{i}';
can the code above also be made to work as well?
this one works
%script
- 10.upto(20) do |i|
document.getElementById('aDiv').innerHTML += '#{i}';
%html
%head
:javascript
var foo = [];
#{
limit = rand(4)+3
array = (0..limit).to_a
array.map{ |i| "foo[#{i}] = #{rand(12)};" }.join ' '
}
console.log(foo.length);
%body
Running the above code gives this output:
<html>
<head>
<script type='text/javascript'>
//<![CDATA[
var foo = [];
foo[0] = 2; foo[1] = 0; foo[2] = 11; foo[3] = 8; foo[4] = 0; foo[5] = 1;
//]]>
</script>
<body></body>
</head>
</html>
As you can see, the big #{...}
block (which may span multiple lines) runs arbitrary Ruby code. The result of the last expression (in this case the map{...}.join
) is converted to a string and placed in the output.
Edit for Radek: If you want to declare a variable inside you Haml template, inside your JavaScript filter (which seems like an odd desire), then you need to be sure that the result of the block to_s
doesn't produce unwanted output:
This Haml...
%p
:javascript
var foo = 12;
#{x = 42}
var bar = #{x};
...produces this HTML:
<p>
<script type='text/javascript'>
//<![CDATA[
var foo = 12;
42
var bar = 42;
//]]>
</script>
</p>
Whereas this Haml...
%p
:javascript
var foo = 12;
#{x = 42; ""}
var bar = #{x};
...produces this HTML...
<p>
<script type='text/javascript'>
//<![CDATA[
var foo = 12;
var bar = 42;
//]]>
</script>
</p>
But before you do this, ask yourself: why am I creating complex Ruby variables in my view?
Shouldn't this variable have been declared by my controller?
Just wanted to add that the following gets you the type and CDATA, but without the funky behaviour of :javascript (I just had to implement something like this).
%script{ :type => 'text/javascript' }
\//<![CDATA[
- (10..20) do |i|
document.getElementById('aDiv').innerHTML += '#{i}';
\//]]>