0

I'm having trouble with creating multiple buttons and matching event listeners in the CoffeeScript part of my ActionCable channel. I'm aware of the different concatenation methods for single quoted text (Literal Strings) and double quoted text (Strings):

  • "#{first_name} McFly" for double quotes
  • first_name + ' McFly' for single quotes

Right?

So I'm a bit confused why this doesn't seem to work:

    answer_text = "answer_button_"
    counter = 0
    for i in data.answers
      answerHtml.push "<button type='button' id=answer_text+counter >#{i.title}</button>"
      $('#'+answer_text+counter).on 'click', (e) -> App.answer_data.send_data()
      counter = counter+1

I've been stuck on this part for too long already, so I'd be really happy if anyone could give me a nudge in the right direction :)

megahra
  • 295
  • 2
  • 19

1 Answers1

0

Ok, so the problem was with the first part of the on click handler - the expression in the braces needed to be enclosed in single quotes. For example:

$('#answer_button_0').on 'click', (e) -> App.answer_data.send_data()

But to be able to concatenate single quotes onto the front and back of my String without turning it into a Literal String I had to escape the single quotes by using $.parseHTML("\'") .

So what finally worked for me was this: [EDIT: turns out this was not the solution, see below]

$($.parseHTML("\'" + '#' + answer_text + counter + "\'")).on 'click', (e) -> App.answer_data.send_data()

EDIT: Managed to fix the event listener and the buttons (thanks @mu!):

answer_text = "answer_button_"
counter = 0
for answer in data.answers
  answerHtml.push "<button type='button' id=#{answer_text+counter} >#{answer.title}</button>"
  counter = counter+1

To fix the event listener I had to make a seperate loop later in the code (after the buttons were appended to the page):

counter = 0
for id in data.answers.map (answer) -> answer.id
  console.log "[AC] answer id: #{i.id}"  #This prints 4 different ids, like it should!
  $('#answer_button_'+counter).on 'click', (e) -> App.answer_data.send_data(id)
  counter = counter+1

Unfortunately, now that the buttons and the event listeners work I have the problem, that the id property that I pass on with the event listeners created in the new loop (at send_data(id)) is always the same - independent from which button I press. I have no idea why... :/

EDIT 2: As @mu suggested I added the do keyword and now it works:

counter = 0
for id in data.answers.map (answer) -> answer.id
  do (id) ->
    $('#answer_button_'+counter).on 'click', (e) -> App.answer_data.send_data(id)
    counter = counter+1

Thank you! :)

megahra
  • 295
  • 2
  • 19
  • Are you sure? `$('#'+answer_text+counter)` should be fine and equivalent to `$("##{answer_text}#{counter}")`. The `id=answer_text+counter` bit inside the string when you're building your ` – mu is too short Sep 14 '17 at 20:22
  • You are right @mu. `$('#answer_button_'+counter).on 'click', (e) -> App.answer_data.send_data()` was the correct way to concatenate - I was thinking overly complicated. And you're right about the other two parts as well: I changed it to `answerHtml.push ""` and I made a second loop to set the event listeners after the buttons were actually appended to the page. Unfortunately I'm facing a different problem now - I've updated my question. – megahra Sep 14 '17 at 23:25
  • You want a `do` loop, see [this answer](https://stackoverflow.com/a/18047974/479863), the bottom of [this section of the docs](http://coffeescript.org/#loops), and [these search results](https://stackoverflow.com/search?q=user%3A479863+%5Bcoffeescript%5D+CoffeeScript+provides+the). – mu is too short Sep 15 '17 at 00:02
  • Yes, that fixed it! Thank you so much @mu :) I learned something new! – megahra Sep 15 '17 at 09:09