Having some trouble with loop in a form

Hello,

I'm clearly missing some bit of code, but I can't figure out what. There are three models: Invoice, Lineitems and items. I want the user to search a list of items, and then add them to the lineitems table. The seach works, an provides a list on this form:

<% form_for :lineitems, :url => {:action => 'create', :id=> @invoice.id} do |f|-%>   <table>

    <% @items.each do |item| %>

    <tr>       <td><%=item.itemname %></td> <%= f.hidden_field :item_id, :value=>item.id %>       <td><%= f.text_field :quantity %></td>       <td><%= f.text_field :price, :value => item.sellprice %></td>

      <td><%= f.submit 'Add Item' %> </td>     </tr>       <% end %>

When you click 'Add Item', it submits for that last item on the list, not the corresponding item.

Controller code for create is: @invoice = Invoice.find(params[:id])

@lineitems = @invoice.lineitems.new(params[:lineitems])

Hello,

I'm clearly missing some bit of code, but I can't figure out what. There are three models: Invoice, Lineitems and items. I want the user to search a list of items, and then add them to the lineitems table. The seach works, an provides a list on this form:

<% form_for :lineitems, :url => {:action => 'create', :id=> @invoice.id} do |f|-%> <table>

&lt;% @items\.each do |item| %&gt;

&lt;tr&gt;
  &lt;td&gt;&lt;%=item\.itemname %&gt;&lt;/td&gt; &lt;%=

f.hidden_field :item_id, :value=>item.id %> <td><%= f.text_field :quantity %></td> <td><%= f.text_field :price, :value => item.sellprice %></td>

  &lt;td&gt;&lt;%= f\.submit &#39;Add Item&#39; %&gt; &lt;/td&gt;
&lt;/tr&gt;
  &lt;% end %&gt;

When you click 'Add Item', it submits for that last item on the list, not the corresponding item.

Well you've only got one form, so when you hit submit all of the item_id, quantity and price parameters are submitted and in this case when faced with a repeated parameter rails picks the last one. The browser doesn't know that because you've hit the submit button for one row you only want to submit those fields that are close to it.

Fred

Hello,

I'm clearly missing some bit of code, but I can't figure out what. There are three models: Invoice, Lineitems and items. I want the user to search a list of items, and then add them to the lineitems table. The seach works, an provides a list on this form:

<% form_for :lineitems, :url => {:action => 'create', :id=> @invoice.id} do |f|-%> <table>

<% @items.each do |item| %>

<tr> <td><%=item.itemname %></td> <%= f.hidden_field :item_id, :value=>item.id %>

Probably nothing to do with your problem but I believe that input fields (hidden or not) are not allowed between td elements. To check, view the source of the page in the browser and cut and paste the whole thing into the html validation service at The W3C Markup Validation Service. It may work ok as you have it in one browser but not another. I imagine you can put it inside the cell.

Colin

Hello,

Thanks for all the replies. I've used this format before in .Net using a datagrid, but I'm tring to apply it to RoR. Fred, if the issue is repeated parameter in a single form, am I best off attempting to add 'fields_for' to the form, or is there a way to make every row iterate on multiple forms, like placing @item.each do outside the form (I would assume this would not work.) Thanks Colin, once I get a functional page, I'll validate it.

max

Creating valid markup, as well as valid code, is how you *get to* a "functional page" -- it's not an afterthought.

Are you saying you do not check that it is valid afterwards? A page can appear to be functional even with invalid markup so I always check mine after it appears to work just in case I have made a mistake.

Colin

"After" what?

Validation, just like running unit tests, needs to be done throughout development, as part of each iteration/refactoring.

Again, thanks for the replies.

I never said I don’t do it. But my issue doesn’t work with any browser at the moment, and even if I eliminate all the td elements (or the entire table), the same problem persists. The problem is in the ruby code, not the markup html yet, which is why I elect to do it after I have the ruby working.

if I take out the html for the table and submit the code for the view like this:

<% form_for :lineitems, :url => {:action => ‘create’, :id=> @invoice.id} do |f|-%>

<% @items.each do |item| %>

<%=item.itemname %> <%= f.hidden_field :item_id, :value=>item.id %> <%= f.text_field :quantitydelivered %>

  <%= f.text_field :price, :value => item.sellprice %>

<%= f.submit 'Add Item' %> 
  <% end %>

<% end %>

I still get the same issue as the original inquiry. As for how to get a button to submit a line data, I’m still waiting for anyone who has an idea, direction of where I’ve gone wrong or even source code I could take a look at.

Creating valid markup, as well as valid code, is how you *get to* a "functional page" -- it's not an afterthought.

Are you saying you do not check that it is valid afterwards?

"After" what?

After it appears to be functional.

Validation, just like running unit tests, needs to be done throughout development, as part of each iteration/refactoring.

Obviously, each time it is modified and appears to be functional again then re-validate. There is no point validating it before it is functional (unless not sure why it is not functional of course in which case validating it is useful).

Colin

Exactly my point. It is totally possible for invalid markup, particularly involving forms (as well as JavaScript), to *prevent* the page from being "functional".

Ignoring a failing validation is just like ignoring a failing unit test. You should fix it *now* and move on.

# And apologies to the OP for the thread semi-hijack :slight_smile:

Apology accepted, but ultimately didn't this become an issue of 'my coding process is better than your coding process'?

Anyway, playing around with it, I got it to work, so in the hope that months from now, someone will come across the same issue, here is the working answer. It was simple, and for some reason I thought I had tried it already and clearly hadn't, but you actually do seperate each iteration into a seperate form.

<% @items.each do |item| %> <% form_for :lineitems, :url => {:action => 'create', :id=> @invoice.id} do |f|-%>

<%=item.itemname %> <%= f.hidden_field :item_id, :value=>item.id %>       <%= f.text_field :quantity %>       <%= f.text_field :price, :value => item.sellprice %>

    <%= f.submit 'Add Item' %> <br/>       <% end %>

  <% end %>

Does what I need it to do, though if this can be done as one form, I'd be interested to see the code :slight_smile:

... There is no point validating it before it is functional (unless not sure why it is not functional of course in which case validating it is useful).

Exactly my point. It is totally possible for invalid markup, particularly involving forms (as well as JavaScript), to *prevent* the page from being "functional".

Ignoring a failing validation is just like ignoring a failing unit test. You should fix it *now* and move on.

I never suggested anything else. I don't know why we are having this discussion really, I pretty much agree with everything you have said.

Colin

I guess you should not use f.submit for “Add item”, instead you should use a link and a corresponding action which will add an item and render lineitem form again.

Thanks, Abhinav

Your submit button is within the @items.each loop, hence I see that for each row there is an ‘Add Item’ button.

There should be only 1 submit button in the end (if you want to submit the entire form)

Thanks & Regards, Dhruva Sagar.

Joan Crawford - “I, Joan Crawford, I believe in the dollar. Everything I earn, I spend.”