views:

58

answers:

3

I have this chunk on jQuery and currently its living in my index.html.erb and it works well. I have alot of snippets like this that i want to move out of the views and into some other file or files to clean them up. Here is my snippet

    $("#request_artist").autocomplete({
        source: function(req, add){
            $.getJSON('<%= ajax_path("artistName") %>', req, function(data) {
      var suggestions = data.suggestions;
                add(suggestions);
            });
        },
    });

The problem is that is the getJson call above i use a rails helper to give me the path to the location and when i add this code to application.js it fails because it doesnt know what it is. So my question would be is there a place to put this code and clean up my index.html.erb

+1  A: 

In your index.html.rb:

<script type="text/javascript">
    var artistNameUrl = '<%= ajax_path("artistName") %>';
</script>

And in a separate js file:

$('#request_artist').autocomplete({
    source: function(req, add) {
        $.getJSON(artistNameUrl, req, function(data) {
            var suggestions = data.suggestions;
            add(suggestions);
        });
    }
});
Darin Dimitrov
+1  A: 

@John

Using jQuery and AJAX in your Rails app is a little more involved than you might think. There is a recent blog article that shows you how to setup jQuery and AJAX when using Rails. Basically, you need to do the following:

Tell Rails how to Handle AJAX calls

applications.js

jQuery(document).ready(function($) {
  //Tell Rails that we’re sending a JavaScript request
  $.ajaxSetup({  
     'beforeSend': function (xhr){
     xhr.setRequestHeader("Accept", "text/javascript")}  
  });


  //General helper for forms submitted via ajax
  $("form.remote_for").submit(function (){
    $('input[type=submit]').attr('disabled', 'disabled');
    $.post($(this).attr('action'), $(this).serialize(), null, "script");  
    return false;
  });
});

Then when you create your form, add the remote_for class to the form definition:

<% form_for([@post, @comment], :html => { :class => "remote_for" }) do |f| %>
. . .
<% end %>

This will automatically send any forms with the remote_for class as an AJAX request.

Setup your controller action to process AJAX requests

def action
    @model = Model.find(params[:model_id])

    respond_to do |format|
       format.js #auto-maps to action.js.erb
    end
end

Place your jQuery code in action.js.erb

app\views\controller\actions.js.erb

This is where the magic happens. It's here that you can combine your Rails objects with your JavaScript and jQuery client-side code. When complete, Rails will send your jQuery back to the client's browser as an AJAX response. Awesome!

$("#request_artist").autocomplete({
    source: function(req, add){
       <%= @artist.name %>', req, function(data) {
       var suggestions = data.suggestions;
       add(suggestions);
    });
    },
});

The article does a better job of walking through a specific scenario. But, it'll allow you to move from inline jQuery to using better separation of concerns. This is also the same technique for using jQuery and AJAX in your rails app instead of the RJS tutorials you might have seen.

Well, it looks like you're moving in the right direction. Good Luck!

Ivan Gorbachev
+1  A: 

What i do to solve your snippet:

$("#request_artist").autocomplete({
    source: function(req, add){
        $.getJSON('<%= ajax_path("artistName") %>', req, function(data) {
          var suggestions = data.suggestions;
          add(suggestions);
        });
    },
});

I would make sure that the item, with id request_artist also has a attribute data-url set correctly to ajax_path("artist_name"). You make sure that this attribute is filled in correctly in the view.

Inside your javascript no more ruby is needed, it can just use the setting of attribute data-url.

var url = $(this).attr('data-url');

I am not quite sure how to integrate that into the autocompleter code. But i am guessing that this would work:

$("#request_artist").autocomplete({
    source: function(req, add){
        $.getJSON($(this).attr('data-url'), req, function(data) {
          var suggestions = data.suggestions;
            add(suggestions);
        });
    },
});
nathanvda