3

I have an odd situation, but here it is:

# a HAML file
:javascript
  #{ if session[:view].blank?
        "$.ajax({
            url: 'url_for params.merge(:action => 'index')',
            dataType: 'script'})"
    else
        "$.ajax({
            url: 'url_for companies_url',
            dataType: 'script'})"
    end }

So this is basically nesting javascript inside ruby, inside javascript, inside HAML. It doesn't work because I've got improper nesting of quotes.

  1. I imagine there's a better way to do this. Any thoughts?
  2. The ajax happening above renders some partials into the current view and changes the session variable. How can I update this javascript so it behaves correctly given the new session[:view]?
sscirrus
  • 55,407
  • 41
  • 135
  • 228

3 Answers3

3

Use ERB and a helper method. It's a lot cleaner:

# foo_helper.rb (or whichever helper is applicable for this view)
module FooHelper
  def url_for_ajax_call
    if session[:view].blank?
      url_for(params.merge(:action => 'index'))
    else
      # url_for(companies_url) is redundant
      companies_url
    end
  end
end

# view.js.erb
$.ajax({ url: <%= url_for_ajax_call %>, dataType: 'script' })
dnch
  • 9,565
  • 2
  • 38
  • 41
  • this is awesome, it works very nicely with my nesting problem. Do you know how I can deal with #2, namely how to re-evaluate this javascript/erb upon the ajax response? At this point of course, session[:view] has been changed by the controller. – sscirrus Jun 27 '11 at 09:49
2

In my opinion, you don't need to switch to ERB but the helper method is good. I'd put the URL into a tag that the page renders. Usually I do this in an anchor tag's data-href attribute for unobtrusive javascript. For example:

= link_to "Link to index view", url_for(params.merge(:action => "index")), { 'data-href' => url_for_ajax_call }

Then:

$.ajax({ url: $(element).data('href'), dataType: 'script' })

Then all your partial needs to do is re-render the link_to which will regenerate the correct url_for_ajax_call.

Obviously, this way is a little more work as you'll need to add a click event handler to the link and you'll need to stop the actual clicking of the link from occurring (http://api.jquery.com/event.preventDefault/). But there's no need to switch to ERB for a single file, you can handle users that turn off javascript, and it'll solve your second question.

pcg79
  • 1,283
  • 9
  • 20
1

Best way I could find to do this kind of things with haml is to write javascript as text inside a %script bloc. So your code would become:

# a HAML file
%script
  -if session[:view].blank?
    $.ajax({url: 'url_for params.merge(:action => 'index')',dataType: 'script'})
      -else
    $.ajax({url: 'url_for companies_url', dataType: 'script'})

as a bonus you can even do ruby interpolation now:

# a HAML file
%script
  alert("#{ruby_variable}")
adrienbourgeois
  • 423
  • 1
  • 3
  • 8