jQuery conversion - how to replace :onchange => remote_function() call?

II'm switching to jQuery and wondering how do I pull the onchange: stuff out of the following for a select and put it into a handler?

here's what I have in my view now:

<%= select_tag :selected_email,    options_from_collection_for_select(update_request.contact.emails, 'id', 'value', update_request.contact.primary_email_id),   :onchange => remote_function(:url => {:action => :set_request_email, :id => update_request.id}, :with => "'value=' + value"),   :id => "request_email_#{update_request.id}" %>

I have this in application.js:

jQuery(document).ready(function() {   // handle change events from update_requests listing   $("select[id^='request_email']").change(function(event) {

    var selected = $("#" + event.target.id + " option:selected");     alert('You chose ' + selected.val());   }); });

but, how would I extract the options/params and post them to the :set_request_email action from the JS?

lunaclaire wrote:

II'm switching to jQuery and wondering how do I pull the onchange: stuff out of the following for a select and put it into a handler?

here's what I have in my view now:

<%= select_tag :selected_email,    options_from_collection_for_select(update_request.contact.emails, 'id', 'value', update_request.contact.primary_email_id),   :onchange => remote_function(:url => {:action => :set_request_email, :id => update_request.id}, :with => "'value=' + value"),   :id => "request_email_#{update_request.id}" %>

$("#your_select_id").live("change",function(event){    //It return whatever value is selected    value_of_select =$("#your_select_id").val(); //Now call ajax request on change //You can refer code http://railstech.com/?p=58 }); Refer Code http://railstech.com/?p=58

Thx, Amar.

I should have been more clear... My need for answers stems from my ignorance of how to access values known in a view to JS and the jquery code so that they can be accessed there or posted back to the server thru ajax.

curr the remote_function() call has the url params which are known in my view (the action to post to and the obj ID of interest that the selection is for), but I cant figure out how to generate that url in JS/jQuery

I think I've done this kind of thing before, but I'm missing it at the moment.

Can someone show me?

Easiest thing to do is to make a simple remote_form_for/ form_remote_tag and look at the jQuery it produces in its onsubmit function. However, I'm a little confused, why not just put your select box inside a form tag that posts to your URL and let rails helpers + jrails do the parameter scrapping and submission for you?

I did take the first steps in switching to jQuery by using jRails, but now I'm trying to "do the right thing" and start moving this app away from the obtrusive JS and those helpers. I've been using remote_function for a long time, but using the conversion here as a model for how to move behaviors to the application.js and away from the views themselves.

So, if someone can answer the question 2 posts back about how to generate/pass the params that should help me "get it" as far as how to set those behaviors up.

The conceptual prob I'm having is that the way I've been doing it seems to have a tighter coupling betw the obj being displayed and the need in some cases (like this one) to pass info about that obj back to the controller.

It seems that by having the jQuery code "waiting" for an event (onChange here), it's decoupled from the view and, thus, doesnt know as much about obj's and such associated with the element it's responding on.

So, my question remains... how to pass/access relevant values for the behavioral response?

Doesn't 'this' point to the DOM object in question in JS? I think this is somewhat what you're looking for, but perhaps I'm misunderstanding (you did post about it four times though, so I should understand :p):

$("#your_select_id").live("change",function(event){    // this is the object(s) you bound to; might need to use $ (this).each(function() {...}) to operate on the right form?    $(this);

   // And you can find the form its on like this    $form = $(this).parents('form');

   // And these are the params for your form    var params = $.param($form.serializeArray());    // Add in authentication token if applicable    params += '&authenticity_token=' + encodeURIComponent(...);

   // And submit something like this    $.ajax({      data: params,      type: 'post',      url: '/some_post_back'    }); }

Or am I still misunderstanding?

'this' is going to refer to elements in the DOM, but what that isnt what I'm referring to. I'll be a more explicit below...

Here's the relevant code from my original post:

remote_function(:url => {:action => :set_request_email, :id => update_request.id}, :with => "'value=' + value")

this is in a partial that is rendered for a set of objects. Basically, for each, I'm loading up a select menu with associated email addresses. When the user selects one of these from the menu, I've been firing off a call to the :set_request_email action to handle the change, passing the relevant obj id and the newly selected value.

That's pretty straightforward when it's inline in the view.

But, I want to understand how to use jQuery in the way I've described above where the behavior is more decoupled and encapsulated in the JS code.

So, the jQuery fragment in the first post shows how I get the selected value, but I still am curious about:

a) how I direct the ajax post to the right action (this is the url: '/ some_post_back' in your code fragment and :set_request_email in my remote_function)

b) how to access the relevant object id to be passed back to the controller action (this is the update_request.id in my remote_function)

Since I'm not calling the jQuery code and, instead, simply setting it up to respond to the change event, I'm missing how it gets 'passed' these values.

There's a concept and technique I'm missing here that may be simple, but I'm not getting it.

Is my question more clear now?

Thx again.

OK, I figured it out. Though I wonder why it was so hard to do so... :slight_smile:

Here's what I'm doing in case others have the same questions and find this...

now in my view template I have:

<%= select_tag :selected_email,   options_from_collection_for_select(update_request.contact.emails, 'id', 'value', update_request.contact.primary_email_id) + '<option value="-1">Add New Email...</option>',   :id => "request_email_#{update_request.id}",   :class => "request_email_select",   :select_email_path => url_for(:controller => :update_requests, :action => :set_request_email),   :request_id => update_request.id %>

Note that I'm 'passing' the data that I need in the JS code as *attributes* on the DOM element.

Then in the JS/jQuery code:

$.ajax({   type: "POST",   url: $(this).attr('select_email_path'),   data: { value: val, id: $(this).attr('request_id') },   success: function(html){ ...   });

where I look for those attributes.

Seems a little weird to me to set these as attributes, but this works. I dont know if this is the right way, but as you can see from this entire thread, I never discovered another way to pass params to jQuery.