views:

488

answers:

2

I have a jQuery script that adds a new field to a form, and this field contains dynamic information from an array. The problem is that I can't figure out how to add an array.each to populate the options of the select field within the javascript without breaking the HAML indentation and causing errors.

Here is my best attempt that does not work:

%script(type="text/javascript")  
  $('#mylink').click(function() {  
  $('#mylink').after('<select>  
  - myarray.each do |options|  
     <option value="#{options.id}">#{options.name}</option>  
  </select>);  
  )};

Also tried it with the :javascript filter with no luck.

+2  A: 

Usually, if something is a pain in haml, it means you should refactor the the tricky bit to a helper or partial and call that.

// some_helper.rb
def new_snazzy_select_tag(options = [])
  select_tag 'tag_name_here', options.map { |option| [option.id, option.name] }
end

Also, you should use the :javascript filter to render javascript since it will put it in a script tag for you and allow indentation.

Lastly, you can use #{ruby_expression} anywhere in haml, including :javascript filters, which is very handy when you need to output the result of ruby expressions to places that are not directly contents of html elements.

// some_view.html.haml
:javascript
  $('#mylink').click(function() {  
    $('#mylink').after("#{escape_javascript new_snazzy_select_tag(myarray)}");
  };
Squeegy
I am pretty new to web app development, I never thought about using a helper. I have been keeping my code pretty close to MVC, but always wondered how to get around the loops I needed in views. That should work nicely. Thank you for the answer.
Josh
Helpers are usually partway between the view and controller. They should never change any server side state, and are simply there to *help* out with nasty view logic. Ruby in your views should be as minimal as possible to be clear and maintainable. Helpers help with that.
Squeegy
A: 

Try this, it should work (all i did was remove a single space in the fifth line and add the closing quote on the sixth):

%script(type="text/javascript")
  $('#mylink').click(function() {
  $('#mylink').after('<select>
  - @myarray.each do |options|
    <option value="#{options.id}">#{options.name}</option>
  </select>');
  )};

However, assuming you're running this with a ruby script or framework of sorts, why not just do it outside the template? That would probably be most appropriate. In rails/sinatra and other frameworks, you could use a helper method to do this. If you look at the haml reference, they actually discourage use of - to evaluate ruby.

ehsanul
I typed in the code from memory without a syntax highlighter, looks like I had a couple errors. I can't test at the moment, but I believe this will still fail. I am going to go the helper route, which I had not thought about before. Thank you.
Josh
I had earlier tested the code I put in my answer in a quick sinatra app, and it seemed to work fine (no haml errors). You sure the error isn't elsewhere? Here's the generated output I got, with random option ids and names: http://pastie.org/920686
ehsanul