2010-07-26 15 views
15

Sto cercando di effettuare una chiamata onchange su una casella di selezione. Per la mia applicazione sto usando jquery.js e rails.js come accennato per fare uso di UJS. Tuttavia, il codice generato è per Prototype e non per le chiamate jquery ajax. Il mio codice sia simile alla seguente:Come effettuare chiamate Ajax con Rails 3 usando remote_function?

<%= select_tag :category, 
     options_for_select(
      Category.find(:all,:select=>"name,id").collect{|c| [c.name,c.id]}), 
     :onchange => remote_function(:url => {:controller => "posts", 
              :action => "filter_post", 
              :filter =>"category"}, 
            :with=>"'category_id=' + $('#category').val()") %> 

Il codice che viene generato da questo è:

new Ajax.Request('/posts/filter_posts?filter=category', {asynchronous:true, evalScripts:true, 
parameters:'category_id=' + $('#category').val() + '&authenticity_token=' + 
encodeURIComponent('CCyYj1wqXtddK6pUV6bAxw0CqZ4lbBxDGQHp13Y/jMY=')}) 

risposta

25

Come Sergei detto: Non v'è alcun remote_function in Rails 3.

La soluzione è quella di aggiungere discretamente il gestore onchange utilizzando qualcosa di simile:

$(function($) { 
    $("#selector_for_element").change(function() { 
     $.ajax({url: '<%= url_for :action => 'action_name', :id => @model.id %>', 
     data: 'selected=' + this.value, 
     dataType: 'script'}) 
    }); 
}); 

Ciò chiamerà il metodo action_name nel controller corrente, passando il risultato di selected=... come parametro. Ora puoi restituire un pezzo di javascript, ad esempio usando qualcosa come:

calculated = calculate_some_value_using(params[:selected]) 
render(:update) {|page| 
    page << "$('#selector_for_field_to_update).html(#{calculated})" 
} 

nel controller. La stringa che si aggiunge alla "pagina" deve essere javascript valido e verrà eseguita automaticamente se si utilizza $ .ajax.

EDIT: FYI, abbiamo recentemente aggiunto un cambiamento di selezione aiutante a jQuery-UJS, così si può fare in questo modo discreto utilizzando il built-in jQuery-UJS adattatore ora:

<%= select_tag :category_id, 
    options_for_select(
     Category.find(:all,:select=>"name,id").collect{|c| [c.name,c.id]}), 
    :data => { :remote => true, :url => url_for(:controller => "posts", 
             :action => "filter_post", 
             :filter =>"category") } %> 

anche se ad essere onesti, l'aggiunta di un evento di modifica select non sarà mai "non invadente" in quanto non vi è alcun fallback valido per gli utenti con javascript disabilitato a meno che il tuo modulo non dipenda dal risultato della richiesta AJAX.

+2

@jangosteve Grazie per la modifica. Esattamente quello che stavo cercando. –

+0

@confusion: mi ha davvero aiutato, grazie – vishB

10

Non c'è remote_function in Rails 3. Se stai usando jQuery, si può fare qualcosa di simile questo:

$.ajax({ 
    type: 'POST', 
    url: 'http://your_url/blah', 
    data: 'param1=value1&params2=value2', 
    success: function(data){eval(data);} 
}); 
3

seguito è la semplice frammento di jQuery dal mio punto di vista Haml

:javascript 

    $("#select_box_id").change(function() { 
     $.post('#{target_url}?param_one='+$(this).val()); 
    }); 

Spero che questo aiuti. Grazie ..

0

Ajax Chiama per controllori-action con i parametri:

function combined_search() { 
    var countries = $('#countries').val(); 
    var albums = $('#albums').val(); 
    var artists = $('#artists').val(); 
    $.ajax({ 
     url:"<%=url_for :controller => 'music_on_demand',:action => 'combined_search' %>", 
     data:'country=' + encodeURIComponent(countries) + '&albums=' + encodeURIComponent(albums) + '&artists=' + encodeURIComponent(artists), 
     cache:false, 
     success:function (data) { 
     } 
    }) 
} 
1

Se dovete affrontare il problema che ho avuto di aggiornamento di un grande rotaie app per Rails 3 che ha fatto un uso pesante di remote_function, è possibile ottenere la compatibilità all'indietro limitata aggiungendo un metodo application_helper che genera codice jQuery nel formato suggerito da altre risposte qui. Sono stato in grado di utilizzare questo codice così com'è, anche se ho dovuto aggiornare un pezzo di codice chiamante per utilizzare la nuova opzione: script di successo anziché l'opzione di hash di aggiornamento che non è supportata qui. Questo può comprare un certo tempo per eventualmente refactoring tutto remote_function chiama ad utilizzare jQuery discreto-UJS callback di evento:

def remote_function(options) 
    ("$.ajax({url: '#{ url_for(options[:url]) }', type: '#{ options[:method] || 'GET' }', " + 
    "data: #{ options[:with] ? options[:with] + '&amp;' : '' } + " + 
    "'authenticity_token=' + encodeURIComponent('#{ form_authenticity_token }')" + 
    (options[:data_type] ? ", dataType: '" + options[:data_type] + "'" : "") + 
    (options[:success] ? ", success: function(response) {" + options[:success] + "}" : "") + 
    (options[:before] ? ", beforeSend: function(data) {" + options[:before] + "}" : "") + "});").html_safe 
end 
Problemi correlati