Answers.Body: <p>Many of those advanced endpoints are undocumented, but you can find out a lot with the devtools. If you use the <em>Delete (with Descendants)</em> option in the backend and check the devtools, you can see it uses <a href="https://docs.craftcms.com/api/v3/craft-controllers-elementindexescontroller.html#public-methods" rel="nofollow noreferrer">craft\controllers\ElementIndexesController::actionPerformAction</a>. This method expects an <code>elementAction</code> parameter to tell it which action to perform. You can pass <code>craft\\elements\\actions\\Delete</code> which includes the <code>withDescendants</code> option you're looking for. The payload for the request will also tell you which parameters the action requires:</p>
  <p><a href="https://i.sstatic.net/ATZzZ.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/ATZzZ.png" alt="Screenshot of the payload for the perform action endpoint" /></a></p>
  <p>Check the source code of the <a href="https://github.com/craftcms/cms/blob/develop/src/controllers/ElementIndexesController.php#L172" rel="nofollow noreferrer"><code>actionPerformAction</code> method</a> and the <a href="https://github.com/craftcms/cms/blob/develop/src/elements/actions/Delete.php" rel="nofollow noreferrer"><code>craft\elements\actions\Delete</code> class</a> to find which parameters you can use and which formats they can take. Then you can construct a frontend form with (hidden) inputs to perform this action for a particular element.</p>
  <p>Adding the parameters inside a form (with <code>method=&quot;POST&quot;</code>) can be done using the <a href="https://craftcms.com/docs/3.x/dev/functions.html#hiddeninput" rel="nofollow noreferrer"><code>hiddenInput</code> Twig function</a>:</p>
  <pre class="lang-twig prettyprint-override"><code>{{ hiddenInput('elementAction', 'craft\\elements\\actions\\Delete') }}
  {{ hiddenInput('elementType', 'craft\\elements\\Entry' }}
  {{ hiddenInput('source', &quot;section:#{entry.section.uid}&quot; }}
  {{ hiddenInput('withDescendants', true) }}
  </code></pre>
  <p>Check the request in the devtools as mentioned above as well as the source code for the controller endpoint and the action class to find out which parameters are required. For this action in particular, it looks like it requires <code>criteria</code> for the query, and an array of <code>elementIds</code> to delete. Some parameters may also be optional. Make sure to check the source code for dependencies between parameters as well. For example, it looks like the action <a href="https://github.com/craftcms/cms/blob/develop/src/elements/actions/Delete.php#L157" rel="nofollow noreferrer">will <em>not</em> delete any descendants</a> if you specify <code>hard: true</code> to hard-delete the elements instead of soft-deleting them.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-12-06T17:26:10.667Z
Answers.Text: Thanks so much for the detailed response MoritzLost. That's really useful information to help me learn how to approach this. Would you have any examples of how that would be constructed? Or something along similar lines? I'm relativity new to something as complex as this. Thanks!
Answers.UserDisplayName: Kieron Keenan
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-12-07T10:57:05.570Z
Answers.Text: @KieronKeenan Basically, you need to use visible and/or hidden inputs in your form to include the data the controller requires to perform the requested action. The same way you're using `{{ hiddenInput('entryId', entry.id) }}` to pass the entryId to the `delete-entry` action, you can, for example, specify the `source` for the action: `{{ hiddenInput('source', "section:#{entry.section.uid}") }}`. Then it's just a matter of checking the request in the devtools and/or the source code to see which parameters the controller and the action require and adding those to the form.
Answers.UserDisplayName: MoritzLost
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-12-07T11:04:24.453Z
Answers.Text: @KieronKeenan I've updated my answer with a code example.
Answers.UserDisplayName: MoritzLost
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-12-08T10:07:01.593Z
Answers.Text: Thanks so much for the help and guidance here. I'm relatively new to Craft so this has been quite challenging for me. I'm still trying to work through the problem with your advice but still unsure what the root cause/causes that's stopping the form from deleting the parent + children entries.
Answers.UserDisplayName: Kieron Keenan
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-12-08T10:08:04.023Z
Answers.Text: this is basically what I've been trying to test out... 
  
  `<form method="post" accept-charset="UTF-8">
      {{ csrfInput() }}
      {{ hiddenInput('elementType', 'craft\\elements\\Entry') }}
      {{ hiddenInput('elementAction', 'craft\\elements\\actions\\Delete') }}
      {{ hiddenInput('deletedElementIds', entry.id) }}
      {{ hiddenInput('hard', false) }}
      {{ hiddenInput('source', "section:#{entry.section.uid}") }}
      {{ hiddenInput('withDescendants', true) }}
      {{ redirectInput(entry.parent.url) }}
  
      <input type="submit" class="button" value="Delete">
    </form>`
Answers.UserDisplayName: Kieron Keenan
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-12-08T10:24:08.563Z
Answers.Text: @KieronKeenan Please post your partial code as a formatted code block in your question, it's unreadable in the comments. Where are you getting the `deletedElementIds` parameter from? I only see that as a variable appearing in the delete action, but not as a POST parameter. Looks like you're still missing some parameters – `criteria`, `context` and `elementIds` in particular. If you can't get it to work, another option would be to build your own controller endpoint that just accepts an element ID and uses the `Elements` service directly to delete the specified element and all it's descendants.
Answers.UserDisplayName: MoritzLost
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-12-08T10:25:28.473Z
Answers.Text: @KieronKeenan The `elementIds` parameter is required – see [this line in the source code](https://github.com/craftcms/cms/blob/develop/src/controllers/ElementIndexesController.php#L179).
Answers.UserDisplayName: MoritzLost
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-12-08T10:30:01.953Z
Answers.Text: @KieronKeenan Some post parameters are also retrieved in the [`beforeAction` method of the controller](https://github.com/craftcms/cms/blob/b26caca81f2b88051c6e37d99be70a91e515274d/src/controllers/ElementIndexesController.php#L83-L110), make sure to check those as well and include them in your form if necessary.
Answers.UserDisplayName: MoritzLost
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-12-10T12:10:48.547Z
Answers.Text: Thanks @MoritzLost! I think I'm in way above my head here trying to figure this out but I really do appreciate the support & advice here. I'll keep going at it till I get it working.
Answers.UserDisplayName: Kieron Keenan
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2021-12-06T10:24:54.197Z
Answers.LastActivityDate: 2021-12-08T10:22:58.793Z
Answers.LastEditDate: 2021-12-08T10:22:58.793Z
Answers.UserDisplayName: MoritzLost
Body: <p>I'm having some trouble solving this issue and could do it with some help. Basically, I'm looking to replicate the &quot;Delete (with descendants)&quot; function from the admin panel in a front-end form.</p>
  <p>On the front-end at the moment users can delete children or parent pages, but not the parent (and children automatically). I've tried a number of different methods but to no avail.</p>
  <p>My front-end is using...</p>
  <pre><code>       &lt;form method=&quot;post&quot; accept-charset=&quot;UTF-8&quot; id=&quot;delete-page&quot;&gt;
            {{ csrfInput() }}
            {{ hiddenInput('context', 'index') }}
            {{ hiddenInput('criteria', '') }}
            {{ hiddenInput('elementAction', 'craft\\elements\\actions\\Delete') }}
            {{ hiddenInput('elementIds', entry.id) }}
            {{ hiddenInput('elementType', 'craft\\elements\\Entry') }}
            {{ hiddenInput('hard', false) }}
            {{ hiddenInput('source', &quot;section:#{entry.section.uid}&quot;) }}
            {{ hiddenInput('withDescendants', true) }}
            &lt;input type=&quot;submit&quot; class=&quot;button&quot; class=&quot;save&quot; value=&quot;Delete P+C&quot; accesskey=&quot;v&quot;&gt;
        &lt;/form&gt;
  </code></pre>
  <p>In the Craft Docs, I came across <a href="https://docs.craftcms.com/api/v3/craft-elements-actions-delete.html#withdescendants" rel="nofollow noreferrer">withDescendants</a> but not sure how to utilize this on the front-end.</p>
  <p>Any advice here?</p>
  
Tags: <frontend><frontend-form><children><delete>
Title: Delete Parent and Children via the frontend
ThreadText: # Delete Parent and Children via the frontend
  
  (Asked by: username_0 on 2021-12-04)
  
  I'm having some trouble solving this issue and could do it with some help. Basically, I'm looking to replicate the "Delete (with descendants)" function from the admin panel in a front-end form.
  
  On the front-end at the moment users can delete children or parent pages, but not the parent (and children automatically). I've tried a number of different methods but to no avail.
  
  My front-end is using...
  
  ```
         <form method="post" accept-charset="UTF-8" id="delete-page">
            {{ csrfInput() }}
            {{ hiddenInput('context', 'index') }}
            {{ hiddenInput('criteria', '') }}
            {{ hiddenInput('elementAction', 'craft\\elements\\actions\\Delete') }}
            {{ hiddenInput('elementIds', entry.id) }}
            {{ hiddenInput('elementType', 'craft\\elements\\Entry') }}
            {{ hiddenInput('hard', false) }}
            {{ hiddenInput('source', "section:#{entry.section.uid}") }}
            {{ hiddenInput('withDescendants', true) }}
            <input type="submit" class="button" class="save" value="Delete P+C" accesskey="v">
        </form>
  
  ```
  
  In the Craft Docs, I came across [withDescendants](https://docs.craftcms.com/api/v3/craft-elements-actions-delete.html#withdescendants) but not sure how to utilize this on the front-end.
  
  Any advice here?
  
  **Tags:** frontend, frontend-form, children, delete
  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2021-12-06. Score: 1
  
  Many of those advanced endpoints are undocumented, but you can find out a lot with the devtools. If you use the *Delete (with Descendants)* option in the backend and check the devtools, you can see it uses [craft\controllers\ElementIndexesController::actionPerformAction](https://docs.craftcms.com/api/v3/craft-controllers-elementindexescontroller.html#public-methods). This method expects an `elementAction` parameter to tell it which action to perform. You can pass `craft\\elements\\actions\\Delete` which includes the `withDescendants` option you're looking for. The payload for the request will also tell you which parameters the action requires:
  
  [![Screenshot of the payload for the perform action endpoint](https://i.sstatic.net/ATZzZ.png)](https://i.sstatic.net/ATZzZ.png)
  
  Check the source code of the [`actionPerformAction` method](https://github.com/craftcms/cms/blob/develop/src/controllers/ElementIndexesController.php#L172) and the [`craft\elements\actions\Delete` class](https://github.com/craftcms/cms/blob/develop/src/elements/actions/Delete.php) to find which parameters you can use and which formats they can take. Then you can construct a frontend form with (hidden) inputs to perform this action for a particular element.
  
  Adding the parameters inside a form (with `method="POST"`) can be done using the [`hiddenInput` Twig function](https://craftcms.com/docs/3.x/dev/functions.html#hiddeninput):
  
  ```twig
  {{ hiddenInput('elementAction', 'craft\\elements\\actions\\Delete') }}
  {{ hiddenInput('elementType', 'craft\\elements\\Entry' }}
  {{ hiddenInput('source', "section:#{entry.section.uid}" }}
  {{ hiddenInput('withDescendants', true) }}
  
  ```
  
  Check the request in the devtools as mentioned above as well as the source code for the controller endpoint and the action class to find out which parameters are required. For this action in particular, it looks like it requires `criteria` for the query, and an array of `elementIds` to delete. Some parameters may also be optional. Make sure to check the source code for dependencies between parameters as well. For example, it looks like the action [will *not* delete any descendants](https://github.com/craftcms/cms/blob/develop/src/elements/actions/Delete.php#L157) if you specify `hard: true` to hard-delete the elements instead of soft-deleting them.
  
  > **Comments:**
  > **username_0**: Thanks so much for the detailed response username_1. That's really useful information to help me learn how to approach this. Would you have any examples of how that would be constructed? Or something along similar lines? I'm relativity new to something as complex as this. Thanks!  
  > **username_1**: @username_0 Basically, you need to use visible and/or hidden inputs in your form to include the data the controller requires to perform the requested action. The same way you're using `{{ hiddenInput('entryId', entry.id) }}` to pass the entryId to the `delete-entry` action, you can, for example, specify the `source` for the action: `{{ hiddenInput('source', "section:#{entry.section.uid}") }}`. Then it's just a matter of checking the request in the devtools and/or the source code to see which parameters the controller and the action require and adding those to the form.  
  > **username_1**: @username_0 I've updated my answer with a code example.  
  > **username_0**: Thanks so much for the help and guidance here. I'm relatively new to Craft so this has been quite challenging for me. I'm still trying to work through the problem with your advice but still unsure what the root cause/causes that's stopping the form from deleting the parent + children entries.  
  > **username_0**: this is basically what I've been trying to test out...   `<form method="post" accept-charset="UTF-8">     {{ csrfInput() }}     {{ hiddenInput('elementType', 'craft\\elements\\Entry') }}     {{ hiddenInput('elementAction', 'craft\\elements\\actions\\Delete') }}     {{ hiddenInput('deletedElementIds', entry.id) }}     {{ hiddenInput('hard', false) }}     {{ hiddenInput('source', "section:#{entry.section.uid}") }}     {{ hiddenInput('withDescendants', true) }}     {{ redirectInput(entry.parent.url) }}      <input type="submit" class="button" value="Delete">   </form>`  
  > **username_1**: @username_0 Please post your partial code as a formatted code block in your question, it's unreadable in the comments. Where are you getting the `deletedElementIds` parameter from? I only see that as a variable appearing in the delete action, but not as a POST parameter. Looks like you're still missing some parameters – `criteria`, `context` and `elementIds` in particular. If you can't get it to work, another option would be to build your own controller endpoint that just accepts an element ID and uses the `Elements` service directly to delete the specified element and all it's descendants.  
  > **username_1**: @username_0 The `elementIds` parameter is required – see [this line in the source code](https://github.com/craftcms/cms/blob/develop/src/controllers/ElementIndexesController.php#L179).  
  > **username_1**: @username_0 Some post parameters are also retrieved in the [`beforeAction` method of the controller](https://github.com/craftcms/cms/blob/b26caca81f2b88051c6e37d99be70a91e515274d/src/controllers/ElementIndexesController.php#L83-L110), make sure to check those as well and include them in your form if necessary.  
  > **username_0**: Thanks @username_1! I think I'm in way above my head here trying to figure this out but I really do appreciate the support & advice here. I'll keep going at it till I get it working.  
  
  ---
  
  