Hello, I just can''t seem to find a way to extend a form dynamically in ROR. Say I am writing a recipe website. There is one form to enter the recipe. There is room for N number of ingredients (let''s say a text field for each ingredient name and selection list for the amount). What if the user wants to add more than N ingredients as he types them in? how do I do this without a POST, and have those new fields included in the request (i guess they need to have a unique name and id). thank you. Alon. -- Posted via http://www.ruby-forum.com/.
Jonathan Viney
2006-Jan-23 12:48 UTC
[Rails] Re: Adding form fields (extending a form) on the fly
You could have a link on the page called ''Add extra ingredient field'' that uses ajax to add in more fields as necessary. Put the ingredient field in a partial (_ingredient.rhtml) so you don''t have to repeat yourself. View: <div id="ingredients"> <% 5.times do %> <%= render :partial => ''ingredient'' %> <% end %> </div> <%= link_to_remote ''Add extra ingredient'', :update => ''ingredients'', :position => :bottom, :url => { :action => :extra_ingredient } %> Controller: def extra_ingredient render :partial => ''ingredient'' end I haven''t tested this, but something like this should work fine. Cheers, Jonny. goldshuv wrote:> Hello, > > I just can''t seem to find a way to extend a form dynamically in ROR. > > Say I am writing a recipe website. There is one form to enter the > recipe. There is room for N number of ingredients (let''s say a text > field for each ingredient name and selection list for the amount). What > if the user wants to add more than N ingredients as he types them in? > how do I do this without a POST, and have those new fields included in > the request (i guess they need to have a unique name and id). > > thank you. > Alon.-- Posted via http://www.ruby-forum.com/.
goldshuv
2006-Jan-23 13:50 UTC
[Rails] Re: Adding form fields (extending a form) on the fly
Jonny, Thanks a lot. I appreciate it. I did try something like this earlier but I am running into a problem. The form may have all the extra fields the user requested, but they all have the same name and id: for example, if my text_field looks something like this <%= text_field(:ingredient, :name) %> rendering it more times will render the same exact thing over and over <%= text_field(:ingredient, :name) %> <%= text_field(:ingredient, :name) %> <%= text_field(:ingredient, :name) %> ... ... and when the form is submitted the request will include only *one* entry for ingredient => { name => "sometext"}. and all the text that the user entered (besides the first one) will not be there. thanks, Alon. Jonathan Viney wrote:> You could have a link on the page called ''Add extra ingredient field'' > that uses ajax to add in more fields as necessary. Put the ingredient > field in a partial (_ingredient.rhtml) so you don''t have to repeat > yourself. > > View: > > <div id="ingredients"> > <% 5.times do %> > <%= render :partial => ''ingredient'' %> > <% end %> > </div> > <%= link_to_remote ''Add extra ingredient'', :update => ''ingredients'', > :position => :bottom, :url => { :action => :extra_ingredient } %> > > Controller: > > def extra_ingredient > render :partial => ''ingredient'' > end > > I haven''t tested this, but something like this should work fine. > > Cheers, Jonny. > > goldshuv wrote: >> Hello, >> >> I just can''t seem to find a way to extend a form dynamically in ROR. >> >> Say I am writing a recipe website. There is one form to enter the >> recipe. There is room for N number of ingredients (let''s say a text >> field for each ingredient name and selection list for the amount). What >> if the user wants to add more than N ingredients as he types them in? >> how do I do this without a POST, and have those new fields included in >> the request (i guess they need to have a unique name and id). >> >> thank you. >> Alon.-- Posted via http://www.ruby-forum.com/.
Michael Bannister
2006-Jan-23 14:31 UTC
[Rails] Re: Adding form fields (extending a form) on the fly
I''m about to do something similar. Have a look on here: http://wiki.rubyonrails.org/rails/pages/UnderstandingRequestParameters You need to do something like <% index = Time.now.to_s -%> <%= text_field("ingredient[#{index}]", :name) %> to generate a temporary key for each ingredient. But in the action that actually creates/saves all the ingredients, don''t use this key as the id, instead let the database autonumber them for you (not 100% sure on details of this bit as I haven''t done it yet!) Michael goldshuv wrote:> Jonny, > > Thanks a lot. I appreciate it. I did try something like this earlier but > I am running into a problem. The form may have all the extra fields the > user requested, but they all have the same name and id: > > for example, if my text_field looks something like this > > <%= text_field(:ingredient, :name) %> > > rendering it more times will render the same exact thing over and over > > <%= text_field(:ingredient, :name) %> > <%= text_field(:ingredient, :name) %> > <%= text_field(:ingredient, :name) %> > ... > ... > > and when the form is submitted the request will include only *one* entry > for ingredient => { name => "sometext"}. and all the text that the user > entered (besides the first one) will not be there. > > thanks, > Alon. > > > > Jonathan Viney wrote: >> You could have a link on the page called ''Add extra ingredient field'' >> that uses ajax to add in more fields as necessary. Put the ingredient >> field in a partial (_ingredient.rhtml) so you don''t have to repeat >> yourself. >> >> View: >> >> <div id="ingredients"> >> <% 5.times do %> >> <%= render :partial => ''ingredient'' %> >> <% end %> >> </div> >> <%= link_to_remote ''Add extra ingredient'', :update => ''ingredients'', >> :position => :bottom, :url => { :action => :extra_ingredient } %> >> >> Controller: >> >> def extra_ingredient >> render :partial => ''ingredient'' >> end >> >> I haven''t tested this, but something like this should work fine. >> >> Cheers, Jonny. >> >> goldshuv wrote: >>> Hello, >>> >>> I just can''t seem to find a way to extend a form dynamically in ROR. >>> >>> Say I am writing a recipe website. There is one form to enter the >>> recipe. There is room for N number of ingredients (let''s say a text >>> field for each ingredient name and selection list for the amount). What >>> if the user wants to add more than N ingredients as he types them in? >>> how do I do this without a POST, and have those new fields included in >>> the request (i guess they need to have a unique name and id). >>> >>> thank you. >>> Alon.-- Posted via http://www.ruby-forum.com/.
Brandt Lofton
2006-Jan-23 15:31 UTC
[Rails] Re: Adding form fields (extending a form) on the fly
I do believe you can also specify the recipes to be an array. Try <%= text_field("ingredient", :name[] %> Or something to that effect. I''m 99% sure there is a way to do this, but I don''t have time to investigate or test atm. -B On 1/23/06, Michael Bannister <rubyforum@michaelbannister.co.uk> wrote:> > I''m about to do something similar. Have a look on here: > http://wiki.rubyonrails.org/rails/pages/UnderstandingRequestParameters > > You need to do something like > <% index = Time.now.to_s -%> > <%= text_field("ingredient[#{index}]", :name) %> > > to generate a temporary key for each ingredient. But in the action that > actually creates/saves all the ingredients, don''t use this key as the > id, instead let the database autonumber them for you (not 100% sure on > details of this bit as I haven''t done it yet!) > > Michael > > goldshuv wrote: > > Jonny, > > > > Thanks a lot. I appreciate it. I did try something like this earlier but > > I am running into a problem. The form may have all the extra fields the > > user requested, but they all have the same name and id: > > > > for example, if my text_field looks something like this > > > > <%= text_field(:ingredient, :name) %> > > > > rendering it more times will render the same exact thing over and over > > > > <%= text_field(:ingredient, :name) %> > > <%= text_field(:ingredient, :name) %> > > <%= text_field(:ingredient, :name) %> > > ... > > ... > > > > and when the form is submitted the request will include only *one* entry > > for ingredient => { name => "sometext"}. and all the text that the user > > entered (besides the first one) will not be there. > > > > thanks, > > Alon. > > > > > > > > Jonathan Viney wrote: > >> You could have a link on the page called ''Add extra ingredient field'' > >> that uses ajax to add in more fields as necessary. Put the ingredient > >> field in a partial (_ingredient.rhtml) so you don''t have to repeat > >> yourself. > >> > >> View: > >> > >> <div id="ingredients"> > >> <% 5.times do %> > >> <%= render :partial => ''ingredient'' %> > >> <% end %> > >> </div> > >> <%= link_to_remote ''Add extra ingredient'', :update => ''ingredients'', > >> :position => :bottom, :url => { :action => :extra_ingredient } %> > >> > >> Controller: > >> > >> def extra_ingredient > >> render :partial => ''ingredient'' > >> end > >> > >> I haven''t tested this, but something like this should work fine. > >> > >> Cheers, Jonny. > >> > >> goldshuv wrote: > >>> Hello, > >>> > >>> I just can''t seem to find a way to extend a form dynamically in ROR. > >>> > >>> Say I am writing a recipe website. There is one form to enter the > >>> recipe. There is room for N number of ingredients (let''s say a text > >>> field for each ingredient name and selection list for the amount). > What > >>> if the user wants to add more than N ingredients as he types them in? > >>> how do I do this without a POST, and have those new fields included in > >>> the request (i guess they need to have a unique name and id). > >>> > >>> thank you. > >>> Alon. > > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails@lists.rubyonrails.org > http://lists.rubyonrails.org/mailman/listinfo/rails >-------------- next part -------------- An HTML attachment was scrubbed... URL: http://wrath.rubyonrails.org/pipermail/rails/attachments/20060123/bc2456a2/attachment.html
Gregory Seidman
2006-Jan-23 16:33 UTC
[Rails] Re: Adding form fields (extending a form) on the fly
On Mon, Jan 23, 2006 at 01:48:45PM +0100, Jonathan Viney wrote: } You could have a link on the page called ''Add extra ingredient field'' } that uses ajax to add in more fields as necessary. Put the ingredient } field in a partial (_ingredient.rhtml) so you don''t have to repeat } yourself. [...] There is no need for AJAX. Take a look at http://www.anthropohedron.net/bookmarkfeeds/ for an example that just uses JavaScript to create a new line and I handle it with Ruby pretty easily. The source is freely available (it was a simple toy I used to learn Ruby and RoR, so consider it public domain) at http://www.anthropohedron.net/bookmarkfeeds/src.tgz } I haven''t tested this, but something like this should work fine. } Cheers, Jonny. --Greg } goldshuv wrote: } > Hello, } > } > I just can''t seem to find a way to extend a form dynamically in ROR. } > } > Say I am writing a recipe website. There is one form to enter the } > recipe. There is room for N number of ingredients (let''s say a text } > field for each ingredient name and selection list for the amount). What } > if the user wants to add more than N ingredients as he types them in? } > how do I do this without a POST, and have those new fields included in } > the request (i guess they need to have a unique name and id). } > } > thank you. } > Alon. } } -- } Posted via http://www.ruby-forum.com/. } _______________________________________________ } Rails mailing list } Rails@lists.rubyonrails.org } http://lists.rubyonrails.org/mailman/listinfo/rails }
goldshuv
2006-Jan-23 17:02 UTC
[Rails] Re: Re: Adding form fields (extending a form) on the fly
Thanks guys, Well still no luck but I appreciate all the suggestions. first suggestion (timestamping) gives this: `@ingredient[Mon Jan 23 18:57:50 IST 2006]'' is not allowed as an instance variable name second suggestion (arrays) gives this: undefined method `[]'' for :quantity_whole:Symbol and I can''t seem to find this use case (cloning the same form field) in the bookmark feeds site (but thanks for the source). still searching... thanks, Alon. -- Posted via http://www.ruby-forum.com/.
Hello Everyone, I hope you AJAX pros don''t mind me asking such a simple question, but it''s been baffling me all weekend. I''m trying to learn the AJAX side of rails and struggling with what I though would be fairly simple operations. I''d like to add rows to a table, and use an effect, like Slide Down or Highlight. However, when I tried to add them in the way recommended by the book I''m going off of, it didn''t work. Here''s some snippits of what I have: My view: ------------------------------- <% content_for("page_scripts") do -%> function item_added() { var item = $(''mytable'').lastChild.lastChild; new Effect.Highlight(item); } <% end -%> <h1>Listing</h1> <%= link_to ''New'', :action => ''new'' %> <div id="mytable_div"> <table id="mytable"> <%= render(:partial => ''mytable'') -%> </table> </div> <br /> ------------------------------- _mytable.rhtml: ------------------------------- <tr bgcolor="#999999"> <th><font color="#ffffff">Col1</font></th> <th><font color="#ffffff">Col2</font></th> <th><font color="#ffffff">Col3</font></th> <th><font color="#ffffff">...</font></th> <th><font color="#ffffff">Col9</font></th> </tr> <%= render(:partial => ''row'', :collection => @items) -%> ------------------------------- _row.rhtml: ------------------------------- <tr bgcolor="#dddddd" id="timecard_<%= timecard.id %>"> <td><%=h item.val1 %></td> <td><%=h item.val2 %></td> <td><%=h item.val3 %></td> <td>...</td> <td><%=h item.val9 %></td> </tr> ------------------------------- Controller''s new action: ------------------------------- def new item = MyClass.new() render(:partial => ''row'', :object => item, :layout => false) end The row is added by AJAX but no effect is called... any idea what I''m doing wrong? -Josh -------------- next part -------------- A non-text attachment was scrubbed... Name: PGP.sig Type: application/pgp-signature Size: 194 bytes Desc: This is a digitally signed message part Url : http://wrath.rubyonrails.org/pipermail/rails/attachments/20060123/d16570f9/PGP.bin
Ben Munat
2006-Jan-23 17:47 UTC
[Rails] Re: Adding form fields (extending a form) on the fly
goldshuv wrote:> I am running into a problem. The form may have all the extra fields the > user requested, but they all have the same name and id: > > for example, if my text_field looks something like this > > <%= text_field(:ingredient, :name) %> > > rendering it more times will render the same exact thing over and over > > <%= text_field(:ingredient, :name) %> > <%= text_field(:ingredient, :name) %> > <%= text_field(:ingredient, :name) %> > ... > ... > > and when the form is submitted the request will include only *one* entry > for ingredient => { name => "sometext"}. and all the text that the user > entered (besides the first one) will not be there. >It is perfectly valid to send multiple values for the same http post param. Rails should make that available as an array.... Hmmm, I just went and checked and it appears that Rails only keeps the first value. Someone please tell me that I''m just not looking at my @params right... tell me that rails is NOT throwing away the other perfectly valid input params! Post params with the same name should simply be put into an array. Hoping someone can set me straight on this! b
goldshuv
2006-Jan-23 18:07 UTC
[Rails] Re: Re: Adding form fields (extending a form) on the fly
Well, i hope so too, but it''s pretty clear from the request dump that only the first one is saved... Alon. -- Posted via http://www.ruby-forum.com/.
Ben Munat
2006-Jan-23 18:45 UTC
[Rails] Re: Re: Adding form fields (extending a form) on the fly
Hmm, from the Agile book, pg. 355: "When the user submits the form, the raw POST data is sent back to our application. Rails extracts the fields from the form and constructs the params hash. *Simple values (such as the id field, extracted by routing the form action) are stored as scalars in the hash. But, if a parameter name has brackets in it, Rails assumes that is it part of more structured data and constructs a hash to hold the key values.* Inside this hash, the string inside the brackets is used as the key." So, Rails adds it''s own data structure communication nomenclature on top of basic HTTP. That''s groovy and all, but I personally find it extremely disconcerting that I have to bend my html to fit the wishes of rails. And what if -- as was I think the case of the OP -- I don''t have anything to use as a key... if I''m simply inputting a list of values? I don''t know if any rails devs are listening here, but I have to say that I''m fairly stunned at this oversight. The code handling request params should simply default to creating an array for each name found in the headers and wrap this in an accessor that returns the first value for single params. It''s fine if you want to add bells and whistles and allow people to create hashes by putting square brackets in the name attribute, but it is a tremendous dent to rails'' credibility in my book if it can''t handle multiple params with the same name. b goldshuv wrote:> Well, i hope so too, but it''s pretty clear from the request dump that > only the first one is saved... > > Alon. >
Ezra Zygmuntowicz
2006-Jan-23 19:27 UTC
[Rails] Re: Re: Adding form fields (extending a form) on the fly
On Jan 23, 2006, at 10:46 AM, Ben Munat wrote:> Hmm, from the Agile book, pg. 355: > > "When the user submits the form, the raw POST data is sent back to > our application. Rails extracts the fields from the form and > constructs the params hash. *Simple values (such as the id field, > extracted by routing the form action) are stored as scalars in the > hash. But, if a parameter name has brackets in it, Rails assumes > that is it part of more structured data and constructs a hash to > hold the key values.* Inside this hash, the string inside the > brackets is used as the key." > > So, Rails adds it''s own data structure communication nomenclature > on top of basic HTTP. That''s groovy and all, but I personally find > it extremely disconcerting that I have to bend my html to fit the > wishes of rails. And what if -- as was I think the case of the OP > -- I don''t have anything to use as a key... if I''m simply inputting > a list of values? > > I don''t know if any rails devs are listening here, but I have to > say that I''m fairly stunned at this oversight. The code handling > request params should simply default to creating an array for each > name found in the headers and wrap this in an accessor that returns > the first value for single params. It''s fine if you want to add > bells and whistles and allow people to create hashes by putting > square brackets in the name attribute, but it is a tremendous dent > to rails'' credibility in my book if it can''t handle multiple params > with the same name. > > bBen- Of course you can accomplish what you want with rails params system. Once you understand how it works I''m sure you will see how nice it is to work with. If you want a list of text_fields to show up in an array in the params all you need to do is something like this: <input name="list[]" type="text" /> <input name="list[]" type="text" /> <input name="list[]" type="text" /> <input name="list[]" type="text" /> <input name="list[]" type="text" /> <input name="list[]" type="text" /> Then the an array of list items will be available in your controller with params[:list] . Its'' really very simple. By using the empty [] array constructor after the name of the field, rails will automatically recognize this and create an array in the params hash with a key of :list. So if you entered the following entries into your six text fields: field1 field2 field3 field4 field5 field6 Then the following would be true: params[:list] == [''field1'', ''field2'', ''field3'', ''field4'', ''field5'', ''field6''] Hope that clears it up for you. Cheers- -Ezra Zygmuntowicz Yakima Herald-Republic WebMaster http://yakimaherald.com 509-577-7732 ezra@yakima-herald.com
Jonathan Viney
2006-Jan-23 20:16 UTC
[Rails] Re: AJAX Effects when Adding/Removing table rows
You would be better off doing the effect with either RJS, or as a callback from the ajax request. To do it the second way, add something like this to the ajax :complete => visual_effect(:highlight, <<element_id>>) Or, to do it your way, you should be calling Effect.Highlight with an id, not an actual element, ie new Effect.Highlight(item.id);. You should also check that item is actually the correct element with a valid id. Just use alert(item.id); to quickly check that. And... to use ajax, your link_to tag should should be link_to_remote: <%= link_to_remote :update => ''mytable'', :position => :bottom , :url => { :action => :new } %> Cheers, Jonny. Joshua Gitlin wrote:> Hello Everyone, > > I hope you AJAX pros don''t mind me asking such a simple question, but > it''s been baffling me all weekend. I''m trying to learn the AJAX side > of rails and struggling with what I though would be fairly simple > operations. I''d like to add rows to a table, and use an effect, like > Slide Down or Highlight. However, when I tried to add them in the way > recommended by the book I''m going off of, it didn''t work. Here''s some > snippits of what I have: > > My view: > ------------------------------- > <% content_for("page_scripts") do -%> > function item_added() > { > var item = $(''mytable'').lastChild.lastChild; > new Effect.Highlight(item); > } > <% end -%> > > <h1>Listing</h1> > > <%= link_to ''New'', :action => ''new'' %> > > <div id="mytable_div"> > <table id="mytable"> > <%= render(:partial => ''mytable'') -%> > </table> > </div> > > <br /> > ------------------------------- > _mytable.rhtml: > ------------------------------- > <tr bgcolor="#999999"> > <th><font color="#ffffff">Col1</font></th> > <th><font color="#ffffff">Col2</font></th> > <th><font color="#ffffff">Col3</font></th> > <th><font color="#ffffff">...</font></th> > <th><font color="#ffffff">Col9</font></th> > </tr> > <%= render(:partial => ''row'', :collection => @items) -%> > ------------------------------- > _row.rhtml: > ------------------------------- > <tr bgcolor="#dddddd" id="timecard_<%= timecard.id %>"> > <td><%=h item.val1 %></td> > <td><%=h item.val2 %></td> > <td><%=h item.val3 %></td> > <td>...</td> > <td><%=h item.val9 %></td> > </tr> > ------------------------------- > Controller''s new action: > ------------------------------- > def new > item = MyClass.new() > render(:partial => ''row'', :object => item, :layout => false) > end > > The row is added by AJAX but no effect is called... any idea what I''m > doing wrong? > > -Josh-- Posted via http://www.ruby-forum.com/.
Jonathan Viney
2006-Jan-23 20:24 UTC
[Rails] Re: Re: Adding form fields (extending a form) on the fly
You should be able to repeat <%= text_field ''ingredient[]'', ''name'' %> as many times as you want, and be able access all of them in the params hash. Second suggestion: You shouldn''t use :quantity_whole[], I don''t think symbols will work here. Do ''quantity_whole[]'' instead. Gregory: You are correct, you don''t *have* to use ajax, but if you don''t you have to repeat the code used to create the extra field in javascript. Ajax helps with DRY in this case. -Jonny. goldshuv wrote:> Thanks guys, > > Well still no luck but I appreciate all the suggestions. > > first suggestion (timestamping) gives this: > `@ingredient[Mon Jan 23 18:57:50 IST 2006]'' is not allowed as an > instance variable name > > second suggestion (arrays) gives this: > undefined method `[]'' for :quantity_whole:Symbol > > and I can''t seem to find this use case (cloning the same form field) in > the bookmark feeds site (but thanks for the source). > > still searching... > > thanks, > Alon.-- Posted via http://www.ruby-forum.com/.
Michael Bannister
2006-Jan-23 20:31 UTC
[Rails] Re: Re: Adding form fields (extending a form) on the fly
Jonathan Viney wrote:> You should be able to repeat <%= text_field ''ingredient[]'', ''name'' %> as > many times as you want, and be able access all of them in the params > hash.Has anyone who''s suggested this actually tried it and got it to work? I''ve tried repeating a form element with name like ''ingredient[]'' and setting the form to an action/view which simply calls debug(params). I only get a single entry in the "ingredient" hash, with an empty key, like this: ingredient: !ruby/hash:HashWithIndifferentAccess '''': !ruby/hash:HashWithIndifferentAccess name: '''' amount: '''' -- Posted via http://www.ruby-forum.com/.
Gregory Seidman
2006-Jan-23 20:43 UTC
[Rails] Re: Re: Adding form fields (extending a form) on the fly
On Mon, Jan 23, 2006 at 09:24:19PM +0100, Jonathan Viney wrote: [...] } Gregory: } You are correct, you don''t *have* to use ajax, but if you don''t you have } to repeat the code used to create the extra field in javascript. Ajax } helps with DRY in this case. DRY is all well and good, but it can be taken too far. If I can safely do something solely on the client side to avoid a server roundtrip (and make no mistake, AJAX is still a server roundtrip), I will do it that way almost every time. (Note that I said "safely." There are times when it is inappropriate to execute code on the client side, particularly when it involves moving too much or sensitive data to the client side and possibly back or when doing so could allow bad data to be accepted by the server.) Furthermore, the JavaScript solution I gave degrades nicely on browsers with JavaScript turned off or entirely unavailable. When the page is loaded there is always a blank row for the user to add another line. If JavaScript is available, a button is created that will dynamically add another blank row. Any rows left blank are ignored by the controller code, but if that original blank row is filled then the controller will accept it as another row. The user with JavaScript can add several rows between server roundtrips, but the user without JavaScript can still add one row per server roundtrip. Once you start relying on AJAX, you start making it harder to degrade nicely. } -Jonny. --Greg
Ben Munat
2006-Jan-23 20:48 UTC
[Rails] Re: Re: Adding form fields (extending a form) on the fly
Ezra Zygmuntowicz wrote:> Its'' really very simple. By using the > empty [] array constructor after the name of the field, rails will > automatically recognize this and create an array in the params hash > with a key of :list.Thanks Ezra. I see that that does indeed work. For the record, I think it is quite silly of rails to require empty square brackets just to know that it''s got an array. Seems like someone was thinking PHP when they decided that. ;-) Speaking of which, I think this wiki page is out of date: http://wiki.rubyonrails.org/rails/pages/UnderstandingRequestParameters#fn1 "That this works seems only logical, because in PHP array[] syntax is used to push new elements to an array. However, this is not possible in Rails, so you?ll have to improvize by inputting arrays with explicit indices. Although it must be admitted that the PHP notation is very convenient, you can do the same thing and more with explicit indices in Rails." b