naroor rathish
2005-Dec-15 11:34 UTC
Adding multiple invoice items to an invoice on the same form
Hi Friends , Got a unique requirement .I am designing a invoice printing system .So right now I have the NEW page for adding the invoice details to the table .Now I have the requirement of adding Invoice Items In the same form .I have added multiple text boxes to enter the values of the Items using <%= text_field ''invoiceitems[]'', ''item_price'' %> <%= text_field ''invoiceitems[]'', ''item_qty'' %> etc. How can I save the multiple items in the same form .I have to insert the invoice details and the invoice items on the same button click. Waiting for the comments and suggestions , Thanx and regards, Naroor Rathish, www.naroor.blogspot.com -- Posted via http://www.ruby-forum.com/.
Andrew Filipowski
2005-Dec-15 12:43 UTC
Re: Adding multiple invoice items to an invoice on the same form
Not an expert but I will take a shot here. The form looks right to me however I did things a little different. I used different names for each field type (so that I had different arrays returned to the server) and than did a loop through the array by something like this: 0.upto.(params[invoiceprice].length - 1) do |x| invoice << Invoice.new(:invoiceprice => params[:invoiceprice][x], :invoiceqty => params[invoiceqty][x]) end I am doing something slimilar however I used text_field_tag and various other _tag helpers in my view because my form was dynamically created and I felt that I could not use the non tag fields due to the fact that I have no preexisting knowledge of what the form is going to look like. Hope this helps, if I did something wrong here would love to be corrected as well but it seems to work may not be the most DRY way to do it. Andrew On Dec 15, 2005, at 6:34 AM, naroor rathish wrote:> Hi Friends , > Got a unique requirement .I am designing a invoice printing > system > .So right now I have the NEW page for adding the invoice details to > the > table .Now I have the requirement of adding Invoice Items In the same > form .I have added multiple text boxes to enter the values of the > Items > using > <%= text_field ''invoiceitems[]'', ''item_price'' %> > <%= text_field ''invoiceitems[]'', ''item_qty'' %> etc. > > How can I save the multiple items in the same form .I have to > insert the > invoice details and the invoice items on the same button click. > > Waiting for the comments and suggestions , > > Thanx and regards, > Naroor Rathish, > www.naroor.blogspot.com > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails
Wilson Bilkovich
2005-Dec-15 14:48 UTC
Re: Adding multiple invoice items to an invoice on the same form
On 12/15/05, naroor rathish <hi_naroor-/E1597aS9LQAvxtiuMwx3w@public.gmane.org> wrote:> Hi Friends , > Got a unique requirement .I am designing a invoice printing system > .So right now I have the NEW page for adding the invoice details to the > table .Now I have the requirement of adding Invoice Items In the same > form .I have added multiple text boxes to enter the values of the Items > using > <%= text_field ''invoiceitems[]'', ''item_price'' %> > <%= text_field ''invoiceitems[]'', ''item_qty'' %> etc. > > How can I save the multiple items in the same form .I have to insert the > invoice details and the invoice items on the same button click. >One way would be to move the text fields you want generated to a partial. Let''s pretend it''s called _invoiceitem.rhtml Then, in your RHTML file, where you currently have those text_field statements.. # Assuming @invoice_items is an Enumerable containing the AR objects you want to work with. <%= render(:partial => ''invoiceitem'', :collection => @invoice_items) %> _invoiceitem.rhtml would look something like: (First line is important, if you want to use the form helpers.) <% @invoiceitem = invoiceitem -%> <%= text_field ''invoiceitem'', ''item_price'', ''index'' => invoiceitem_counter %> <%= text_field ''invoiceitem'', ''item_qty'', ''index'' => invoiceitem_counter %> # And so on, for the various attributes you want to display. # nameofpartial_counter is a local variable created for you that keeps track of the index. In the controller action that your form submits to, you''d do something like: @items = [] params[:invoiceitem].each do |key, item| @items << InvoiceItem.new(item) end Now you''ve got an array of all the invoice item objects, and you can do whatever you want with it.. maybe stuffing it in the session for later use, or calling ".valid?" on each entry and putting something in the flash if any of them aren''t correct, etc. Hopefully someone will come along and show a more elegant solution that I just don''t know about yet, but this is roughly how I do it. --Wilson.
Steve Koppelman
2005-Dec-15 19:05 UTC
Re: Adding multiple invoice items to an invoice on the same
I''ve been doing roughly the same thing, using the :index in each form field to pass an index for each line item. Since the same partial is going to get used for both new invoices and editing existing invoices, what you may want to do is name the variable that contains the :index value more generically so that when calling "new.rhtml" you pass :index that invoice_item counter''s value (3 rows? then pass it 1, 2, and 3 in a loop), and when you''re calling the partial from "edit.rhtml" you''re passing it invoice_item.id. You''ll have to go through a bit more contortion if you want to mix new lineitems with edits of old ones on the same edit form, obviously, since you''ll need a way for your update action to distinguish between the different purposes you''re using :index for. -- -sk Wilson Bilkovich wrote:> On 12/15/05, naroor rathish <hi_naroor-/E1597aS9LQAvxtiuMwx3w@public.gmane.org> wrote: >> invoice details and the invoice items on the same button click. >> > One way would be to move the text fields you want generated to a > partial. > Let''s pretend it''s called _invoiceitem.rhtml > Then, in your RHTML file, where you currently have those text_field > statements.. > # Assuming @invoice_items is an Enumerable containing the AR objects > you want to work with. > <%= render(:partial => ''invoiceitem'', :collection => @invoice_items) %> > > _invoiceitem.rhtml would look something like: (First line is > important, if you want to use the form helpers.) > <% @invoiceitem = invoiceitem -%> > <%= text_field ''invoiceitem'', ''item_price'', ''index'' => > invoiceitem_counter %> > <%= text_field ''invoiceitem'', ''item_qty'', ''index'' => invoiceitem_counter > %> > # And so on, for the various attributes you want to display. > # nameofpartial_counter is a local variable created for you that keeps > track of the index. > > In the controller action that your form submits to, you''d do something > like: > > @items = [] > params[:invoiceitem].each do |key, item| > @items << InvoiceItem.new(item) > end > > Now you''ve got an array of all the invoice item objects, and you can > do whatever you want with it.. maybe stuffing it in the session for > later use, or calling ".valid?" on each entry and putting something in > the flash if any of them aren''t correct, etc. > > Hopefully someone will come along and show a more elegant solution > that I just don''t know about yet, but this is roughly how I do it. > > --Wilson.-- Posted via http://www.ruby-forum.com/.
Naroor Rathish
2005-Dec-20 05:43 UTC
Re: Adding multiple invoice items to an invoice on the same
Hi Wilson , I was trying your code to be implemented in mine but some errors are coming . I added a partial :: <% @invoiceitem = invoiceitem -%> <%= text_field ''invoiceitem'', ''item_price'', ''index'' => invoiceitem_counter %> <%= text_field ''invoiceitem'', ''item_qty'', ''index'' => invoiceitem_counter %> Where are we initialising the counter? Please tell how is the first line working . In the rhtml file I have added : <%= form_remote_tag(:update => "my_list", :url => { :action => :add_new_item }, :position => "bottom" ) %> <%= submit_tag "Add New Item" %> <%= end_form_tag %> <form action="/ajax/save_items" method="post"> <ul id="my_list"> <li>Original item... please add more!</li> </ul> <%= submit_tag ''Update'' %> </form> I have added like this for creating a dynamic generation of text boxes using ajax. And in the controller class , def add_new_item render(:partial => ''invoiceitems'', :collection => @invoice_items) end def save_items @items = [] params[:invoiceitem].each do |key, item| @items = InvoiceItem.new(item) end end Please help my in implementing this requirement . Thanks and regards, Naroor Rathish. Wilson Bilkovich wrote:> On 12/15/05, naroor rathish <hi_naroor-/E1597aS9LQAvxtiuMwx3w@public.gmane.org> wrote: >> invoice details and the invoice items on the same button click. >> > One way would be to move the text fields you want generated to a > partial. > Let''s pretend it''s called _invoiceitem.rhtml > Then, in your RHTML file, where you currently have those text_field > statements.. > # Assuming @invoice_items is an Enumerable containing the AR objects > you want to work with. > <%= render(:partial => ''invoiceitem'', :collection => @invoice_items) %> > > _invoiceitem.rhtml would look something like: (First line is > important, if you want to use the form helpers.) > <% @invoiceitem = invoiceitem -%> > <%= text_field ''invoiceitem'', ''item_price'', ''index'' => > invoiceitem_counter %> > <%= text_field ''invoiceitem'', ''item_qty'', ''index'' => invoiceitem_counter > %> > # And so on, for the various attributes you want to display. > # nameofpartial_counter is a local variable created for you that keeps > track of the index. > > In the controller action that your form submits to, you''d do something > like: > > @items = [] > params[:invoiceitem].each do |key, item| > @items << InvoiceItem.new(item) > end > > Now you''ve got an array of all the invoice item objects, and you can > do whatever you want with it.. maybe stuffing it in the session for > later use, or calling ".valid?" on each entry and putting something in > the flash if any of them aren''t correct, etc. > > Hopefully someone will come along and show a more elegant solution > that I just don''t know about yet, but this is roughly how I do it. > > --Wilson.-- Posted via http://www.ruby-forum.com/.
Wilson Bilkovich
2005-Dec-20 16:11 UTC
Re: Re: Adding multiple invoice items to an invoice on the same
When you render a partial by passing in a collection, the render() call automatically provides a counter object for you. It gives this object the name #{partialname}_counter.. In this case, invoiceitem_counter. The first line (@invoiceitem = invoiceitem) is necessary because there is no way in Ruby to ask a variable what its name is. To work around this, the Rails helpers (such as text_field) take the name of the object as a string (''invoiceitem''), and then use that when they need to access the object. The helpers, however, are coded to expect an instance variable. text_field(''blah'', ''blah_property'') requires that there be an instance variable @blah. When working with a collection, the objects are passed in as locals (invoiceitem), so we need to turn them into instance variables (@invoiceitem) before using helpers on them. The problem with your code, at first glance, seems to be that you''re not actually working with a collection. Your first partial call only has one item, and subsequent invoice items are added one at a time, via Ajax. This means that you need to keep track of the ''item count'' separately, probably via an instance variable in the controller. The Ajax action will need to increment that number by one when it fires, and you''ll use that number as the index of the next item to be added. Good luck, --Wilson. On 12/20/05, Naroor Rathish <hi_naroor-/E1597aS9LQAvxtiuMwx3w@public.gmane.org> wrote:> Hi Wilson , > I was trying your code to be implemented in mine but some errors are > coming . > I added a partial :: > <% @invoiceitem = invoiceitem -%> > <%= text_field ''invoiceitem'', ''item_price'', ''index'' => > invoiceitem_counter %> > <%= text_field ''invoiceitem'', ''item_qty'', ''index'' => > invoiceitem_counter > %> > Where are we initialising the counter? Please tell how is the first line > working . > > In the rhtml file I have added : > > <%= form_remote_tag(:update => "my_list", > :url => { :action => :add_new_item }, > :position => "bottom" ) %> > > <%= submit_tag "Add New Item" %> > <%= end_form_tag %> > <form action="/ajax/save_items" method="post"> > <ul id="my_list"> > <li>Original item... please add more!</li> > </ul> > > <%= submit_tag ''Update'' %> > </form> > I have added like this for creating a dynamic generation of text boxes > using ajax. > > And in the controller class , > > def add_new_item > > render(:partial => ''invoiceitems'', :collection => @invoice_items) > > end > def save_items > > @items = [] > params[:invoiceitem].each do |key, item| > @items = InvoiceItem.new(item) > end > end > > Please help my in implementing this requirement . > > Thanks and regards, > Naroor Rathish. > > > Wilson Bilkovich wrote: > > On 12/15/05, naroor rathish <hi_naroor-/E1597aS9LQAvxtiuMwx3w@public.gmane.org> wrote: > >> invoice details and the invoice items on the same button click. > >> > > One way would be to move the text fields you want generated to a > > partial. > > Let''s pretend it''s called _invoiceitem.rhtml > > Then, in your RHTML file, where you currently have those text_field > > statements.. > > # Assuming @invoice_items is an Enumerable containing the AR objects > > you want to work with. > > <%= render(:partial => ''invoiceitem'', :collection => @invoice_items) %> > > > > _invoiceitem.rhtml would look something like: (First line is > > important, if you want to use the form helpers.) > > <% @invoiceitem = invoiceitem -%> > > <%= text_field ''invoiceitem'', ''item_price'', ''index'' => > > invoiceitem_counter %> > > <%= text_field ''invoiceitem'', ''item_qty'', ''index'' => invoiceitem_counter > > %> > > # And so on, for the various attributes you want to display. > > # nameofpartial_counter is a local variable created for you that keeps > > track of the index. > > > > In the controller action that your form submits to, you''d do something > > like: > > > > @items = [] > > params[:invoiceitem].each do |key, item| > > @items << InvoiceItem.new(item) > > end > > > > Now you''ve got an array of all the invoice item objects, and you can > > do whatever you want with it.. maybe stuffing it in the session for > > later use, or calling ".valid?" on each entry and putting something in > > the flash if any of them aren''t correct, etc. > > > > Hopefully someone will come along and show a more elegant solution > > that I just don''t know about yet, but this is roughly how I do it. > > > > --Wilson. > > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
Naroor Rathish
2005-Dec-21 13:46 UTC
Re: Re: Adding multiple invoice items to an invoice on the s
Hi wilson, Got a strange error. NameError in Ajax#add_new_item Showing app/views/ajax/_invoiceitems.rhtml where line #2 raised: undefined local variable or method `invoiceitem'' for #<#<Class:0x3873970>:0x3873898> Extracted source (around line #2): 1: 2: <% @invoiceitem = invoiceitem %> 3: <%= text_field ''invoiceitem'', ''item_price'', ''index'' => invoiceitem_counter %> 4: <%= text_field ''invoiceitem'', ''item_qty'', ''index'' => invoiceitem_counter %> Request Parameters: {"commit"=>"Add", "_"=>""} Show session dump --- flash: !ruby/hash:ActionController::Flash::FlashHash {} Response Headers: {"cookie"=>[], "Cache-Control"=>"no-cache"} Can''t we use ajx with partials .Please let me know the result. Thanking you, Naroor Rathish -- Posted via http://www.ruby-forum.com/.
Wilson Bilkovich
2005-Dec-21 16:34 UTC
Re: Re: Re: Adding multiple invoice items to an invoice on the s
If your partial is named _invoiceitems.rhtml, the object will be ''invoiceitems'', not ''invoiceitem''. Take the ''s'' off the end of the filename, and you should be good. On 12/21/05, Naroor Rathish <hi_naroor-/E1597aS9LQAvxtiuMwx3w@public.gmane.org> wrote:> Hi wilson, > Got a strange error. > > NameError in Ajax#add_new_item > Showing app/views/ajax/_invoiceitems.rhtml where line #2 raised: > > undefined local variable or method `invoiceitem'' for > #<#<Class:0x3873970>:0x3873898> > > Extracted source (around line #2): > > 1: > 2: <% @invoiceitem = invoiceitem %> > 3: <%= text_field ''invoiceitem'', ''item_price'', ''index'' => > invoiceitem_counter %> > 4: <%= text_field ''invoiceitem'', ''item_qty'', ''index'' => > invoiceitem_counter %> > > Request > Parameters: {"commit"=>"Add", "_"=>""} > > Show session dump > > --- > flash: !ruby/hash:ActionController::Flash::FlashHash {} > Response > Headers: {"cookie"=>[], "Cache-Control"=>"no-cache"} > > > Can''t we use ajx with partials .Please let me know the result. > > Thanking you, > Naroor Rathish > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
Naroor Rathish
2005-Dec-22 08:17 UTC
Re: Re: Re: Adding multiple invoice items to an invoice on t
Hi Wilson, Thanx for the comments .That got cleared but final saving issues . The error is NameError in Ajax#save_items uninitialized constant Invoiceitem RAILS_ROOT: ./script/../config/.. Request Parameters: {"commit"=>"Update", "invoice"=>{"inv_number"=>"rest"}, "invoiceitem"=>{"1"=>{"item_price"=>"12", "item_qty"=>"12"}, "2"=>{"item_price"=>"13", "item_qty"=>"13"}}} The code I have written for saving is (i mean in the controller is ) def save_items @invoice = Invoice.new(params[:invoice]) params[:invoiceitem].each do |key, val| @invoice.invoiceitems << Invoiceitem.new(val) end end Calling the partial is like render(:partial => ''invoiceitems'', :collection => @invoiceitems ) In the partial I have given, <% $count = $count + 1 %> <% @invoiceitem = invoiceitems %> <%= text_field ''invoiceitem'', ''item_price'', ''index'' => $count %> <%= text_field ''invoiceitem'', ''item_qty'', ''index'' => $count %> <br> Please help me out. Thanx and regards, Naroor Rathish -- Posted via http://www.ruby-forum.com/.
Wilson Bilkovich
2005-Dec-22 15:36 UTC
Re: Re: Re: Re: Adding multiple invoice items to an invoice on t
@invoice.invoiceitems << Invoiceitem.new(val) ..should instead be: @invoice.invoice_items << InvoiceItem.new(val) On 12/22/05, Naroor Rathish <hi_naroor-/E1597aS9LQAvxtiuMwx3w@public.gmane.org> wrote:> Hi Wilson, > Thanx for the comments .That got cleared but final saving issues . > The error is > NameError in Ajax#save_items > uninitialized constant Invoiceitem > RAILS_ROOT: ./script/../config/.. > > Request > Parameters: {"commit"=>"Update", "invoice"=>{"inv_number"=>"rest"}, > "invoiceitem"=>{"1"=>{"item_price"=>"12", "item_qty"=>"12"}, > "2"=>{"item_price"=>"13", "item_qty"=>"13"}}} > > The code I have written for saving is (i mean in the controller is ) > > > def save_items > > @invoice = Invoice.new(params[:invoice]) > params[:invoiceitem].each do |key, val| > @invoice.invoiceitems << Invoiceitem.new(val) > end > end > > Calling the partial is like > render(:partial => ''invoiceitems'', :collection => @invoiceitems ) > > In the partial I have given, > <% $count = $count + 1 %> > <% @invoiceitem = invoiceitems %> > <%= text_field ''invoiceitem'', ''item_price'', ''index'' => $count %> > <%= text_field ''invoiceitem'', ''item_qty'', ''index'' => $count %> > <br> > > Please help me out. > Thanx and regards, > Naroor Rathish > > -- > Posted via http://www.ruby-forum.com/. > _______________________________________________ > Rails mailing list > Rails-1W37MKcQCpIf0INCOvqR/iCwEArCW2h5@public.gmane.org > http://lists.rubyonrails.org/mailman/listinfo/rails >
Naroor Rathish
2005-Dec-23 04:28 UTC
Re: Re: Re: Re: Adding multiple invoice items to an invoice
Hi Wilson , The same error NoMethodError in Ajax#save_items undefined method `invoice_items'' for #<Invoice:0x385a920> with Request Parameters: {"commit"=>"Update", "invoice"=>{"inv_number"=>"inv123"}, "invoiceitem"=>{"1"=>{"item_price"=>"12", "item_qty"=>"12"}, "2"=>{"item_price"=>"13", "item_qty"=>"13"}}} Should the name of the table be invoice_items ??Right now I have the name of the table as invoiceitems . Thanx, Naroor Rathish -- Posted via http://www.ruby-forum.com/.
Naroor Rathish
2005-Dec-23 09:46 UTC
Re: Re: Re: Re: Adding multiple invoice items to an invoice
Hi Wilson , The results I am getting in each variables are params[:invoice] = inv_number123 params[:invoiceitem] = 1item_priceprice1item_qtyqty12item_priceprice2item_qtyqty23item_priceprice3item_qtyqty3 Is the output correct when I dynamically added 3 rows with two columns for entering intem price and quantity . Regards, Naroor Rathish -- Posted via http://www.ruby-forum.com/.
Wilson Bilkovich
2005-Dec-23 18:27 UTC
Re: Re: Re: Re: Re: Adding multiple invoice items to an invoice
On 12/22/05, Naroor Rathish <hi_naroor-/E1597aS9LQAvxtiuMwx3w@public.gmane.org> wrote:> Hi Wilson , > The same error > NoMethodError in Ajax#save_items > undefined method `invoice_items'' for #<Invoice:0x385a920> > with > Request > Parameters: {"commit"=>"Update", "invoice"=>{"inv_number"=>"inv123"}, > "invoiceitem"=>{"1"=>{"item_price"=>"12", "item_qty"=>"12"}, > "2"=>{"item_price"=>"13", "item_qty"=>"13"}}} > > Should the name of the table be invoice_items ??Right now I have the > name of the table as invoiceitems . >Yeah, the table needs to be called invoice_items, or else you need to override the table with set_table_name in your model class. params[:invoiceitem] contains a Hash that has index numbers from the view as its keys, and hashes as values. Those hashes it contains use field names as their keys. e.g. items = params[:invoiceitem] second_item = items[:2] second_item is now a Hash with two keys.. :item_price and :item_qty second_item[:item_price] == ''13'' --Wilson.