<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>

CC BY-SA 4.0
2019-12-04T16:46:35.747Z
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`
mmc501
CC BY-SA 4.0
2024-01-09T11:06:07.397Z
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.
fdelaneau
CC BY-SA 4.0
2024-01-09T19:48:37.703Z
@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`.
Brandon Kelly
CC BY-SA 3.0
2014-09-18T22:27:29.877Z
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.
David A McInnis
CC BY-SA 3.0
2014-09-18T22:28:43.117Z
@DavidAaronMcInnis `entry.myAssetsFieldHandle.first().id` would be one way.
Brandon Kelly
CC BY-SA 4.0
2014-08-19T21:09:31.883Z
2019-01-29T11:43:36.833Z
2019-01-29T11:43:36.833Z
Brandon Kelly
<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>

CC BY-SA 3.0
2014-08-19T20:55:23.063Z
Hey Alan, I just [removed](http://craftcms.stackexchange.com/posts/2013/revisions) your two additional questions, as they each warrant their own posts.
Brandon Kelly
CC BY-SA 3.0
2014-08-20T04:10:23.467Z
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).
Alan Miller
CC BY-SA 3.0
2014-08-20T05:15:36.747Z
@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!
Lindsey D
CC BY-SA 4.0
2019-01-28T06:23:54.223Z
@brandon is their a way to delete an asset in this manner in Craft 3?
kinoli
CC BY-SA 4.0
2019-01-29T11:44:18.143Z
@kinoli just updated my answer for Craft 3.
Brandon Kelly
<assets><form><entry><assetfilemodel>
How do you delete assets from a frontend form?
# 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 Alan, I just [removed](http://craftcms.stackexchange.com/posts/2013/revisions) your two additional questions, as they each warrant their own posts.  
> **username_0**: 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).  
> **username_2**: @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!  
> **username_3**: @brandon is their a way to delete an asset in this manner in Craft 3?  
> **username_1**: @kinoli 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:
$('#delete-file').click(function() {
    var data = {
        fileId: 100
    };

    $.post('/actions/assets/deleteFile', data, function(response) {
        // ...
    });
});

Craft 3:
$('#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 that provides its own controller that does its own permission checking and handles the file deletion. It would look something like this:
Craft 2:
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:
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**: @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`.  

---

