Answers.Body: <p>After a few days of reflection;</p>
  
  <p>I decided that resetting the checkbox values programatically on <code>EVENT_AFTER_SAVE_ELEMENT</code> was not really needed. </p>
  
  <p>I ended up using a JS solution that unsets my checkbox values from <code>true</code> to <code>false</code> on page load. Works very well. I added my JS through an Asset Bundle, which is loaded through my module. My Asset Bundle function looks like this:</p>
  
  <pre><code>// Load asset bundle
  protected static function loadAssetBundle()
  {
      // Load AssetBundle
      if (Craft::$app-&gt;getRequest()-&gt;getIsCpRequest()) {
  
          // Don't show asset bundle on CP login
          if (Craft::$app-&gt;getUser()-&gt;getIdentity() !== NULL ) {
  
              Event::on(
                  View::class,
                  View::EVENT_BEFORE_RENDER_TEMPLATE,
                  function (TemplateEvent $event) {
  
                      try {
                          Craft::$app-&gt;getView()-&gt;registerAssetBundle(YourModuleAsset::class);
                      } catch (InvalidConfigException $e) {
                          Craft::error(
                              'Error registering YourModuleAssetBundle - '.$e-&gt;getMessage(),
                              __METHOD__
                          );
                      }
  
                  }
              );
  
          }
      }
  
  }
  </code></pre>
  
  <p>The Asset Bundle JS looks like this:</p>
  
  <pre><code>// reset checkbox values after save
  // Use the "Control Panel Body Classes" plugin to assign classes to &lt;body&gt;
  if ($('body.class-set-by-cp-body-classes-plugin')[0]){
      $("input[name='fields[myCheckboxField][]']").prop('checked', false);
  }
  </code></pre>
  
  <p>EDIT: This no longer works since upgrading to Craft 3.4. Visually, the fields are reset in the CP, but the reset values do not persist when the entry is saved</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-02-07T08:51:42.580Z
Answers.LastActivityDate: 2020-02-14T18:50:01.937Z
Answers.LastEditDate: 2020-02-14T18:50:01.937Z
Answers.UserDisplayName: Warmbeat
Body: <p>I'm porting the functionality of an existing plugin from another CMS into Craft 3 through a custom Craft module. The functionality is:</p>
  
  <p>When an option from a multi-value checkbox is checked on the "master" entry, the module will (1) create a new corresponding entry, and (2) reset the checkbox options on the "master" entry, so that no options are selected.</p>
  
  <p><strong>Research</strong></p>
  
  <p>I'm trying to be a good Craft citizen and have spent time studying the following articles. However, they either fail to mention what <code>event</code> they are using, or they end up using <code>EVENT_BEFORE_SAVE_ELEMENT</code>, or the solutions do not work with the current version of Craft (3.1.7):</p>
  
  <ul>
  <li><a href="https://craftcms.stackexchange.com/questions/26014/update-checkbox-value-through-plugin-craft-3">Update checkbox value through plugin (Craft 3)</a></li>
  <li><a href="https://craftcms.stackexchange.com/questions/20962/how-to-save-a-new-entry-with-custom-fields-craft-3">How to save a new entry with custom fields - Craft 3</a></li>
  <li><a href="https://craftcms.stackexchange.com/questions/26772/how-to-saveelement-in-event-after-save-element-without-infinite-loop">How to saveElement in EVENT_AFTER_SAVE_ELEMENT without infinite loop</a></li>
  <li><a href="https://craftcodingchallenge.com/challenge-6-the-chicken-or-the-egg" rel="nofollow noreferrer">https://craftcodingchallenge.com/challenge-6-the-chicken-or-the-egg</a></li>
  </ul>
  
  <p><strong>Attempted Solution</strong></p>
  
  <pre><code>protected static function creatNewEntry()
  {
      Event::on(
          Elements::class,
          Elements::EVENT_AFTER_SAVE_ELEMENT,
          function(ElementEvent $event) {
  
              // Ignore any element that is not an entry
              if (!($event-&gt;element instanceof Entry)) {
                  return;
              }
  
              // Ignore entries that are new because they have no id
              if ($event-&gt;isNew) {
                  return;
              }
  
              // Ignore entries that do not belong in section id
              if ($event-&gt;element-&gt;sectionId != 5) {
                  return;
              }
  
              // Ignore entries that are not in the primary site...
              // This is important if you have a multi-site setup
              if ($event-&gt;element-&gt;siteId != 1) {
                  return;
              }
  
              // Fetch current entry from db. Let's call this the master entry...
              $masterEntry = Craft::$app-&gt;entries-&gt;getEntryById($event-&gt;element-&gt;id, $event-&gt;element-&gt;siteId);
  
              // Get values from checkbox from the master entry...
              $checkboxOptions = $masterEntry-&gt;multiCheckboxField-&gt;getOptions();
  
              foreach ( $checkboxOptions as $option ) {
  
                  // What should happen when a particular checkbox value is selected?
                  if ( ($option-&gt;selected == true) &amp;&amp; ($option-&gt;value == 'example1') ) {
  
                      // Create new entry...
                      $newEntry = new Entry();
                      $newEntry-&gt;sectionId = $masterEntry-&gt;sectionId;
                      $newEntry-&gt;typeId = $masterEntry-&gt;typeId;
                      $newEntry-&gt;title = $masterEntry-&gt;title . 'example1';
                      $newEntry-&gt;enabled = $masterEntry-&gt;enabled;
                      $newEntry-&gt;siteId = $masterEntry-&gt;siteId;
                      $newEntry-&gt;slug = $masterEntry-&gt;slug . 'example1';
  
                  }
  
                  if ( ($option-&gt;selected == true) &amp;&amp; ($option-&gt;value == 'example2') ) {
  
                      // Create new entry...
                      $newEntry = new Entry();
                      $newEntry-&gt;sectionId = $masterEntry-&gt;sectionId;
                      $newEntry-&gt;typeId = $masterEntry-&gt;typeId;
                      $newEntry-&gt;title = $masterEntry-&gt;title . 'example2';
                      $newEntry-&gt;enabled = $masterEntry-&gt;enabled;
                      $newEntry-&gt;siteId = $masterEntry-&gt;siteId;
                      $newEntry-&gt;slug = $masterEntry-&gt;slug . 'example2';
  
                  }
  
              }
  
              // Handle successful / failure of new entry...
              if (isset($newEntry)) {
  
                  $success = Craft::$app-&gt;elements-&gt;saveElement($newEntry);
  
                  if (!$success) {
                      Craft::error('Error saving entry: '.$newEntry-&gt;title.' ('.$newEntry-&gt;id.')', __METHOD__);
                  } else {
                      Craft::info('New entry saved: '.$newEntry-&gt;title.' ('.$newEntry-&gt;id.')', __METHOD__);
                  }
  
              }
  
          }
      );
  }
  </code></pre>
  
  <p>This works great! However, there is no logic in the module that resets the multi-value checkbox on the master entry.</p>
  
  <p>Whilst debugging, I have tried:</p>
  
  <ul>
  <li>adding <code>$event-&gt;element-&gt;multiCheckboxField = [];</code> on <code>EVENT_BEFORE_SAVE_ELEMENT</code> which resets the checkbox selected value from <code>true</code> to <code>false</code>, which is what I want! However, this does not work on <code>EVENT_AFTER_SAVE_ELEMENT</code>. I can't use <code>EVENT_BEFORE_SAVE_ELEMENT</code> because it will require a user to save twice in the CP for my module to fire off the checkbox value.</li>
  <li>adding another static function, which saves the current event element however, this triggers an endless loop, which bounces between <code>isNew' =&gt; $isNewElement</code> on the <code>afterSaveElement</code> and the <code>saveElement()</code> in my module.</li>
  <li>Thought about using a hacky JS solution in the CP - which I don't want to resort to!</li>
  </ul>
  
Tags: <plugin-development><plugin-elementapi><events>
Title: How to reset a multi-value checkbox using EVENT_AFTER_SAVE_ELEMENT in Craft 3?
ThreadText: # How to reset a multi-value checkbox using EVENT_AFTER_SAVE_ELEMENT in Craft 3?
  
  (Asked by: username_0 on 2019-02-04)
  
  I'm porting the functionality of an existing plugin from another CMS into Craft 3 through a custom Craft module. The functionality is:
  
  When an option from a multi-value checkbox is checked on the "master" entry, the module will (1) create a new corresponding entry, and (2) reset the checkbox options on the "master" entry, so that no options are selected.
  
  **Research**
  
  I'm trying to be a good Craft citizen and have spent time studying the following articles. However, they either fail to mention what `event` they are using, or they end up using `EVENT_BEFORE_SAVE_ELEMENT`, or the solutions do not work with the current version of Craft (3.1.7):
  
  * [Update checkbox value through plugin (Craft 3)](https://craftcms.stackexchange.com/questions/26014/update-checkbox-value-through-plugin-craft-3)
  * [How to save a new entry with custom fields - Craft 3](https://craftcms.stackexchange.com/questions/20962/how-to-save-a-new-entry-with-custom-fields-craft-3)
  * [How to saveElement in EVENT\_AFTER\_SAVE\_ELEMENT without infinite loop](https://craftcms.stackexchange.com/questions/26772/how-to-saveelement-in-event-after-save-element-without-infinite-loop)
  * <https://craftcodingchallenge.com/challenge-6-the-chicken-or-the-egg>
  
  **Attempted Solution**
  
  ```
  protected static function creatNewEntry()
  {
      Event::on(
          Elements::class,
          Elements::EVENT_AFTER_SAVE_ELEMENT,
          function(ElementEvent $event) {
  
              // Ignore any element that is not an entry
              if (!($event->element instanceof Entry)) {
                  return;
              }
  
              // Ignore entries that are new because they have no id
              if ($event->isNew) {
                  return;
              }
  
              // Ignore entries that do not belong in section id
              if ($event->element->sectionId != 5) {
                  return;
              }
  
              // Ignore entries that are not in the primary site...
              // This is important if you have a multi-site setup
              if ($event->element->siteId != 1) {
                  return;
              }
  
              // Fetch current entry from db. Let's call this the master entry...
              $masterEntry = Craft::$app->entries->getEntryById($event->element->id, $event->element->siteId);
  
              // Get values from checkbox from the master entry...
              $checkboxOptions = $masterEntry->multiCheckboxField->getOptions();
  
              foreach ( $checkboxOptions as $option ) {
  
                  // What should happen when a particular checkbox value is selected?
                  if ( ($option->selected == true) && ($option->value == 'example1') ) {
  
                      // Create new entry...
                      $newEntry = new Entry();
                      $newEntry->sectionId = $masterEntry->sectionId;
                      $newEntry->typeId = $masterEntry->typeId;
                      $newEntry->title = $masterEntry->title . 'example1';
                      $newEntry->enabled = $masterEntry->enabled;
                      $newEntry->siteId = $masterEntry->siteId;
                      $newEntry->slug = $masterEntry->slug . 'example1';
  
                  }
  
                  if ( ($option->selected == true) && ($option->value == 'example2') ) {
  
                      // Create new entry...
                      $newEntry = new Entry();
                      $newEntry->sectionId = $masterEntry->sectionId;
                      $newEntry->typeId = $masterEntry->typeId;
                      $newEntry->title = $masterEntry->title . 'example2';
                      $newEntry->enabled = $masterEntry->enabled;
                      $newEntry->siteId = $masterEntry->siteId;
                      $newEntry->slug = $masterEntry->slug . 'example2';
  
                  }
  
              }
  
              // Handle successful / failure of new entry...
              if (isset($newEntry)) {
  
                  $success = Craft::$app->elements->saveElement($newEntry);
  
                  if (!$success) {
                      Craft::error('Error saving entry: '.$newEntry->title.' ('.$newEntry->id.')', __METHOD__);
                  } else {
                      Craft::info('New entry saved: '.$newEntry->title.' ('.$newEntry->id.')', __METHOD__);
                  }
  
              }
  
          }
      );
  }
  
  ```
  
  This works great! However, there is no logic in the module that resets the multi-value checkbox on the master entry.
  
  Whilst debugging, I have tried:
  
  * adding `$event->element->multiCheckboxField = [];` on `EVENT_BEFORE_SAVE_ELEMENT` which resets the checkbox selected value from `true` to `false`, which is what I want! However, this does not work on `EVENT_AFTER_SAVE_ELEMENT`. I can't use `EVENT_BEFORE_SAVE_ELEMENT` because it will require a user to save twice in the CP for my module to fire off the checkbox value.
  * adding another static function, which saves the current event element however, this triggers an endless loop, which bounces between `isNew' => $isNewElement` on the `afterSaveElement` and the `saveElement()` in my module.
  * Thought about using a hacky JS solution in the CP - which I don't want to resort to!
  
  **Tags:** plugin-development, plugin-elementapi, events
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_0 on 2019-02-07. Score: 1 | Accepted answer
  
  After a few days of reflection;
  
  I decided that resetting the checkbox values programatically on `EVENT_AFTER_SAVE_ELEMENT` was not really needed.
  
  I ended up using a JS solution that unsets my checkbox values from `true` to `false` on page load. Works very well. I added my JS through an Asset Bundle, which is loaded through my module. My Asset Bundle function looks like this:
  
  ```
  // Load asset bundle
  protected static function loadAssetBundle()
  {
      // Load AssetBundle
      if (Craft::$app->getRequest()->getIsCpRequest()) {
  
          // Don't show asset bundle on CP login
          if (Craft::$app->getUser()->getIdentity() !== NULL ) {
  
              Event::on(
                  View::class,
                  View::EVENT_BEFORE_RENDER_TEMPLATE,
                  function (TemplateEvent $event) {
  
                      try {
                          Craft::$app->getView()->registerAssetBundle(YourModuleAsset::class);
                      } catch (InvalidConfigException $e) {
                          Craft::error(
                              'Error registering YourModuleAssetBundle - '.$e->getMessage(),
                              __METHOD__
                          );
                      }
  
                  }
              );
  
          }
      }
  
  }
  
  ```
  
  The Asset Bundle JS looks like this:
  
  ```
  // reset checkbox values after save
  // Use the "Control Panel Body Classes" plugin to assign classes to <body>
  if ($('body.class-set-by-cp-body-classes-plugin')[0]){
      $("input[name='fields[myCheckboxField][]']").prop('checked', false);
  }
  
  ```
  
  EDIT: This no longer works since upgrading to Craft 3.4. Visually, the fields are reset in the CP, but the reset values do not persist when the entry is saved
  
  
  ---
  
  