Answers.Body: <p>You shouldn't JSON-encode the table field values; Craft handles that internally. Simply give it a multi-dimensional array.</p>
  <p>The below would save one row with two columns to the table field <code>itemEvents</code>, belonging to an element <code>$match</code>:</p>
  <pre class="lang-php prettyprint-override"><code>$itemsTable = [[
      'col1' =&gt; $itemType,
      'col2' =&gt; $itemTime,
  ]];
  
  $match-&gt;setFieldValue('itemEvents', $itemsTable);
  
  ...
  
  \Craft::$app-&gt;getElements()-&gt;saveElement($match);
  </code></pre>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-15T01:38:44.580Z
Answers.Text: Thanks for this one too! I saw some other answers saying it needed to be JSON-encoded, thanks for clarifying. I have a question about the last line of saving the element; I'm using `Event::on(Entry::class,Element::EVENT_BEFORE_SAVE,` (and have tried `EVENT_AFTER_SAVE` too) for this and it seems to create an infinite loop. Any advice on how to do that properly?
Answers.UserDisplayName: supazu
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-15T13:59:51.637Z
Answers.Text: @brynli64 Right, you shouldn't explicitly save the entry (using `\Craft::$app->getElements->saveElement()` in an `EVENT_BEFORE_SAVE` or `EVENT_AFTER_SAVE` event handler. In this case, you probably want to use the `EVENT_BEFORE_SAVE` event handler, and just `$match->setFieldValue('itemEvents', $itemsTable);` inside that (assuming `$match` is the entry being saved). The complicating factor is that the source for your table is in a Matrix block; I'm not sure if that data is even available before the entry has been saved (Matrix blocks are saved as separate elements).
Answers.UserDisplayName: Mats Mikkel Rummelhoff
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-17T06:11:17.183Z
Answers.Text: Thanks for the info! I'll look into that a bit more then.
Answers.UserDisplayName: supazu
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-17T06:20:36.523Z
Answers.Text: So it's actually working with `EVENT_BEFORE_SAVE` now, however, it's only adding one row (presumably it's going throw each row and overwriting the previous one.) Any thoughts on how I can just add a row, rather than resave the whole table? Apologies for the trouble, I appreciate your help!
Answers.UserDisplayName: supazu
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-17T08:33:25.087Z
Answers.Text: @brynli64 Great! The table field returns an array, so if you want to add new rows without overwriting existing data, you'll need to push or merge the new rows to the array the field returns. I.e. something like `$match->setFieldValue('itemEvents', array_merge($match->itemEvents ?? [], $itemsTable));`
Answers.UserDisplayName: Mats Mikkel Rummelhoff
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-17T12:19:22.757Z
Answers.Text: Brilliant - I think that's done it! Thank you!
Answers.UserDisplayName: supazu
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2023-01-14T20:48:39.150Z
Answers.LastActivityDate: 2023-01-14T20:48:39.150Z
Answers.UserDisplayName: Mats Mikkel Rummelhoff
Body: <p>I'm having some trouble adding a row to a table field programmatically. I'm iterating over a table inside a Matrix field and would like to save those values to another table (if that makes sense.)</p>
  <pre><code>foreach ($blocks as $block) {
      $items = $block-&gt;items;
      foreach ($items as $item) {
          $itemType = $itemEvents['type'];
          $itemTime = $itemEvents['time'];
          $itemsTable = array(
              array(
                  'col2' =&gt; $itemType,
                  'col3' =&gt; $itemTime,
              )
          );
      }
      
      ## I understand this is wrong, but this is what I want to do:
      $match-&gt;setFieldValue('itemEvents', json_encode($itemsTable));
  }
  </code></pre>
  <p>Can anyone help with the last part of actually updating the <code>itemEvents</code> table field/adding a row to it?</p>
  
Tags: <modules><table-field>
Title: Add rows to table field
ThreadText: # Add rows to table field
  
  (Asked by: username_0 on 2023-01-14)
  
  I'm having some trouble adding a row to a table field programmatically. I'm iterating over a table inside a Matrix field and would like to save those values to another table (if that makes sense.)
  
  ```
  foreach ($blocks as $block) {
      $items = $block->items;
      foreach ($items as $item) {
          $itemType = $itemEvents['type'];
          $itemTime = $itemEvents['time'];
          $itemsTable = array(
              array(
                  'col2' => $itemType,
                  'col3' => $itemTime,
              )
          );
      }
      
      ## I understand this is wrong, but this is what I want to do:
      $match->setFieldValue('itemEvents', json_encode($itemsTable));
  }
  
  ```
  
  Can anyone help with the last part of actually updating the `itemEvents` table field/adding a row to it?
  
  **Tags:** modules, table-field
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2023-01-14. Score: 2 | Accepted answer
  
  You shouldn't JSON-encode the table field values; Craft handles that internally. Simply give it a multi-dimensional array.
  
  The below would save one row with two columns to the table field `itemEvents`, belonging to an element `$match`:
  
  ```php
  $itemsTable = [[
      'col1' => $itemType,
      'col2' => $itemTime,
  ]];
  
  $match->setFieldValue('itemEvents', $itemsTable);
  
  ...
  
  \Craft::$app->getElements()->saveElement($match);
  
  ```
  
  > **Comments:**
  > **username_0**: Thanks for this one too! I saw some other answers saying it needed to be JSON-encoded, thanks for clarifying. I have a question about the last line of saving the element; I'm using `Event::on(Entry::class,Element::EVENT_BEFORE_SAVE,` (and have tried `EVENT_AFTER_SAVE` too) for this and it seems to create an infinite loop. Any advice on how to do that properly?  
  > **username_1**: @brynli64 Right, you shouldn't explicitly save the entry (using `\Craft::$app->getElements->saveElement()` in an `EVENT_BEFORE_SAVE` or `EVENT_AFTER_SAVE` event handler. In this case, you probably want to use the `EVENT_BEFORE_SAVE` event handler, and just `$match->setFieldValue('itemEvents', $itemsTable);` inside that (assuming `$match` is the entry being saved). The complicating factor is that the source for your table is in a Matrix block; I'm not sure if that data is even available before the entry has been saved (Matrix blocks are saved as separate elements).  
  > **username_0**: Thanks for the info! I'll look into that a bit more then.  
  > **username_0**: So it's actually working with `EVENT_BEFORE_SAVE` now, however, it's only adding one row (presumably it's going throw each row and overwriting the previous one.) Any thoughts on how I can just add a row, rather than resave the whole table? Apologies for the trouble, I appreciate your help!  
  > **username_1**: @brynli64 Great! The table field returns an array, so if you want to add new rows without overwriting existing data, you'll need to push or merge the new rows to the array the field returns. I.e. something like `$match->setFieldValue('itemEvents', array_merge($match->itemEvents ?? [], $itemsTable));`  
  > **username_0**: Brilliant - I think that's done it! Thank you!  
  
  ---
  
  