Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic nested form on change of select box

I have used Ryan bates nested model form it is working fine,But
i have two models i,e storage and order both having nested model called items.

Storage:

has_many :orders  
has_many :items, :dependent => :destroy
accepts_nested_attributes_for :items

Order:

belongs_to:storage         
has_many :items, :dependent => :destroy
accepts_nested_attributes_for :items

In order view there is storage select box,

<%= f.select :storage_id,
            Storage.all.map{|s| [s.store_no, s.id]} %>

On selecting storage number respective items should appears in the Orders form with partial
can any body tell me the best way to do.

Thanks,

like image 630
Jagdish Barabari Avatar asked Apr 20 '12 11:04

Jagdish Barabari


1 Answers

First you need to watch that input field to see it is changed. So, assuming:

  1. the Storage selector has an id of 'storage'
  2. the Storage selector has the id of the 'storage' as its value

...you could put this in your storage.coffee.js file:

jQuery ->
  $('select#storage').change ->
    storage_id = $('option:selected',this).val()
    $.get 'storages/' +storage_id+ '/orders.js'

Then, assuming that Orders are nested under storage, if your OrdersController looks like so:

OrdersController < ApplicationController

  def index
    @storage = Storage.find(params[:storage_id])
    @orders = @storage.orders
  end

end

...and if you have a partial app/views/orders/_order.html.erb...

...and if you have a div#orders on your page that you want the orders dropped into...

...then you should be able to make an app/views/orders/index.js.erb file like so:

$('div#orders').html('<%= escape_javascript(render @orders) %>');

This should render a copy of the partial for each instance of the orders that belong to a given storage and append it to the dom after the storage selector.

What's happening is: when the select menu is changed it fires a js GET request to the orders index for the given storage. Then that request will automatically attempt to serve up an index.js page, with the instance variables set in the controller available to that view. The js in that view will execute after whatever interpolated ruby is inserted, so you can use rails functions (like render @orders) and then the output of those gets injected into the dom via $('div#orders').html('your rendered orders will be inserted in here by rails').

Clearly you'll have to tweak this to fit your page, I'm just guessing as to what elements of your page are called etc., but this basic concept should work fine. Let me know if you have any questions.

like image 179
Andrew Avatar answered Oct 20 '22 21:10

Andrew