Mark Thomas
2009-Aug-11 01:50 UTC
Dynamic drop-downs in a form_for using AJAX remote_function - Help
Hello - I am fairly new to Ruby on Rails, but feel like I am learning quick. I have what seems to be a fairly unique issue as I cannot find much out there that describes what I''m seeing. Hopefully it''s a very simple fix, and I simply can''t see the forest through all the trees! I am attempting to create 2 related drop-down lists in the same form_for, both using collection_select. On the first drop-down, I have an onChange "remote_function" call that I want to send an AJAX call to the controller and filter the list in the 2nd drop-down based on what was selected in the first. In the controller method, I then call page.replace_html to render a partial. In the partial is the "updated/filtered" 2nd collection_select drop- down list. The remote_function works fine and calls the Controller method when the first drop-down changes. I am also able to pass the selected value to the method and filter the records returned. The problem occurs when the controller attempts to render the partial, I get the following error: ActionView::TemplateError (undefined local variable or method `f'' for #<ActionView::Base:0xb6e7b2f4>) on line #1 of app/views/listings/ _automodels.html.erb: <%= f.collection_select :model, @automodels, :model, :model, {:prompt => "-Select a Make First-"} %> This leads me to believe that the "f" variable the rest of the fields in the form_for are using is not available to the newly-replaced "collection_select", but I''m not sure why? If the partial contains a simple HTML <input> instead of the collection_select, the replace_html works fine. Source code is worth 1,000 words, so here it is: listings/new.html.erb 1. <% form_for([@user, @listing]) do |f| %> 2. <%= f.error_messages %> 3. <p> 4. <%= f.label :make %><br /> 5. <%= f.collection_select :make, @automakes, :make, :make, {:prompt => "-Select a Make-"}, {:onChange => remote_function(:url => {:action => ''get_automodels''}, :with => "''make='' + this.value")} %> 6. </p> 7. <p> 8. <%= f.label "Model:" %><br/> 9. <div id=''automodelsdiv''> 10. <%= f.collection_select :model, @automodels, :model, :model, {:prompt => "-Select a Make First-"} %> 11. </div> 12. </p> 13. <p> 14. <%= f.submit ''Create'' %> 15. </p> 16. <% end %> listings_controller.rb 1. def get_automodels 2. @automodels = Automodels.find_by_make(params[:make]) 3. render :update do |page| 4. page.replace_html(''automodelsdiv'', :partial => ''automodels'') 5. end 6. end _automodels.html.erb 1. <%= f.collection_select :model, @automodels, :model, :model, {:prompt => "-Select a Make First-"} %>
Frederick Cheung
2009-Aug-11 07:54 UTC
Re: Dynamic drop-downs in a form_for using AJAX remote_function - Help
On Aug 11, 2:50 am, Mark Thomas <thomasm...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hello - > > ActionView::TemplateError (undefined local variable or method `f'' for > #<ActionView::Base:0xb6e7b2f4>) on line #1 of app/views/listings/ > _automodels.html.erb: > <%= f.collection_select :model, @automodels, :model, :model, {:prompt > => "-Select a Make First-"} %> > > This leads me to believe that the "f" variable the rest of the fields > in the form_for are using is not available to the newly-replaced > "collection_select", but I''m not sure why?Because that f referred to a form builder object created by form_for. You''re in a different scope to when you rendered the original form, in a different request, with a different instance of the controller, possibly on a different mongrel or even a different server. The form builder isn''t going to magically appear. Fred
Mark Thomas
2009-Aug-12 02:20 UTC
Re: Dynamic drop-downs in a form_for using AJAX remote_function - Help
Thanks Frederick for looking at my issue. Apparently I don''t have a full understanding of how the AJAX request interacts with (or I guess doesn''t interact with) the form_for... So is the basic idea of what I''m attempting completely wrong or is there some slight modification I can do to pull it off? Basically, I have a form where I want to create a new listing record - but I want the fields to be restricted to values stored in the automodels Model in the database (and the model drop-down to be filtered based on the make selected). From what I''ve been reading, the best way to do the "dynamic select" is using AJAX. However, I guess the collection_selects are never inside a form in the examples I''ve read? I''m open to any suggestions from the experts here - even if it means overhauling the whole thing... :-) On Aug 11, 3:54 am, Frederick Cheung <frederick.che...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> On Aug 11, 2:50 am, Mark Thomas <thomasm...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > Hello - > > > ActionView::TemplateError (undefined local variable or method `f'' for > > #<ActionView::Base:0xb6e7b2f4>) on line #1 of app/views/listings/ > > _automodels.html.erb: > > <%= f.collection_select :model, @automodels, :model, :model, {:prompt > > => "-Select a Make First-"} %> > > > This leads me to believe that the "f" variable the rest of the fields > > in the form_for are using is not available to the newly-replaced > > "collection_select", but I''m not sure why? > > Because that f referred to a form builder object created by form_for. > You''re in a different scope to when you rendered the original form, in > a different request, with a different instance of the controller, > possibly on a different mongrel or even a different server. The form > builder isn''t going to magically appear. > > Fred
Me
2009-Aug-12 03:21 UTC
Re: Dynamic drop-downs in a form_for using AJAX remote_function - Help
You could put each select in a partial then re-render it when coming back from the rjs with the updated select items. On Aug 11, 9:20 pm, Mark Thomas <thomasm...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Thanks Frederick for looking at my issue. > > Apparently I don''t have a full understanding of how the AJAX request > interacts with (or I guess doesn''t interact with) the form_for... > So is the basic idea of what I''m attempting completely wrong or is > there some slight modification I can do to pull it off? > Basically, I have a form where I want to create a new listing record - > but I want the fields to be restricted to values stored in the > automodels Model in the database (and the model drop-down to be > filtered based on the make selected). > From what I''ve been reading, the best way to do the "dynamic select" > is using AJAX. However, I guess the collection_selects are never > inside a form in the examples I''ve read? > > I''m open to any suggestions from the experts here - even if it means > overhauling the whole thing... :-) > > On Aug 11, 3:54 am, Frederick Cheung <frederick.che...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > wrote: > > > On Aug 11, 2:50 am, Mark Thomas <thomasm...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > Hello - > > > > ActionView::TemplateError (undefined local variable or method `f'' for > > > #<ActionView::Base:0xb6e7b2f4>) on line #1 of app/views/listings/ > > > _automodels.html.erb: > > > <%= f.collection_select :model, @automodels, :model, :model, {:prompt > > > => "-Select a Make First-"} %> > > > > This leads me to believe that the "f" variable the rest of the fields > > > in the form_for are using is not available to the newly-replaced > > > "collection_select", but I''m not sure why? > > > Because that f referred to a form builder object created by form_for. > > You''re in a different scope to when you rendered the original form, in > > a different request, with a different instance of the controller, > > possibly on a different mongrel or even a different server. The form > > builder isn''t going to magically appear. > > > Fred
Frederick Cheung
2009-Aug-12 07:50 UTC
Re: Dynamic drop-downs in a form_for using AJAX remote_function - Help
On Aug 12, 3:20 am, Mark Thomas <thomasm...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Thanks Frederick for looking at my issue. > > Apparently I don''t have a full understanding of how the AJAX request > interacts with (or I guess doesn''t interact with) the form_for...Forget about the ajaxness of it. If you had a page with a form and you followed a link from that page you wouldn''t expect the form builder from the first page to be hanging around when you render the second page. If you want to use the form builder version of a helper you just need to create a new form builder for the template that gets rendered for the ajax request (you can use fields_for to create a form builder without actually creating <form> tags) Fred> So is the basic idea of what I''m attempting completely wrong or is > there some slight modification I can do to pull it off? > Basically, I have a form where I want to create a new listing record - > but I want the fields to be restricted to values stored in the > automodels Model in the database (and the model drop-down to be > filtered based on the make selected). > From what I''ve been reading, the best way to do the "dynamic select" > is using AJAX. However, I guess the collection_selects are never > inside a form in the examples I''ve read? > > I''m open to any suggestions from the experts here - even if it means > overhauling the whole thing... :-) > > On Aug 11, 3:54 am, Frederick Cheung <frederick.che...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> > wrote: > > > > > On Aug 11, 2:50 am, Mark Thomas <thomasm...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote: > > > > Hello - > > > > ActionView::TemplateError (undefined local variable or method `f'' for > > > #<ActionView::Base:0xb6e7b2f4>) on line #1 of app/views/listings/ > > > _automodels.html.erb: > > > <%= f.collection_select :model, @automodels, :model, :model, {:prompt > > > => "-Select a Make First-"} %> > > > > This leads me to believe that the "f" variable the rest of the fields > > > in the form_for are using is not available to the newly-replaced > > > "collection_select", but I''m not sure why? > > > Because that f referred to a form builder object created by form_for. > > You''re in a different scope to when you rendered the original form, in > > a different request, with a different instance of the controller, > > possibly on a different mongrel or even a different server. The form > > builder isn''t going to magically appear. > > > Fred
sandeep
2009-Aug-31 18:32 UTC
Re: Dynamic drop-downs in a form_for using AJAX remote_function - Help
Hi I am also struck at the same point please help me ... same problem u r facing sandeep On Aug 11, 6:50 am, Mark Thomas <thomasm...-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:> Hello - > > I am fairly new to Ruby on Rails, but feel like I am learning quick. > I have what seems to be a fairly unique issue as I cannot find much > out there that describes what I''m seeing. Hopefully it''s a very > simple fix, and I simply can''t see the forest through all the trees! > > I am attempting to create 2 related drop-down lists in the same > form_for, both using collection_select. > On the first drop-down, I have an onChange "remote_function" call that > I want to send an AJAX call to the controller and filter the list in > the 2nd drop-down based on what was selected in the first. In the > controller method, I then call page.replace_html to render a partial. > In the partial is the "updated/filtered" 2nd collection_select drop- > down list. > > The remote_function works fine and calls the Controller method when > the first drop-down changes. I am also able to pass the selected value > to the method and filter the records returned. The problem occurs > when the controller attempts to render the partial, I get the > following error: > > ActionView::TemplateError (undefined local variable or method `f'' for > #<ActionView::Base:0xb6e7b2f4>) on line #1 of app/views/listings/ > _automodels.html.erb: > <%= f.collection_select :model, @automodels, :model, :model, {:prompt > => "-Select a Make First-"} %> > > This leads me to believe that the "f" variable the rest of the fields > in the form_for are using is not available to the newly-replaced > "collection_select", but I''m not sure why? > > If the partial contains a simple HTML <input> instead of the > collection_select, the replace_html works fine. > > Source code is worth 1,000 words, so here it is: > > listings/new.html.erb > > 1. <% form_for([@user, @listing]) do |f| %> > 2. <%= f.error_messages %> > 3. <p> > 4. <%= f.label :make %><br /> > 5. <%= f.collection_select :make, @automakes, :make, :make, > {:prompt => "-Select a Make-"}, {:onChange => remote_function(:url => > {:action => ''get_automodels''}, :with => "''make='' + this.value")} %> > 6. </p> > 7. <p> > 8. <%= f.label "Model:" %><br/> > 9. <div id=''automodelsdiv''> > 10. <%= f.collection_select :model, > @automodels, :model, :model, {:prompt => "-Select a Make First-"} %> > 11. </div> > 12. </p> > 13. <p> > 14. <%= f.submit ''Create'' %> > 15. </p> > 16. <% end %> > > listings_controller.rb > > 1. def get_automodels > 2. @automodels = Automodels.find_by_make(params[:make]) > 3. render :update do |page| > 4. page.replace_html(''automodelsdiv'', :partial => ''automodels'') > 5. end > 6. end > > _automodels.html.erb > > 1. <%= f.collection_select :model, @automodels, :model, :model, > {:prompt => "-Select a Make First-"} %>