jQuery Rails Functions


#1

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(“
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


#2

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


#3

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


#4

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


#5

DAZ,

http://docs.jquery.com/Main_Page 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(“
Dropped!”);
}
error: function(msg) {
# do failed stuff here
}
});
}
});

Simon


#6

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


#7

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


#8

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


#9

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


#10

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