<p>I would use a custom controller that requests the javascript data and then appends it to your table with a method like:</p>

<pre class="lang-php prettyprint-override"><code>public function appendDataToTable($entryId, $jsData) {
    $entry = \craft\elements\Entry::find()-&gt;id($entryId)-&gt;one();
    $tableValue   = $entry-&gt;getFieldValue( 'editableTableField' );
    $tableValue[] = [
        'col0' =&gt; $jsData,
    ];
    $entry-&gt;setFieldValue( 'editableTableField', $tableValue );
}
</code></pre>

<p>...if u need an example for the controller let me know, i am on the phone right now:</p>

CC BY-SA 4.0
2019-06-25T14:44:34.390Z
thanks for the response. I'd like to see an example if you don't mind. Wouldn't I still need to create the HTML via js so it's populated on the front-end once they click the button? also, i've added some code examples of how my flow works
Cat Named Dog
CC BY-SA 4.0
2019-06-25T16:16:46.930Z
I'm able to append data to the table now via a controller, but I'm confused about the JS. I'm not sure if I have to manually insert <tr> with the appropriate iteration from scratch. Then I wouldn't need to use a controller method since saving an entry will save whatever is in the table
Cat Named Dog
CC BY-SA 4.0
2019-06-25T09:24:41.440Z
2019-06-25T09:49:10.150Z
2019-06-25T09:49:10.150Z
HendrikEng
<p>I am making a custom field via a module.</p>

<p>I have an <code>editableTableField</code> that will hold the actual field values saved to an entry and I have other HTML elements that are used to grab data from a controller.</p>

<p>On button click, I need to take the data that is returned via my custom javascript and insert it into the table.</p>

<p>Is it possible to hook into the field and dynamically insert data into the field? Or do I have to create the html and manage the iterators and append it?</p>

<p>Here's an example of how I'm grabbing the data in JS</p>

<pre><code>      // add zips in state
      $('#fields-add-state-zips').on('click', function() {
         var ajaxdata = {
            area: 'state',
            state: $stateSelect.val()
         };

         getDataFromArea(ajaxdata, function(locationData) {
            console.log(locationData);
         });
      });

</code></pre>

<p>Which calls my controller route:</p>

<pre><code>    public function actionGetLocationsInArea() {
        $module = BulkAssignPostals::getInstance();

        $area = Craft::$app-&gt;request-&gt;post('area');

        $state = Craft::$app-&gt;request-&gt;post('state');
        $county = Craft::$app-&gt;request-&gt;post('county');
        $city = Craft::$app-&gt;request-&gt;post('city');
        $zip = Craft::$app-&gt;request-&gt;post('zip');

        $data = [];
        isset($state) ? $data['state'] = $state : $data['state'] = "";
        isset($county) ? $data['county'] = $county : $data['county'] = "";
        isset($city) ? $data['city'] = $city : $data['city'] = "";
        isset($zip) ? $data['zip'] = $zip : $data['zip'] = "";


        $res = Service::getLocationsInArea($area, $data);

        return json_encode($res);
    }
</code></pre>

<p>which calls my service</p>

<pre><code>    public static function getLocationsInArea($area, $data) {
        $locations = [];

        switch ($area) {
            case "state":
                if (isset($data['state'])) {
                    $state = $data['state'];
                    $locations = Model::getLocationsInState($state);
                }
                break;
            case "county":
                if (isset($data['state']) &amp;&amp; isset($data['county'])) {
                    $state = $data['state'];
                    $county = $data['county'];
                    $locations = Model::getLocationsInCounty($state, $county);
                }
                break;
            case "city":
                if (isset($data['state']) &amp;&amp; isset($data['county']) &amp;&amp; isset($data['city'])) {
                    $state = $data['state'];
                    $county = $data['county'];
                    $city = $data['city'];
                    $locations = Model::getLocationsInCity($state, $county, $city);
                }
                break;
            case "zip":
                if (isset($data['zip'])) {
                    $zip = $data['zip'];
                    $locations = Model::getLocationByZip($zip);
                }
                break;
            default:

        }

        return [
            'locations' =&gt; $locations
        ];
    }
</code></pre>

<p>which uses my model</p>

<pre><code>    public static function getLocationsInState($state) {
        return PostalLocations::find()
        -&gt;select('state_abbr,county,city,zip')
        -&gt;where(['state_abbr' =&gt; $state])
        -&gt;asArray()
        -&gt;all();
    }
</code></pre>

<p>Edit:</p>

<p>I've come up with some javascript, but it feels very hacky and I'm hoping theres a better way. perhaps some craft JS hook of sorts. I'm not sure.</p>

<p>Here's my JS</p>

<pre><code>     function addToTableField(rows) {

      $table = $('#fields-bulkAssignPostalsassignedPostals');
      $trCount = $table.find('tbody').find("tr").length - 0;

      rows.locations.forEach(function(row) {
         $table.find('tbody').append(
            $('&lt;tr&gt;&lt;/tr&gt;').attr('data-id', $trCount)
         );

         for (var key in row) {
            $table.find('tr[data-id='+$trCount+']').append(
               $('&lt;td&gt;&lt;/td&gt;').attr('class', 'textual').append(
                  $("&lt;textarea&gt;&lt;/textarea&gt;").attr('name', 'fields[bulkAssignPostals][assignedLocations]['+$trCount+']['+key+']').html(row[key])
               )

            );

         }
         $table.find('tr[data-id='+$trCount+']').append(
            '&lt;td class="thin action"&gt;&lt;a class="move icon" title="Reorder"&gt;&lt;/a&gt;&lt;/td&gt;',
            '&lt;td class="thin action"&gt;&lt;a class="delete icon" title="Delete"&gt;&lt;/a&gt;&lt;/td&gt;'
         );

         $trCount++;

      });


   }
</code></pre>

<field><custom-field><modules>
Add rows to editableTableField via custom javascript
# Add rows to editableTableField via custom javascript

(Asked by: username_0 on 2019-06-24)

I am making a custom field via a module.
I have an editableTableField that will hold the actual field values saved to an entry and I have other HTML elements that are used to grab data from a controller.
On button click, I need to take the data that is returned via my custom javascript and insert it into the table.
Is it possible to hook into the field and dynamically insert data into the field? Or do I have to create the html and manage the iterators and append it?
Here's an example of how I'm grabbing the data in JS
      // add zips in state
      $('#fields-add-state-zips').on('click', function() {
         var ajaxdata = {
            area: 'state',
            state: $stateSelect.val()
         };

         getDataFromArea(ajaxdata, function(locationData) {
            console.log(locationData);
         });
      });


Which calls my controller route:
    public function actionGetLocationsInArea() {
        $module = BulkAssignPostals::getInstance();

        $area = Craft::$app->request->post('area');

        $state = Craft::$app->request->post('state');
        $county = Craft::$app->request->post('county');
        $city = Craft::$app->request->post('city');
        $zip = Craft::$app->request->post('zip');

        $data = [];
        isset($state) ? $data['state'] = $state : $data['state'] = "";
        isset($county) ? $data['county'] = $county : $data['county'] = "";
        isset($city) ? $data['city'] = $city : $data['city'] = "";
        isset($zip) ? $data['zip'] = $zip : $data['zip'] = "";


        $res = Service::getLocationsInArea($area, $data);

        return json_encode($res);
    }

which calls my service
    public static function getLocationsInArea($area, $data) {
        $locations = [];

        switch ($area) {
            case "state":
                if (isset($data['state'])) {
                    $state = $data['state'];
                    $locations = Model::getLocationsInState($state);
                }
                break;
            case "county":
                if (isset($data['state']) && isset($data['county'])) {
                    $state = $data['state'];
                    $county = $data['county'];
                    $locations = Model::getLocationsInCounty($state, $county);
                }
                break;
            case "city":
                if (isset($data['state']) && isset($data['county']) && isset($data['city'])) {
                    $state = $data['state'];
                    $county = $data['county'];
                    $city = $data['city'];
                    $locations = Model::getLocationsInCity($state, $county, $city);
                }
                break;
            case "zip":
                if (isset($data['zip'])) {
                    $zip = $data['zip'];
                    $locations = Model::getLocationByZip($zip);
                }
                break;
            default:

        }

        return [
            'locations' => $locations
        ];
    }

which uses my model
    public static function getLocationsInState($state) {
        return PostalLocations::find()
        ->select('state_abbr,county,city,zip')
        ->where(['state_abbr' => $state])
        ->asArray()
        ->all();
    }

Edit:
I've come up with some javascript, but it feels very hacky and I'm hoping theres a better way. perhaps some craft JS hook of sorts. I'm not sure.
Here's my JS
     function addToTableField(rows) {

      $table = $('#fields-bulkAssignPostalsassignedPostals');
      $trCount = $table.find('tbody').find("tr").length - 0;

      rows.locations.forEach(function(row) {
         $table.find('tbody').append(
            $('').attr('data-id', $trCount)
         );

         for (var key in row) {
            $table.find('tr[data-id='+$trCount+']').append(
               $('').attr('class', 'textual').append(
                  $("").attr('name', 'fields[bulkAssignPostals][assignedLocations]['+$trCount+']['+key+']').html(row[key])
               )

            );

         }
         $table.find('tr[data-id='+$trCount+']').append(
            '',
            ''
         );

         $trCount++;

      });


   }

**Tags:** field, custom-field, modules


---

## 1 answers

### Answer by username_1 on 2019-06-25. Score: 1

I would use a custom controller that requests the javascript data and then appends it to your table with a method like:
public function appendDataToTable($entryId, $jsData) {
    $entry = \craft\elements\Entry::find()->id($entryId)->one();
    $tableValue   = $entry->getFieldValue( 'editableTableField' );
    $tableValue[] = [
        'col0' => $jsData,
    ];
    $entry->setFieldValue( 'editableTableField', $tableValue );
}

...if u need an example for the controller let me know, i am on the phone right now:

> **Comments:**
> **username_0**: thanks for the response. I'd like to see an example if you don't mind. Wouldn't I still need to create the HTML via js so it's populated on the front-end once they click the button? also, i've added some code examples of how my flow works  
> **username_0**: I'm able to append data to the table now via a controller, but I'm confused about the JS. I'm not sure if I have to manually insert <tr> with the appropriate iteration from scratch. Then I wouldn't need to use a controller method since saving an entry will save whatever is in the table  

---

