1

I need to be able to use a variable from within a loop, outside of the loop to be used in javascript between script tags. Preferably not with script tags and in a file but script tags to start...

I have this that doesn't work:

<% @line_items.each do |li| %>
<button type="button" onclick="mockupColor<%= "#{li.id}" %>()"></button>
<div id="tshirt-div-<%= "#{li.id}" %>">
#code
<script>
    function mockupColor<%= li.id %>(){
        document.getElementById("tshirt-div-<%= "#{li.id}" %>").style.backgroundColor = '#000000';
    }, false);
</script>
<% end %>

Error: mockupColor1 is not defined

This does work:

<% @line_items.each do |li| %>
<button type="button" onclick="mockupColor"></button>
<div id="tshirt-div">
#code
<% end %>
<script>
    function mockupColor(){
        document.getElementById("tshirt-div").style.backgroundColor = '#000000';
    }, false);
</script>

The issue is I need to be able to call for the li.id because once i figure this function issue out, the colors will change depending on the li.id.

Is there a way to somehow match up the li.id from the loop in a script tag outside of the loop?

I don't see why this won't work because I have definitely used javascript within loops before and worked out fine. I used similar code in a fields_for loop in an app and using functions this way worked out perfectly fine...For whatever reason, not this time. Or is there something I am missing and not doing right?

HTML: (inside loop)

<button type="button" class="btn btn-info" data-toggle="modal" data-color="796" data-target="#exampleModal2-796" id="#exampleModal2-796"  onclick="mockupColor()">

<script>
function mockupColor() {
   document.getElementById("tshirt-div-796").style.backgroundColor = '#000000';
};
</script>
3
  • What's the generated html/javascript code? Commented Nov 1, 2019 at 3:35
  • Added the html code for what isn't working. Even removing the ID from the loop, it will not work inside the loop Commented Nov 1, 2019 at 3:50
  • I suggest checking out the Working with JavaScript in Rails guide which uses a similar example. Commented Nov 1, 2019 at 11:27

2 Answers 2

1

While you could fix it by adding the proper parentheses and delimiters around the call to mockColor -- instead, rather than using inline handlers (which are widely considered to be pretty poor practice), consider adding a data attribute instead, and then using event delegation to watch for clicks of a button inside the container:

<button type="button" data-color="<%= "{li.id}" %>"></button>
<div>

and

container.addEventListener('click', ({ target }) => {
  if (!target.matches('button')) {
    return;
  }
  target.nextElementSibling.style.backgroundColor = '#' + target.dataset.color;
});

where container is the container around the buttons and divs.

Note that with the use of nextElementSibling, there's no need to give the <div>s ids anymore. (numeric-indexed IDs are best avoided anyway)

Sign up to request clarification or add additional context in comments.

2 Comments

And this goes inside the loop or outside?
The HTML part needs to be part of the loop for the li.id to be defined, of course - the Javascript should be outside (like in a single standalone <script> tag, which runs once)
0
<% @line_items.each do |li| %>
   <button type="button" onclick="mockupColor(<%= "#{li.id}" %>)"></button>
   <div id="tshirt-div-<%= "#{li.id}" %>">#code</div>   
<% end %>
<script>
    function mockupColor(id){
        document.getElementById("tshirt-div-"+id).style.backgroundColor = '#000000';
    );
</script>

You do not need to loop java script function. The function should just accept the JavaScript variable and process as the java script.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.