11

I have the following select list.

<%= select_tag "project_id", options_from_collection_for_select(@projects, "id", "title") %>

When the user selects an option from the above list, the list below should be populated with values from database based on the above selection.

<%= select_tag "version_id", options_from_collection_for_select(??project.versions??, "id", "title") %>

I think i should make use of the onchange event, but i have no idea on how to use it. Someone help me please. Thanks!

3
  • 1
    See this this question Commented Oct 30, 2011 at 15:40
  • @rubyprince I have written about rails 3(!!). The remote_function doesn't exist in Rails 3 Commented Oct 31, 2011 at 7:16
  • oh..sorry, in that case you can replace the onchange function with something in jQuery...I will post an answer with it... Commented Oct 31, 2011 at 10:13

1 Answer 1

25

Javascript

function update_versions_div(project_id) {  
  jQuery.ajax({
    url: "/update_versions",
    type: "GET",
    data: {"project_id" : project_id},
    dataType: "html"
    success: function(data) {
      jQuery("#versionsDiv").html(data);
    }
  });
}

Controller

def edit
  @projects = Project.all
  @versions = Version.all
end

def update_versions
  @versions = Version.where(project_id => params[:project_id]).all
  render :partial => "versions", :object => @versions
end

View

<%= select_tag "project_id", options_from_collection_for_select(@projects, "id", "title"), :prompt => "Select a project", :onchange => "update_versions_div(this.value)" %>
<div id="versionsDiv">
  <%= render :partial => 'versions', :object => @versions %>
</div>

Partial: _version.html.erb

<%= select_tag "version_id", options_from_collection_for_select(versions, "id", "title"), :prompt => "Select a version" %>

Also add a route for /update_versions in your routes.rb

match "/update_versions" => "<controller>#update_versions"

Here, you should replace <controller> with name of the controller.

I havent tested the code, so there may be errors.

Update

PullMonkey has updated the code with Rails 3 example, which is obviously superior than this code. Please checkout http://pullmonkey.com/2012/08/11/dynamic-select-boxes-ruby-on-rails-3/ also

Sign up to request clarification or add additional context in comments.

3 Comments

Few improvements to this in terms of security and active record handling: @versions = Version.where('project_id = ?', params[:project_id]).first The where clause currently has a security flaw. Putting the string directly in could leave the query open to malicious content. Furthermore it is currently grabbing the ActiveRecord:Relation and not the object itself. Therefore adding a first method will fix this.
Hi @JellyFishBoy..there are 2 things here: - Version.where(project_id => params[:project_id]) - this where clause does not leave a security flaw, as far as I know. I am not putting the string directly, but, instead is passing a hash. It is the idiomatic way of writing conditions in Rails. Rails does the security handling, if we provide it as a hash. See Rails guide
@JellyFishBoy..About the .first, my intention is not to get the first record, but to get all the records, with the project id. You are right to say, that it returns an activerecord relation and it will fire the query right away, but this activerecord relation will fire the query as soon as methods like inspect, each are called against it. So, the code will work, but I agree that it is better to call explicitely. I will add that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.