4

There is a drop down using select

<%= select("array", "folder", @rows.keys, {}, :onchange =>"?" )%>

There is a partial called "form"

<%= render "form"%>

I need to render the partial whenever there is a change in the selection. Please, let me know if there is a way to do it. I found that the remote_function is deprecated from rails 3.0. I have seen all possible links here with onchange and select tags but could not find a proper answer. I'm new to rails, jQuery and Ajax. Please help

Thanks

Evan Mulawski
  • 54,662
  • 15
  • 117
  • 144
user1455116
  • 2,034
  • 4
  • 24
  • 48

2 Answers2

12

There is definitely a way to do this, and it's a bit of work, but it's quite easy once you get the hang of it.

First, you'll want to attach a jQuery function to the change event of your select box. This can be done by adding some javascript to your application.js file. We want to do this here so our javscript remains unobtrustive. You can try something like this in your application.js file:

$(document).ready(function(){
  $("#select_field_id").change(function(){
    var id = $(this).children(":selected").val();
    var params = 'some_id=' + id;
    $.ajax({
      url: "/some_controller/change_folder",
      data: params
    })
});

What this does is attach an anonymous function to the change event of a select field with id select_field_id. When that field is changed, the id of the selected option gets stored in the var id, and then we create a parameter for the request we'll send by doing var params = 'some_id=' + id;. some_id would be the id of whatever you're changing (so a folder_id if that's what you're using in your example).

Now we need to create the method that will handle this request in our controller. So going with the folder example, add this to the folder controller:

def change_folder
  @folder = Folder.find(params[:some_id])
  respond_to do |format|
    format.js
  end
end

This simply finds a folder based on the id sent in by your ajax request to change_folder. It will also be looking for a corresponding change_folder.js.erb or change_folder.js file to render.

Now we need to write up a change_folder.js.erb file. We need to replace the HTML on some part of your page with the new folder we got, so you should have some kind of div or other section with a unique id.

Inside change_folder.js.erb, we can write this:

$('#your_div').html("<%= escape_javascript(render(partial: "folder", 
locals: { :folder => @folder })).html_safe %>")

This will render a partial called _folder.html.erb that is in the same directory as the change_folder.js.erb file. The partial will need to use an @folder variable for displaying the fields, so you would need something like:

<%= @folder.name %>
<%= @folder.last_updated %>

Inside your _folder.html.erb partial. .name and .last_updated are of course just made up properties of a Folder model. You'll have to use whatever properties you have given to your Folder model instead.

That should get you going to where you need to be. Please let me know if you need anything clarified.

Zajn
  • 4,078
  • 24
  • 39
  • Thank you so much, since iam totally new to Rails, Jquery, Ajax it takes some time for me to create a .js.erb file and render a partial from it. Currently @viren solved my problem. – user1455116 Jun 21 '12 at 16:37
  • Thank you so much for the write up @Zajn, a few things I encountered: 1) You need to add a [member route](http://guides.rubyonrails.org/routing.html#adding-more-restful-actions) in your routes.rb file that corresponds to `change_folder` in this case something like `get :change_folder`, you will probably have to play around with it a little bit depending on where the ajax call is 2) GOTCHA: any js erros in `change_folder.js.erb` will fail *silently* so it may seem like it's not working for no reason, be sure to test the js file by doing something simple like `console.log(...)` – ohhh Aug 19 '15 at 14:48
  • Do I also have to permit extra parameters (using Rails 5.1.3) in the controller? For some reason it doesn't work for me. I've followed the steps in your answer and in ohhh's comment. Thanks! – mabu Oct 24 '17 at 13:35
2

why not render the form in the same page and hide and show it on change of select tag

<html> 
  <body>

  <!-- Your Select tag -->
  <select id="select_id"> 
    <option value="one" selected> One </option>
    <option value="two"> Two </option>
  </select>

  <!-- Here your a div inside with your form is placed -->
  <div id="myform" style="display:none">
    <form action="/someurl">
      .. ..
    </form> 

   <!-- JQuery code to  show the form -->
  <script type="text/javascript">
    $(document).ready(function() {
       $("select#select_id").bind("change",function() {
         if ($(this).val() == "one") 
          $("div#myform").show(); 
         else
          $("div#myform").hide(); 
       })
   })

  </script>

</html>

I you still want to make an ajax request I pretty simple too

$(document).ready(function() {
  $("select#select_id").bind("change",function() {
    if ($(this).val() == "one") {
     $.ajax({
        url : "/form_url",
        data : "html", 
        type: "GET",
        success : function(data) {
          $("div#myform").html(data)
        }
     }) 

  })
})

on the server side you need to respond_to the ajax request using format.js and render a template directed using render command or just define a .js.erb file

Viren
  • 5,812
  • 6
  • 45
  • 98