views:

669

answers:

3

Hi

I'm building an app in CodeIgniter. I have an invoice form which uses jQuery to create new line items. The line items are formated as follows:

<input type="text" name="invoice[new_item_attributes][][description]" class="ui-corner-all text invDesc" title="Description" />
<input type="text" name="invoice[new_item_attributes][][qty]" class="ui-corner-all text invQty" title="Qty" />
<input type="text" name="invoice[new_item_attributes][][amount]" class="ui-corner-all text invAmount" title="Amount" onChange="CalculateTotal(this.form)" />
<input type="hidden" name="invoice[new_item_attributes][][rowTotal]" class="row-total-input" />

What I can't work out is how can I loop through multiple line items to store then in a DB called line items.

At the moment i have

foreach ( $_POST['invoice'] as $key => $value)
 {
  $data = array(
   'description' => $value;
     );
 }

But I know that can't be write because I need to somehow reference the *invoice[new_item_attributes][][description]* to store it in description etc...

Any help would be greatly appreciated.

+2  A: 

The correct solution will depend on whether you plan on storing scalar values under $_POST['invoice']['new_item_attributes'] or if you plan on making it an array of arrays (in other words, you plan on having multiples of the new_item_attributes.

If you only plan on storing scalar values then you'll first need to change each of the form elements to look like this:

name="inovoice[new_item_attributes][description]"

You'll notice that the empty [] is gone.

And then your loop should look like so:

foreach($_POST['invoice']['new_item_attributes'] as $key => $val) {
    $data = array('description => $value);
}

Otherwise you'll need to use this in your PHP code:

foreach($_POST['invoice']['new_item_attributes'] as $key => $val) {
         $data = array('description' => $val['description']);
}

Or:

foreach($_POST['invoice']['new_item_attributes'] as $key => $val) {
     foreach($val as $sub => $value) {
         $data = array($sub => $value);
     }
}
Noah Goodrich
Thanks Gabriel I'll give it a shot.
Tristan
A: 

My loop looks like this:

    foreach ( $_POST['invoice']['new_item_attributes'] as $key => $val ) 
   {
    $data = array(
     'description' => $val['description'],
     'qty'   => $val['qty'],
     'amount'  => $val['amount'],
     'rowTotal'  => $val['rowTotal'],
     'client_id'  => $_POST['client'],
     'company_id' => $this->session->userdata('companyID'),
     'invoice_id' => $row['id'],
       );
    $this->db->insert('line_items', $data);   
   }

However storing each line item into the line_items table doesn't work to well. If I enter 1 line item in I get 4 entries stored in the table, and they don't seem to reflect the information inputted.

Tristan
+1  A: 

Using array append always increments the array index on assignment whether you do it in PHP or in an HTML form, so you'll end up with this:

invoice[new_item_attributes][0][description]
invoice[new_item_attributes][1][qty]
invoice[new_item_attributes][2][amount]
invoice[new_item_attributes][3][rowTotal]

If you switch your field names around so it's invoice[new_item_attributes][description][], etc, then your submitted data will look like this:

invoice[new_item_attributes][description][0]
invoice[new_item_attributes][qty][0]
invoice[new_item_attributes][amount][0]
invoice[new_item_attributes][rowTotal][0]

Which is closer to what you're after, now the fields have indexes corresponding to their line item. It won't work with your existing foreach loop, however:

$items = array();
foreach ($invoice['new_item_attributes']['description'] as $key => $val) {
    $items[] = array('description' => $val,
                     'qty' => $invoice['new_item_attributes']['qty'][$key],
                     'amount' => $invoice['new_item_attributes']['amount'][$key],
                     'rowTotal' => $invoice['new_item_attributes']['rowTotal'][$key],
    );
}

will make an array $items of your form submission that you can easily manipulate in the way you were originally expecting.

scribble
thansk scribble i'll try that
Tristan
I have added the [] to hte inputs but now when I try to access them using $val['description'] etc...
Tristan
You could foreach though [description] and use $key to refer to the corresponding line items in the other three field arrays.
scribble
Updated my answer with an example of what I mean.
scribble
That worked. Thanks!
Tristan