Answers.Body: <p>You can create a POST request via Ajax to the <code>assets/deleteFile</code> (Craft 2) / <code>assets/delete-asset</code> (Craft 3) controller action:</p>
  
  <p><strong>Craft 2:</strong></p>
  
  <pre class="lang-javascript prettyprint-override"><code>$('#delete-file').click(function() {
      var data = {
          fileId: 100
      };
  
      $.post('/actions/assets/deleteFile', data, function(response) {
          // ...
      });
  });
  </code></pre>
  
  <p><strong>Craft 3:</strong></p>
  
  <pre class="lang-javascript prettyprint-override"><code>$('#delete-file').click(function() {
      var data = {
          assetId: 100
      };
  
      $.post('/actions/assets/delete-asset', data, function(response) {
          // ...
      });
  });
  </code></pre>
  
  <p>That controller action will require that the user is logged-in with a user account that has the “Remove files” permission on the asset source that the file belongs to. Granting that permission to a user will give them the ability to delete <strong>any</strong> file within that asset source though - not just their own. So this is probably not a good idea.</p>
  
  <p>A better way of doing this would be to write a <a href="https://docs.craftcms.com/v3/extend/module-guide.html" rel="nofollow noreferrer">module</a> that provides its own <a href="https://www.yiiframework.com/doc/guide/2.0/en/structure-controllers" rel="nofollow noreferrer">controller</a> that does its own permission checking and handles the file deletion. It would look something like this:</p>
  
  <p><strong>Craft 2:</strong></p>
  
  <pre class="lang-php prettyprint-override"><code>class MyController extends BaseController
  {
      public function actionDeleteFile()
      {
          $this-&gt;requireAjaxRequest();
  
          $fileId = craft()-&gt;request-&gt;getRequiredPost('fileId');
          $file = craft()-&gt;assets-&gt;getFileById($fileId);
  
          if (!$file)
          {
              throw new Exception('Could not find a file with the ID '.$fileId);
          }
  
          // Make sure that it's within a folder with the same name as the user's username
          if ($file-&gt;getFolder()-&gt;name != craft()-&gt;userSession-&gt;getUser()-&gt;username)
          {
              throw new HttpException(403);
          }
  
          $response = craft()-&gt;assets-&gt;deleteFiles($fileIds);
          $this-&gt;returnJson($response-&gt;getResponseData());
      }
  }
  </code></pre>
  
  <p><strong>Craft 3:</strong></p>
  
  <pre class="lang-php prettyprint-override"><code>use Craft;
  use craft\web\Controller;
  use yii\web\BadRequestHttpException;
  use yii\web\ForbiddenHttpException;
  use yii\web\Response;
  
  class MyController extends Controller
  {
      public function actionDeleteFile(): Response
      {
          $this-&gt;requireAcceptsJson();
  
          $assetId = Craft::$app-&gt;request-&gt;getRequiredBodyParam('fileId');
          $asset = Craft::$app-&gt;assets-&gt;getAssetById($assetId);
  
          if (!$asset) {
              throw new BadRequestHttpException('Invalid asset ID: ' . $assetId);
          }
  
          // Make sure that it's within a folder with the same name as the user's username
          if ($asset-&gt;getFolder()-&gt;name != Craft::$app-&gt;user-&gt;getIdentity()-&gt;username) {
              throw new ForbiddenHttpException('Not permitted to delete asset ' . $assetId);
          }
  
          $success = Craft::$app-&gt;elements-&gt;deleteElement($asset);
          return $this-&gt;asJson([
              'success' =&gt; $success,
          ]);
      }
  }
  </code></pre>
  
  <p>With that in place, you’d just need to update your JavaScript to point to your <code>deleteFile</code>/<code>delete-file</code> action instead of Craft’s.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2019-12-04T16:46:35.747Z
Answers.Text: Does the above post via Ajax method for deleting a file in Craft 3 still work? Been trying it but just getting error: Bad request 
  `yii\web\BadRequestHttpException: Unable to verify your data submission`
Answers.UserDisplayName: mmc501
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-01-09T11:06:07.397Z
Answers.Text: I tried using this code with Craft 4, but its not going well 
  
  I created a module using the module generator, but I’m getting a 404 error for the action /actions/deleteFile/delete-file and invalid id undefined response.
  
  I don't understand how I could get a 404 and an error response from the code that it can't reach.
Answers.UserDisplayName: fdelaneau
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-01-09T19:48:37.703Z
Answers.Text: @fdelaneau Actions should be kebab-case in Craft 3+ (Yii2). (“`deleteFile`/`delete-file`” was me demonstrating the two ways you might access it, depending on Craft 2 or 3+.) The entire module URI will be composed of your module ID, controller name (sans `Controller`) and action name (sans `action`). So for example, if the module ID is `foo-bar` and your controller is named `BazController`, and action method is `actionDeleteFile()`, the URI would be `actions/foo-bar/baz/delete-file`.
Answers.UserDisplayName: Brandon Kelly
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-09-18T22:27:29.877Z
Answers.Text: So, how do I get the fileId to pass into the controller? I have tried {{entry.myFileHandle.id}} and a bunch of other stuff that is not working for me.
Answers.UserDisplayName: David A McInnis
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2014-09-18T22:28:43.117Z
Answers.Text: @DavidAaronMcInnis `entry.myAssetsFieldHandle.first().id` would be one way.
Answers.UserDisplayName: Brandon Kelly
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2014-08-19T21:09:31.883Z
Answers.LastActivityDate: 2019-01-29T11:43:36.833Z
Answers.LastEditDate: 2019-01-29T11:43:36.833Z
Answers.UserDisplayName: Brandon Kelly
Body: <p>I am creating a proof of concept for a client in Craft where the client's customers can manage projects from the frontend of a Craft install.</p>
  
  <p>I have a frontend form working correctly for creating a new project and uploading files attached to it... however the missing piece to the puzzle for full management is being able to delete a project entry and also being able to manage the media attached to the project entry.</p>
  
  <p>Is it possible to let a frontend user manage assets, in particular deleting assets from their username folder?</p>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-08-19T20:55:23.063Z
Comments.Text: Hey Alan, I just [removed](http://craftcms.stackexchange.com/posts/2013/revisions) your two additional questions, as they each warrant their own posts.
Comments.UserDisplayName: Brandon Kelly
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-08-20T04:10:23.467Z
Comments.Text: Thanks @BrandonKelly so much for your thorough answer and the edits. I hope I am not spamming the SE site too much by breaking the other questions out into two new questions: [How do you delete entries from a frontend form?](http://craftcms.stackexchange.com/questions/2033/how-do-you-delete-entries-from-a-frontend-form?lq=1) and [Is it possible to use the assets modal on the front end?](http://craftcms.stackexchange.com/questions/2034/is-it-possible-to-use-the-assets-modal-on-the-front-end?lq=1).
Comments.UserDisplayName: Alan Miller
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2014-08-20T05:15:36.747Z
Comments.Text: @AlanMiller Not spamming at all, glad you split these into separate questions! As individual questions, you'll be able to get better, more detailed responses. Plus, it's way more useful to any future visitors who may only share one of your questions. Splitting them up is definitely the right move!
Comments.UserDisplayName: Lindsey D
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-01-28T06:23:54.223Z
Comments.Text: @brandon is their a way to delete an asset in this manner in Craft 3?
Comments.UserDisplayName: kinoli
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2019-01-29T11:44:18.143Z
Comments.Text: @kinoli just updated my answer for Craft 3.
Comments.UserDisplayName: Brandon Kelly
Tags: <assets><form><entry><assetfilemodel>
Title: How do you delete assets from a frontend form?
ThreadText: # How do you delete assets from a frontend form?
  
  (Asked by: username_0 on 2014-08-19)
  
  I am creating a proof of concept for a client in Craft where the client's customers can manage projects from the frontend of a Craft install.
  
  I have a frontend form working correctly for creating a new project and uploading files attached to it... however the missing piece to the puzzle for full management is being able to delete a project entry and also being able to manage the media attached to the project entry.
  
  Is it possible to let a frontend user manage assets, in particular deleting assets from their username folder?
  
  **Tags:** assets, form, entry, assetfilemodel
  
  > **Comments:**
  > **username_1**: Hey username_0, I just [removed](http://craftcms.stackexchange.com/posts/2013/revisions) your two additional questions, as they each warrant their own posts.  
  > **username_0**: Thanks @username_1 so much for your thorough answer and the edits. I hope I am not spamming the SE site too much by breaking the other questions out into two new questions: [How do you delete entries from a frontend form?](http://craftcms.stackexchange.com/questions/2033/how-do-you-delete-entries-from-a-frontend-form?lq=1) and [Is it possible to use the assets modal on the front end?](http://craftcms.stackexchange.com/questions/2034/is-it-possible-to-use-the-assets-modal-on-the-front-end?lq=1).  
  > **username_2**: @username_0 Not spamming at all, glad you split these into separate questions! As individual questions, you'll be able to get better, more detailed responses. Plus, it's way more useful to any future visitors who may only share one of your questions. Splitting them up is definitely the right move!  
  > **username_3**: @username_1 is their a way to delete an asset in this manner in Craft 3?  
  > **username_1**: @username_3 just updated my answer for Craft 3.  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2014-08-19. Score: 9 | Accepted answer
  
  You can create a POST request via Ajax to the `assets/deleteFile` (Craft 2) / `assets/delete-asset` (Craft 3) controller action:
  
  **Craft 2:**
  
  ```javascript
  $('#delete-file').click(function() {
      var data = {
          fileId: 100
      };
  
      $.post('/actions/assets/deleteFile', data, function(response) {
          // ...
      });
  });
  
  ```
  
  **Craft 3:**
  
  ```javascript
  $('#delete-file').click(function() {
      var data = {
          assetId: 100
      };
  
      $.post('/actions/assets/delete-asset', data, function(response) {
          // ...
      });
  });
  
  ```
  
  That controller action will require that the user is logged-in with a user account that has the “Remove files” permission on the asset source that the file belongs to. Granting that permission to a user will give them the ability to delete **any** file within that asset source though - not just their own. So this is probably not a good idea.
  
  A better way of doing this would be to write a [module](https://docs.craftcms.com/v3/extend/module-guide.html) that provides its own [controller](https://www.yiiframework.com/doc/guide/2.0/en/structure-controllers) that does its own permission checking and handles the file deletion. It would look something like this:
  
  **Craft 2:**
  
  ```php
  class MyController extends BaseController
  {
      public function actionDeleteFile()
      {
          $this->requireAjaxRequest();
  
          $fileId = craft()->request->getRequiredPost('fileId');
          $file = craft()->assets->getFileById($fileId);
  
          if (!$file)
          {
              throw new Exception('Could not find a file with the ID '.$fileId);
          }
  
          // Make sure that it's within a folder with the same name as the user's username
          if ($file->getFolder()->name != craft()->userSession->getUser()->username)
          {
              throw new HttpException(403);
          }
  
          $response = craft()->assets->deleteFiles($fileIds);
          $this->returnJson($response->getResponseData());
      }
  }
  
  ```
  
  **Craft 3:**
  
  ```php
  use Craft;
  use craft\web\Controller;
  use yii\web\BadRequestHttpException;
  use yii\web\ForbiddenHttpException;
  use yii\web\Response;
  
  class MyController extends Controller
  {
      public function actionDeleteFile(): Response
      {
          $this->requireAcceptsJson();
  
          $assetId = Craft::$app->request->getRequiredBodyParam('fileId');
          $asset = Craft::$app->assets->getAssetById($assetId);
  
          if (!$asset) {
              throw new BadRequestHttpException('Invalid asset ID: ' . $assetId);
          }
  
          // Make sure that it's within a folder with the same name as the user's username
          if ($asset->getFolder()->name != Craft::$app->user->getIdentity()->username) {
              throw new ForbiddenHttpException('Not permitted to delete asset ' . $assetId);
          }
  
          $success = Craft::$app->elements->deleteElement($asset);
          return $this->asJson([
              'success' => $success,
          ]);
      }
  }
  
  ```
  
  With that in place, you’d just need to update your JavaScript to point to your `deleteFile`/`delete-file` action instead of Craft’s.
  
  > **Comments:**
  > **username_6**: So, how do I get the fileId to pass into the controller? I have tried {{entry.myFileHandle.id}} and a bunch of other stuff that is not working for me.  
  > **username_1**: @DavidAaronMcInnis `entry.myAssetsFieldHandle.first().id` would be one way.  
  > **username_4**: Does the above post via Ajax method for deleting a file in Craft 3 still work? Been trying it but just getting error: Bad request  `yii\web\BadRequestHttpException: Unable to verify your data submission`  
  > **username_5**: I tried using this code with Craft 4, but its not going well   I created a module using the module generator, but I’m getting a 404 error for the action /actions/deleteFile/delete-file and invalid id undefined response.  I don't understand how I could get a 404 and an error response from the code that it can't reach.  
  > **username_1**: @username_5 Actions should be kebab-case in Craft 3+ (Yii2). (“`deleteFile`/`delete-file`” was me demonstrating the two ways you might access it, depending on Craft 2 or 3+.) The entire module URI will be composed of your module ID, controller name (sans `Controller`) and action name (sans `action`). So for example, if the module ID is `foo-bar` and your controller is named `BazController`, and action method is `actionDeleteFile()`, the URI would be `actions/foo-bar/baz/delete-file`.  
  
  ---
  
  