Skip to content

Instantly share code, notes, and snippets.

@JeffreyWay
Last active February 22, 2023 10:53
Show Gist options
  • Save JeffreyWay/5112282 to your computer and use it in GitHub Desktop.
Save JeffreyWay/5112282 to your computer and use it in GitHub Desktop.
Want to send a DELETE request when outside of a form? This will handle the form-creation bits for you dynamically, similar to the Rails implementation. (Requires jQuery, but doesn't have to.) To use, import script, and create a link with the `data-method="DELETE"` attribute.
/*
<a href="posts/2" data-method="delete"> <---- We want to send an HTTP DELETE request
- Or, request confirmation in the process -
<a href="posts/2" data-method="delete" data-confirm="Are you sure?">
*/
(function() {
var laravel = {
initialize: function() {
this.methodLinks = $('a[data-method]');
this.registerEvents();
},
registerEvents: function() {
this.methodLinks.on('click', this.handleMethod);
},
handleMethod: function(e) {
var link = $(this);
var httpMethod = link.data('method').toUpperCase();
var form;
// If the data-method attribute is not PUT or DELETE,
// then we don't know what to do. Just ignore.
if ( $.inArray(httpMethod, ['PUT', 'DELETE']) === - 1 ) {
return;
}
// Allow user to optionally provide data-confirm="Are you sure?"
if ( link.data('confirm') ) {
if ( ! laravel.verifyConfirm(link) ) {
return false;
}
}
form = laravel.createForm(link);
form.submit();
e.preventDefault();
},
verifyConfirm: function(link) {
return confirm(link.data('confirm'));
},
createForm: function(link) {
var form =
$('<form>', {
'method': 'POST',
'action': link.attr('href')
});
var token =
$('<input>', {
'type': 'hidden',
'name': 'csrf_token',
'value': '<?php echo csrf_token(); ?>' // hmmmm...
});
var hiddenInput =
$('<input>', {
'name': '_method',
'type': 'hidden',
'value': link.data('method')
});
return form.append(token, hiddenInput)
.appendTo('body');
}
};
laravel.initialize();
})();
Copy link

ghost commented Oct 8, 2016

Thx @Dially

@jeffochoa
Copy link

How can you test this links on laravel ?

testSomeLink() { $this->visit('link')->see('result'); }

In this case I get a method not allowed exception.

Ideas ?

@act360
Copy link

act360 commented Apr 19, 2017

I tried to modify alert layout with other js library but when i click delete it does not wait for confirm to delete.can anybody give some idea on this?

@tmomin
Copy link

tmomin commented May 16, 2017

Cant seem to get this to work.

@extends('layouts.app')

@section('title', 'Search')

@section('content')
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
    <script src="/js/laravel.js"></script>

    <div class="container theme-showcase" role="main">

        <!-- Main jumbotron for a primary marketing message or call to action -->
        <div class="jumbotron">
            <h1>Welcome to AKF Golf 2017</h1>
            <p>This site is to be used to check players on the of the tournament.</p>
        </div>

        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <table class="table table-striped table-hover">
                    <thead>
                    <tr>
                        <th>#</th>
                        <th>Name</th>
                        <th>Dollar Amount</th>
                        <th>Number of Players</th>
                        <th></th>
                        <th></th>
                    </tr>
                    </thead>
                    <tbody>
                    @foreach($sponsors as $sponsor)
                        <tr>
                            <td>{{ $sponsor->id }}</td>
                            <td>{{ $sponsor->name }}</td>
                            <td>${{ $sponsor->dollarAmount }}</td>
                            <td>{{ $sponsor->numOfPlayers }}</td>
                            <td><a href="{{ url('/sponsors', [$sponsor->id]) }}">Edit</a></td>
                            <td><a href="{{ url('/sponsors', [$sponsor->id]) }}" data-method="DELETE" data-confirm="Are you sure?">Delete</a></td>
                        </tr>
                    @endforeach
                    </tbody>
                </table>
            </div>
        </div>

    </div> <!-- /container -->

@endsection

<script src="https://cdnjs.cloudflare.com/ajax/libs/signature_pad/1.5.3/signature_pad.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>

@antoniputra
Copy link

I've made Javascript Vanilla version of this: https://gist.github.com/antoniputra/410af23ecc59b77d69dab0b2530718a1

no longer depend on jQuery anymore 😄

@kohlerdominik
Copy link

kohlerdominik commented Jan 22, 2018

This is a nice way for links. But for forms, in my opinion it's better to change the form attributes (and the "_method"-field if necessary). I couldn't find any solution for this, so i made my own script. It's built very like Jeffreys code.

Examples:

<input type="submit" value="Submit to alternative action" data-submit-action="/new-target">
<input type="submit" value="Submit to alternative target" data-submit-target="_blank">
<input type="submit" value="Submit as delete" data-submit-method="delete">
<input type="submit" value="Submit with confirmation" data-submit-confirmation="Are you sure?">
 {{ Form::submit('Submit alternative', [   'data-submit-action' => '/new-target',
                                        'data-submit-target' => '_blank',
                                        'data-submit-method' => 'delete',
                                        'data-submit-confirmation => 'Are you sure?'  ]); }}

I uploaded the full script to my own gist: https://gist.github.com/kohlerdominik/af78ecaec7a83e566e6fe8170f5f11bd

@hakankozakli
Copy link

If the event is not firing it is probably because document is not ready yet. Try this: https://gist.github.com/hakankozakli/3b76daa8cb49193f366178b98b64b71d

@a1iraxa
Copy link

a1iraxa commented Jul 4, 2018

This would even work in bootstrap-modal and dynamic inserted button.

https://github.com/a1iraxa/restful-delete-object

Return response must be:

{
    "success":true,
    "hide":false,
    "reload":false,
    "remove":false,
    "message":"Deleted!"
} 

Inspired by:
https://gist.github.com/dirkpostma/5442850

@nickdavies791
Copy link

How would I then send any data that is outside of the form to the form, if the form is appended to the body?

i.e. I have multiple checkboxes in a table. How would these get sent to the form so they can be deleted?

@kevinruscoe
Copy link

Here's a Vue version - https://gist.github.com/kevdotbadger/7dfd81d51c975156b50a717908cba891

turn your <a href="MY_PUT_URL" class="button">Go!</a> into <method-link href="MY_PUT_URL" method="PUT" classes="button">Go!</method-link>

@eemr3
Copy link

eemr3 commented May 18, 2020

Nice one Jeffrey, Thanks!

@rodrigoespinozadev
Copy link

rodrigoespinozadev commented Aug 1, 2020

Thank you @JeffreyWay just what i needed you rock!

@guilhermemuller
Copy link

Here's a simple update that uses vanilla JS and a default confirmation message: https://gist.github.com/guilhermemuller/114064dfe4e8ee49c37cce6f1a824081

@atulmahankal
Copy link

atulmahankal commented Oct 5, 2022

add <meta name="csrf-token" content="{{ csrf_token() }}" /> into head
then
Change below code

        'name': 'csrf_token',
        'value': '<?php echo csrf_token(); ?>' // hmmmm...

into

        'name': '_token',
	'value': document.getElementsByName('_token')[0].value,

else it gives 419 | PAGE EXPIRED Error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment