Now is a perfect time to learn!  jQuery can make this task a bit less
daunting.  Here is one approach (the basic idea).

Let's pretend your form looks something like this:

<form ... >
  <div class="form_container">
    <div class="original_invoice_row">
      <input name="invoices[][title] type="text" />
      <input name="invoices[][amount] type="text" />
      ... etc ...
    </div>
  </div>
</form>

I *think* that is the correct way to create a collection using HTML (the
name invoices[][<some attribute>]).

So you would say, "Javascript, find me all of the inputs inside of div with
a class name that equals "original_invoice_row".  Then fetch all of the
relevant values from those inputs.  Then insert a new div, with the new row
of input elements, and copy the relevant values over to that new row."

jQuery makes this task much less painful.

$('.original_invoice_row input') // jQuery selector to find all of the
input elements inside of the div with a class name of "original_invoice_row

Then you can iterate over this collection (jQuery can make this easier
also), and fetch the appropriate values.  Then use jQuery again and crate a
new div with inputs that have names like "invoices[][amount]" and plug in
the values that you have fetched.  Lastly, I believe jQuery has an "append"
method that will insert this new div at the end of a container (our
"form_container" element from our example).

I do not consider myself to be a JS wizard, but hopefully that gives you at
least one idea of how you might tackle it.


On Tue, Feb 5, 2013 at 10:53 AM, KT <[email protected]> wrote:

> Yes, exactly!  But I don't know JS....  :(
>
>
> On Tuesday, February 5, 2013 10:46:57 AM UTC-8, Benjamin Wanicur wrote:
>
>> If we are correct in assuming the @invoice object here is a result of
>> @invoice = Invoice.new, then another option for creating multiple,
>> identical invoice objects from a form row is to use some javascript. You
>> could write a JS function that would take the values from the initial "form
>> row" and duplicate them into a second form row (and so on... creating many
>> duplicate rows).  You would end up with a form containing data for many
>> Invoice objects.  In your ruby code you would need the #create method to
>> deal with a collection of objects rather than just a single object.
>>
>>
>> On Tue, Feb 5, 2013 at 9:35 AM, Jason King <[email protected]> wrote:
>>
>>> Start with the simple case, where they create an new invoice from
>>> scratch.  In the `new` action (which is the action that displays the empty
>>> form to start with) you'll have something like @invoice = Invoice.new to
>>> pre-populate an @invoice object so that `form_for` in your view works.
>>>
>>> Then, once that's working, with the `create` action also working, add a
>>> new checkbox (or maybe a second submit button, up to you) to your form,
>>> something like "Create another like this one".  Then in your `create`
>>> action that receives your invoice you want to check for that checkbox and
>>> if it exists then once you've saved your invoice you're going to set 
>>> @invoice
>>> = @invoice.dup and then render :new which will display that same form,
>>> this time with all the fields from the invoice that was just submitted.
>>>  Note that when that checkbox is checked you will need to `render` and not
>>> `redirect_to` - that's the only trick here really
>>>
>>> On Tue, Feb 5, 2013 at 7:59 AM, KT <[email protected]> wrote:
>>>
>>>> Correct - the issue is that I need to create the first invoice first,
>>>> then duplicate it as many times as needed - like an Excel row.  So, can I
>>>> do that all in one form or must I first save a record, then dup it?
>>>> Basically, the users need to create a bunch of invoices at the same time
>>>> and to eliminate having to enter the same info over and over, just copy the
>>>> row above and change a couple attributes.... just like Excel.
>>>>
>>>> I'm stuck.
>>>>
>>>>
>>>> On Thursday, January 31, 2013 4:48:26 PM UTC-8, Jason King wrote:
>>>>
>>>>> My understanding is that that's what ActiveRecord::Base#dup does.
>>>>>
>>>>>  Based on the error you're getting KT I'd actually guess that the
>>>>> problem here is that the initial @invoice that's used in the form_for
>>>>> doesn't have an id, which means that Invoice.find(params[:id]) is being
>>>>> called with a nil id, which generates the "Couldn't find an invoice
>>>>> without an ID" error that you're getting.
>>>>>
>>>>> So, how are you setting that @invoice in the controller action that *
>>>>> displays* the form?
>>>>>
>>>>>
>>>>> On Thu, Jan 31, 2013 at 3:42 PM, Robert Kaufman <[email protected]>wrote:
>>>>>
>>>>>> Hi KT,
>>>>>>   The problem is that Rails automatically decides whether you are
>>>>>> updating or creating a new record based on whether your instance 
>>>>>> (@invoice
>>>>>> in this case) things it is a new record or not.  The memory dup you are
>>>>>> making thinks it is an existing record, even though its id is blank.
>>>>>>  Changing your controller action to something like this should do the 
>>>>>> trick:
>>>>>>
>>>>>> def clone_invoice
>>>>>>   invoice = Invoice.find(params[:id])
>>>>>>   new_invoice = Invoice.new(invoice.**attributes**.merge('id' =>
>>>>>> nil))
>>>>>> end
>>>>>>
>>>>>>
>>>>>> Note, I removed your @ variables, since we're really only using them
>>>>>> inside of this method.  It would be even better to have a make_clone 
>>>>>> method
>>>>>> in your model which you would just call on the original invoice object
>>>>>> (that's just a little more OO).
>>>>>>
>>>>>> Best,
>>>>>> Rob
>>>>>>
>>>>>> On Jan 31, 2013, at 2:05 PM, KT <[email protected]> wrote:
>>>>>>
>>>>>>  Hi all!  I was hoping someone could help me with another issue...
>>>>>>
>>>>>> I have an INVOICE form.  Users would like to create multiple records
>>>>>> at the same time.  In addition, they would like to copy the first 
>>>>>> record's
>>>>>> attributes for the next record, so they only have to change a few fields.
>>>>>> Less typing.  MS Excel style.
>>>>>>
>>>>>> I've seen the Railscast for adding multiple records through nested
>>>>>> attributes, but I'm using a single model, so I don't know how that
>>>>>> applies.  I do not want to break out my flat invoice table if I can avoid
>>>>>> it.
>>>>>>
>>>>>> I've tried the following, but when I click on "Add Invoice", I get an
>>>>>> error: "Couldn't find an invoice without an ID".
>>>>>>
>>>>>> _form.html.erb:
>>>>>>
>>>>>> <% form_for @invoice, :html => { :multipart => true } do |f| %>
>>>>>>
>>>>>> <table class="ExcelTable2007">
>>>>>>      <tr>
>>>>>>        <th class="heading">PO #<font color="red"> *</font></th>
>>>>>>        <th class="heading">Invoice #<font color="red"> *</font></th>
>>>>>>        <th class="heading">"Bill To" is Correct</th>
>>>>>>        <th class="heading">Invoice Date<font color="red">
>>>>>> *</font></th>
>>>>>>        <th class="heading">Date Received<font color="red">
>>>>>> *</font></th>
>>>>>>        <th class="heading">AP Clerk Note<font color="red">
>>>>>> *</font></th>
>>>>>>        <th class="heading">Division<font color="red"> *</font></th>
>>>>>>        <th class="heading">GR Approver<font color="red"> *</font></th>
>>>>>>        <th class="heading">Invoice Attachment<font color="red">
>>>>>> *</font></th>
>>>>>>      </tr>
>>>>>>      <tr>
>>>>>>        <td class="heading"><%= f.text_field :po_number, :size => 10
>>>>>> %></td>
>>>>>>        <td class="heading"><%= f.text_field :invoice_number, :size =>
>>>>>> 10 %></td>
>>>>>>        <td class="heading"><%= f.check_box :bill_to_address %></td>
>>>>>>        <td class="heading"><%= f.calendar_date_select "invoice_date",
>>>>>> :time => false, :size => 12 %></td>
>>>>>>        <td class="heading"><%= f.calendar_date_select
>>>>>> "date_received", :time => false, :size => 12 %></td>
>>>>>>        <td class="heading"><%= f.text_field :clerk_note %></td>
>>>>>>        <td class="heading"><%= f.collection_select :division_id,
>>>>>> Division.active.order(:**divisio**n), :id, :division, :include_blank
>>>>>> => true %></td>
>>>>>>        <td class="heading"><%= f.collection_select
>>>>>> :approver_username, Aduser.order(:last_name, :first_name), :username,
>>>>>> :fullname, :include_blank => true %></td>
>>>>>>        <td class="heading"><%= f.file_field :attachment %></td>
>>>>>>       </tr>
>>>>>>     </p>
>>>>>> </table>
>>>>>> &emsp;&emsp;&emsp;&emsp;<%= link_to "Add Invoice",
>>>>>> clone_invoice_url(@invoice) %>
>>>>>>   <br>
>>>>>>   <br>
>>>>>>
>>>>>>   <div class="actions">
>>>>>>     <%= f.submit "Submit" %>
>>>>>>   </div>
>>>>>>   </p>
>>>>>> <% end %>
>>>>>>
>>>>>> ------------------------------****---------------
>>>>>>
>>>>>> invoices_controller:
>>>>>>
>>>>>> def clone_invoice
>>>>>>   @invoice = Invoice.find(params[:id])
>>>>>>   @new_invoice = @invoice.dup
>>>>>> end
>>>>>>
>>>>>> --
>>>>>> --
>>>>>> SD Ruby mailing list
>>>>>> [email protected]
>>>>>>
>>>>>> http://groups.google.com/**group**/sdruby<http://groups.google.com/group/sdruby>
>>>>>> ---
>>>>>> You received this message because you are subscribed to the Google
>>>>>> Groups "SD Ruby" group.
>>>>>> To unsubscribe from this group and stop receiving emails from it,
>>>>>> send an email to sdruby+un...@**googlegroups.com.
>>>>>>
>>>>>> For more options, visit 
>>>>>> https://groups.google.com/**grou**ps/opt_out<https://groups.google.com/groups/opt_out>
>>>>>> .
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>  --
>>>>>> --
>>>>>> SD Ruby mailing list
>>>>>> [email protected]
>>>>>>
>>>>>> http://groups.google.com/**group**/sdruby<http://groups.google.com/group/sdruby>
>>>>>> ---
>>>>>> You received this message because you are subscribed to the Google
>>>>>> Groups "SD Ruby" group.
>>>>>> To unsubscribe from this group and stop receiving emails from it,
>>>>>> send an email to sdruby+un...@**googlegroups.com.
>>>>>>
>>>>>> For more options, visit 
>>>>>> https://groups.google.com/**grou**ps/opt_out<https://groups.google.com/groups/opt_out>
>>>>>> .
>>>>>>
>>>>>>
>>>>>>
>>>>>
>>>>>  --
>>>> --
>>>> SD Ruby mailing list
>>>> [email protected]
>>>> http://groups.google.com/**group/sdruby<http://groups.google.com/group/sdruby>
>>>> ---
>>>> You received this message because you are subscribed to the Google
>>>> Groups "SD Ruby" group.
>>>> To unsubscribe from this group and stop receiving emails from it, send
>>>> an email to sdruby+un...@**googlegroups.com.
>>>> For more options, visit 
>>>> https://groups.google.com/**groups/opt_out<https://groups.google.com/groups/opt_out>
>>>> .
>>>>
>>>>
>>>>
>>>
>>>  --
>>> --
>>> SD Ruby mailing list
>>> [email protected]
>>> http://groups.google.com/**group/sdruby<http://groups.google.com/group/sdruby>
>>> ---
>>> You received this message because you are subscribed to the Google
>>> Groups "SD Ruby" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to sdruby+un...@**googlegroups.com.
>>> For more options, visit 
>>> https://groups.google.com/**groups/opt_out<https://groups.google.com/groups/opt_out>
>>> .
>>>
>>>
>>>
>>
>>  --
> --
> SD Ruby mailing list
> [email protected]
> http://groups.google.com/group/sdruby
> ---
> You received this message because you are subscribed to the Google Groups
> "SD Ruby" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/groups/opt_out.
>
>
>

-- 
-- 
SD Ruby mailing list
[email protected]
http://groups.google.com/group/sdruby
--- 
You received this message because you are subscribed to the Google Groups "SD 
Ruby" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to