<p>So the reason your code worked with Craft 3 was that it wasn't typed, so it was okay with an empty table being stored as a string.</p>
<p>As for why your normalization via event doesn't work:</p>
<ul>
<li>Does the event get triggered?</li>
<li>If yes, maybe try:</li>
</ul>
<pre class="lang-php prettyprint-override"><code>    if (empty($settings['whitelist'])) {
      $settings['whitelist'] = [];
    }
</code></pre>
<p>...in case the value is coming in as <code>null</code> or some other empty value?</p>

CC BY-SA 4.0
2022-08-14T20:23:58.300Z
Thanks @andrew, the 'EVENT_BEFORE_SAVE_SETTINGS' event isn't being triggered at all in Craft 3. I've tried using the "EVENT_BEFORE_SAVE_PLUGIN_SETTINGS" instead, which does trigger, however when the whitelist field is empty the type error gets thrown before the event does.
Mark Notton
CC BY-SA 4.0
2022-08-13T22:10:37.190Z
2022-08-13T22:10:37.190Z
andrew.welch
<p><strong>Prevent users on Craft 3 from being able to submit an empty table:</strong></p>
<p>In the plugins settings.twig file update the the 'whitelist' rows variables to  an empty array if it's empty and the Craft version is starts with &quot;3&quot;</p>
<pre><code>{% if whitelist is empty and craft.app.getVersion()|first == '3' %}
  {% set whitelist = whitelist is empty ? { item : '' } %}
{% endif %}
</code></pre>
<p>If you are using the 'allowReorder' property; it is worth hiding the first delete button on the first row item:</p>
<pre class="lang-css prettyprint-override"><code>{% css %}
  #settings-whitelsit tbody &gt; tr:first-of-type a.delete { display:none; }
{% endcss %}
</code></pre>
<p>There is a minRows property that can be defined in the editableTable options:</p>
<pre><code>forms.editableTable({
  minRows : craft.app.getVersion()|first == '3' ? 1 : null,
  ...
})
</code></pre>

CC BY-SA 4.0
2022-08-20T23:04:59.960Z
2022-08-22T07:32:28.400Z
2022-08-22T07:32:28.400Z
Mark Notton
<p>My plugin uses a <code>{{ forms.editableTable({...}) }}</code> field within the settings.twig. When the field has row items it will save just fine, but when the table is empty it attempts to save it as an empty string. This throws an error:</p>
<p><code>Typed property marknotton\myplugin\models\Settings::$whitelist must be array, string used</code></p>
<p>I would have expected it to save an empty array. Especially as I've defined the default value as an array in the Settings class.</p>
<p>Following <a href="https://github.com/craftcms/cms/issues/3105#issuecomment-405650687" rel="nofollow noreferrer">Brandons suggestion from an older issue</a>, I have tried to amend the setting before it is saved via an Event listener:</p>
<pre class="lang-php prettyprint-override"><code>// This is in my plugins init() method
Event::on(
  MyPlugin::class,
  MyPlugin::EVENT_BEFORE_SAVE_SETTINGS,
  [Settings::class, 'onBeforeSaveSettings']
);
</code></pre>
<pre class="lang-php prettyprint-override"><code>class Settings extends Model {

  public array $whitelist = [];

  public function rules(): array 
  {
    return [
      ['whitelist', ArrayValidator::class],
    ];
  }

  public static function onBeforeSaveSettings(ModelEvent $event): ModelEvent
  {
    $plugin = $event-&gt;sender;
    $settings = $plugin-&gt;getSettings();

    if ( is_string($settings['whitelist']) ) {
      $settings['whitelist'] = [];
    }
    
    return $event;
  }

}
</code></pre>
<p>This works perfectly in Craft 4, but in Craft 3 my 'onBeforeSaveSettings' method isn't getting called at all.</p>
<p>Is this just a novice data type issue I'm overlooking? Or is the <code>EVENT_BEFORE_SAVE_SETTINGS</code> event failing to run on Craft 3 specifically?</p>

<craft3><plugin-development><settings>
Plugin 'editableTable' settings field returns incorrect type when empty
# Plugin 'editableTable' settings field returns incorrect type when empty

(Asked by: username_0 on 2022-08-11)

My plugin uses a {{ forms.editableTable({...}) }} field within the settings.twig. When the field has row items it will save just fine, but when the table is empty it attempts to save it as an empty string. This throws an error:
Typed property marknotton\myplugin\models\Settings::$whitelist must be array, string used
I would have expected it to save an empty array. Especially as I've defined the default value as an array in the Settings class.
Following Brandons suggestion from an older issue, I have tried to amend the setting before it is saved via an Event listener:
// This is in my plugins init() method
Event::on(
  MyPlugin::class,
  MyPlugin::EVENT_BEFORE_SAVE_SETTINGS,
  [Settings::class, 'onBeforeSaveSettings']
);

class Settings extends Model {

  public array $whitelist = [];

  public function rules(): array 
  {
    return [
      ['whitelist', ArrayValidator::class],
    ];
  }

  public static function onBeforeSaveSettings(ModelEvent $event): ModelEvent
  {
    $plugin = $event->sender;
    $settings = $plugin->getSettings();

    if ( is_string($settings['whitelist']) ) {
      $settings['whitelist'] = [];
    }
    
    return $event;
  }

}

This works perfectly in Craft 4, but in Craft 3 my 'onBeforeSaveSettings' method isn't getting called at all.
Is this just a novice data type issue I'm overlooking? Or is the EVENT_BEFORE_SAVE_SETTINGS event failing to run on Craft 3 specifically?

**Tags:** craft3, plugin-development, settings


---

## 2 answers

### Answer by username_1 on 2022-08-13. Score: 1

So the reason your code worked with Craft 3 was that it wasn't typed, so it was okay with an empty table being stored as a string.
As for why your normalization via event doesn't work:

Does the event get triggered?
If yes, maybe try:

    if (empty($settings['whitelist'])) {
      $settings['whitelist'] = [];
    }

...in case the value is coming in as null or some other empty value?

> **Comments:**
> **username_0**: Thanks @andrew, the 'EVENT_BEFORE_SAVE_SETTINGS' event isn't being triggered at all in Craft 3. I've tried using the "EVENT_BEFORE_SAVE_PLUGIN_SETTINGS" instead, which does trigger, however when the whitelist field is empty the type error gets thrown before the event does.  

---

### Answer by username_0 on 2022-08-20. Score: 1

Prevent users on Craft 3 from being able to submit an empty table:
In the plugins settings.twig file update the the 'whitelist' rows variables to  an empty array if it's empty and the Craft version is starts with "3"
{% if whitelist is empty and craft.app.getVersion()|first == '3' %}
  {% set whitelist = whitelist is empty ? { item : '' } %}
{% endif %}

If you are using the 'allowReorder' property; it is worth hiding the first delete button on the first row item:
{% css %}
  #settings-whitelsit tbody > tr:first-of-type a.delete { display:none; }
{% endcss %}

There is a minRows property that can be defined in the editableTable options:
forms.editableTable({
  minRows : craft.app.getVersion()|first == '3' ? 1 : null,
  ...
})


---

