George12's avatar

Form with delete button vs Span element

Hello,

I just saw this tutorial https://laracasts.com/series/learning-vue-step-by-step/episodes/16 which 'encourages' - I think - to have a form with only a button for deletion like this

<form method="POST" 
.....
  >
    {{ method_field('DELETE') }}
    {{ csrf_field() }}

    <button type="submit">Delete Post</button>
</form>

until now i was using the following code

            <span @click="deletePost(post)" >Delete post</span>

Both approaches work fine but I am more interested in good practices so I was wondering which is the best approach and why? Which one do you use?

0 likes
16 replies
pmall's avatar

Destroy actions are fired from routes with DELETE http method. So either you send it via a form or via ajax.

If you use GET http method then csrf protection is not active and it is bad.

You can do anything you want as long as csrf protection is used.

1 like
InaniELHoussain's avatar

the first one is more secure than the second, yet I'd go for the second since its simple and 'clear'

d3xt3r's avatar

I was wondering which is the best approach and why?

Both and none. It depends on your use case, if you have API oriented approach, go with later, else go with former. The former requires full page reload vs usually a json response in case of later.

pmall's avatar

@d3xt3r If second approach use GET http method then yes is is less secure because id does not go through csrf protection.

If it uses DELETE http method (I don't know from the code above) then it's ok.

1 like
miigaa's avatar

I've created a directive for that. It is very easy to use. If the delete button was clicked it's gonna ask confirmation then submit a delete form with csrf token.

Here is the directive:

import swal from 'sweetalert';

module.exports = {
    isLiteral: true,

    bind: function () {
        var _this = this;

        this.el.addEventListener('click', function (e) {
            e.preventDefault();
            
            swal({
                title: "Are you sure?",
                text: "You're deleting a data!",
                type: "warning",
                showCancelButton: true,
                confirmButtonColor: "#DD6B55",
                confirmButtonText: "Yes, Go",
                cancelButtonText: "Cancel",
                closeOnConfirm: false 
            }, function () {
                $('<form method="POST" action="'+ _this.expression +'"><input type="hidden" name="_method" value="DELETE" /><input type="hidden" name="_token" value="'+ App.csrfToken +'" /></form>')
                    .submit();
            });

        }.bind(this));
    }
}

----------

Vue.directive('safe-delete', require('path-to-directive'));

And use it wherever you want like this

<a v-safe-delete="{{ url()->route('route-to-destroy') }}" class="btn btn-danger">Delete</a>
2 likes
d3xt3r's avatar

@pmall Hmm, thats true even with the form, right? method=GET. I was comparing against the same methods though, assuming the backend is same for both the ways.

pmall's avatar

@d3xt3r first post use method="POST" and method_field('DELETE').

pmall's avatar

IMHO using a form is way cleaner than a vue directive. It is a lot of code and it rely on vue. You can use a partial if you dont want to write your form many time :

# partials/delete_button.blade.php
<form method="POST" action="{{ $action }}">
    {{ method_field('DELETE') }}
    {{ csrf_field() }}
    <button type="submit">{{ isset($placeholder) ? $placeholder : 'Delete' }}</button>
</form>
# Use it anywhere
@include('partials.delete_button', ['action' => route('foos.destroy', $foo)])
d3xt3r's avatar

@pmall I don't understand where it is coming from. As stated

Both approaches work fine but I am more interested in good practices

so if the form uses 'delete' verb i assumed that the deletePost(post) method would have been structured/written in a way such that it also uses delete forcing the csrf protection to be enabled by default.

I which case, i don't understand why is one safer than the other

pmall's avatar

I which case, i don't understand why is one safer than the other

If both pass through csrf protection then they are both as safe as the other

d3xt3r's avatar

Yes, my point exactly. Thanks for conforming though :)

ohffs's avatar

@pmall I think the vue thing gives you an 'are you sure y/n' box rather than just doing a 'form with vue'.

I have a similar bit of plain JS that uses bootstrap's modal in places where people might click 'delete' and it has bigger consequences than just removing a single minor resource (if they delete one of their own 'blog posts' or whatever, meh. If they delete a whole department from the organisation I'll have a bad day... ;-)

Sadly, even a 'Are you sure?' isn't always enough mind you - but that's humans for you... ;-)

pmall's avatar

I think the vue thing gives you an 'are you sure y/n' box rather than just doing a 'form with vue'.

It is pretty easy to add this in a partial.

ohffs's avatar

Indeed - my JS blob is a partial too - just mentioning that they weren't just doing a "vue for vue's sake" :-)

Please or to participate in this conversation.