jQuery Rails Functions

Hi,

I was wondering if anybody who used jQuery with rails could help me out. I have a droppable that fires a simple function, shown below:

$("#list").droppable({   accept: ".item",   hoverClass: 'droppable-hover',   drop: function(ev, ui) {     $(this).append("<br>Dropped!");   } });

But how could I get this to fire a Rails funciton in the controller so that the dropped item could be changed at a database level? For example, when it is dropped, how would I change the updated_at value to Time.now?

Thanks,

DAZ

Hi,

You need to call a function in your drop handler that goes out to rails to
make the changes.

We do the following in some of our jquery handlers:

var c = {}; c['authenticity_token'] = encodeURIComponent(window._token); c['user_id'] = <%= current_user.id %>; $.post("<%= url_for(:action => 'lock', :id => @current_page.form_data.id)
%>", c);

Cheers Simon

Thanks Simon, but I'm really new to jQuery - I think I know how to call a function from the drop handler:

$("#dropper").droppable({   accept: "#dragger",   drop: dropped()

});

function dropped(){ // do stuff }

But what do I have to put in the dropped function that actually accesses rails? You seem to be using $.post, but I don't really know how this works. Also, I've seen other examples use $.load, and again, I don't quite get how it works.

Is there any good documentation on this?

cheers again,

DAZ

DAZ,

jQuery API Documentation is pretty good.

We use $.post because of some extra stuff we need to do, but $.ajax is probably the best option for you.

Something like this should work (warning, written in front of the TV and untested)

$("#list").droppable({    accept: ".item",    hoverClass: 'droppable-hover',    drop: function(ev, ui) {        var c = {};        c['authenticity_token'] = encodeURIComponent(window._token);        $.ajax({          type: "POST",           url: "url-to-your-rails-function",           data: c,           success: function(msg){             $(this).append("<br>Dropped!");           }           error: function(msg) {             # do failed stuff here           }        });    } });

Simon

Thanks for this Simon - very useful. So it seems that $.ajax is just a more general version of $.load and $.post - still trying to figure out the exact differences, but at least now I can gain access to the controller and start updating model attributes. I haven't had time to test your code, but will have a play around.

Also ... is all the authenticity_token stuff essential/best practice or are you just using that as an example?

thanks again,

DAZ

Thanks for this Simon - very useful. So it seems that $.ajax is just a more general version of $.load and $.post - still trying to figure out the exact differences, but at least now I can gain access to the controller and start updating model attributes. I haven't had time to test your code, but will have a play around.

Also ... is all the authenticity_token stuff essential/best practice or are you just using that as an example?

thanks again,

DAZ

That's cool.

Depends on the query I think, but it is generally required.

Rails has some rudimentary security built in to stop things (like search
bots I guess) hitting controller functions. You can try it without, but
keep an eye on the logs for an invalid authenticity token error.

Simon

Thanks again Simon, I've since noticed that all forms created by the form_for helper have authenticity token code in too (albeit using some ugly inline javascript!) so it id definitely something I'll look into.

On a separate note ... in your example, you simply listed url: "url-to-your-rails-function"

How do I specify the rails functions? I guess that I can't use any nice helpers such as tasks_path? Are the links relative to the root directory? The actual controller action I want to access would be a dropped action in the tasks controller, so is the url "/tasks/ dropped" ?

I really appreciate all the help you have given so far, it has really helped me get to grips with jQueary on Rails - I'm finding it a great way to keep the JS unobtrusive!

cheers,

DAZ

Hey DAZ,

No probs.

From our code..          $.ajax({              url: "/form_datas/correct/"+formId,

so, form_datas is our controller, correct is the action, and formId is the id param passed to the action

you may be able to use rails helper methods, I don't know, we just specify the URL as above.

cheers Simon

Thanks again Simon - your help is very much appreciated!

Here are a few things I have found out - in case anybody else is reading this:

* To get the authenticity tag to work you need this somewhere in your view: <%= javascript_tag "window._token = '#{form_authenticity_token}'" if protect_against_forgery? %>

Then you can get the authenticity token by referencing window._token

* You can use nice RESTful urls and even fake out the PUT and DELETE requests, for example

$post("/tasks/1"); will go to the show page for the task with id 1 $post("/tasks/1",{_method: "PUT",authenticity_token: encodeURIComponent (window._token)}); will go to the update action for the task with id 1

Hope that makes sense!

cheers,

DAZ