Laravel delete method not working with DELETE verb - laravel-5

In my routes file, I have
Route::delete('events/{events}', ['as' => 'events_delete', 'uses' => 'Admin\EventsController#destroy'] );
In my view file I have
<em class="fa fa-trash"></em>
This does not work. When I change the route to
Route::get('events/{events}', ['as' => 'events_delete', 'uses' => 'Admin\EventsController#destroy'] );
it does work. However I don't like the idea of using a GET verb to delete items instead of the DELETE verb. It feels like a trick...
How can I change the form code to make sure it sends a DELETE verb?
Solution 1 (from TheFallen): with DELETE VERB in routes file
<form action="{!! route('events_delete', ['id' => $event->id ]) !!}" method="POST">
{{ method_field('DELETE') }}
{{ csrf_field() }}
<button class="btn btn-danger btn-sm" type="submit"><em class="fa fa-trash"></em></button>
</form>
Solution 2: with GET VERB in routes file
<em class="fa fa-trash"></em>

You have to make a delete request to use the route this way, which you can do with a form, otherwise with the anchor you're making a get request.
If you already don't have the laravelcollective/html package install it from composer to use the forms facade. Then you can make the request like this:
{!! Form::open(['method' => 'DELETE', 'route' => $yourRoute]) !!}
{!! Form::submit('Delete') !!}
{!! Form::close() !!}
EDIT:
Without the forms facade:
<form action="{{ $yourRoute }}" method="POST">
{{ method_field('DELETE') }}
{{ csrf_field() }}
<button class="btn btn-danger btn-sm" type="submit"><em class="fa fa-trash"></em></button>
</form>

That will produce a GET request, therefore it will not match Route::delete
HTML forms do not support PUT, PATCH or DELETE actions. So, when defining PUT, PATCH or DELETE routes that are called from an HTML form, you will need to add a hidden _method field to the form.
Refer: https://laravel.com/docs/master/routing#form-method-spoofing
To call the delete route, you have to implement using jquery
<a eventid="{{$event->id}}" href="#" type="button" class="btn btn-sm btn-danger"><em class="fa fa-trash"></em></a>
$(document).on("click",".anchorclass",function(e){
e.preventDefault();
if(!confirm("Are you sure?")) return;
$.ajax({
type: "DELETE",
url: 'events/'+$(this).attr("eventid"),
success: function(data) {
//Process results
}
});
});

Related

The DELETE method is not supported for this route. Supported methods: GET, HEAD, POST

I am creating an index form that displays some data. Everything is ready but when I make the delete button I get an error "The DELETE method is not supported for this route. Supported methods: GET, HEAD, POST."
Route
Route::group(['middleware' => ['auth']], function() {
Route::resource('roles','RoleController');
Route::resource('users','UserController');
Route::resource('kamar_theresia','Kamar_TheresiaController');
});
Controller
public function destroy($id)
{
Kamar_Theresia::find($id)->delete();
return redirect()->route('kamar_theresia.index')
->with('success','Kamar Theresia deleted successfully');
}
View
#foreach ($kamar_theresia as $tere)
<tr>
<td>{{ ++$i }}</td>
<td>{{ $tere->nama }}</td>
<td>{{ $tere->name }}</td>
<td>{{ $tere->ketersediaan }}</td>
<td>
#can('theresia-delete')
{!! Form::open(['method' => 'DELETE','route' => ['kamar_theresia.destroy', $tere->id],'style'=>'display:inline']) !!}
{!! Form::submit('Delete', ['class' => 'btn btn-danger']) !!}
{!! Form::close() !!}
#endcan
</td>
</tr>
#endforeach
That's because the you're passing DELETE method as the method of your form, and it is wrong, the right thing to do is pass de POST method.
Check this example:
<form action="{{ route('kamar_theresia.destroy', $tere->id) }}" method="POST">
#csrf
#method('delete')
<button type="submit" class="btn btn-outline-danger">Delete</button>
</form>
Your controller should be:
public function destroy(Kamar_Theresia $khamar_teresia)
{
$khamar_teresia->delete();
return redirect()->route('kamar_theresia.index')
->with('success','Kamar Theresia deleted successfully');
}
Make sure you do not have your form inside another form. I made this silly mistake and got the same error message.
Looks like you're almost there! I would use POST for the form similar to this:
{{ Form::open(['method' => 'POST', 'route' => ['kamar_theresia.destroy']) }}
{{ Form::hidden('id',$tere->id) }}
{{ Form::submit('Delete') }}
{{ Form::close() }}
and then in your controller
public function destroy(Request $request){
$id = $request->input('id');
Kamar_Theresia::find($id)->delete();
The rest of your code should be ok. Let me know if this doesn't work.
Use the {{ csrf_field() }} and {{ method_field('DELETE') }} into Form.
{{ csrf_field() }}
{{ method_field('DELETE') }}
Use this into Controller
public function destroy($id)
{
$delete = kamar_theresia::find($id);
$delete->delete();
return redirect('/')->with('deleted','Kamar Theresia deleted successfully');
}
if we are using Route::resource() then it will be automatically route with destroy function.
Forgot to put slash in action at start:
<form method="POST" action={{--here=> --}}"/save_edit_delete_order/{{$order_id}}">
#csrf
#method('delete')
......
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Yes, I am</button>
</div>
</div>
</form>
And in resource Controller:
public function destroy($id)
{
return 'kuku';
}
view
<form action="{{route('command.delete',[$command->id,$command->car_id])}}" method="post">
#csrf
{{method_field('delete')}}
<button type="submit" class="btn btn-danger"><i class="fa fa-trash"></i></button>
</form>
web
Route::delete('/commands/{commandId}/{carId}/delete','CommandController#deleteUserCommands')->name('command.delete');

Submitting Data, Error: Symfony \ Component \ HttpKernel \ Exception \ MethodNotAllowedHttpException No message

<form action="upload_creation" method="post">
<div class="modal-footer">
<button type="button" class="btn btn-link" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Send</button>
</div>
</form>
this is my code for form, i want to submit a file with button
public function upload_creation(Request $request){
$input = $request->all();
$creation = $this->creationRepository->create($input);
foreach($request->file('direktori_gambar') as $image)
{
$name=time().$image->getClientOriginalName();
$image->move(public_path().'/public/img', $name);
$input['pictureName']=$image->getClientOriginalName();
$input['pictureFile']='/public/img/'.$name;
$mediaUkm = $this->creationPictRepository->create($input);
}
return view('webgallery.desktugas')->with($this->data);
this is the controller i referred to in form Action
after i click the submit button, it came up as no message error on laravel
any idea how to fix this?
Which method do you use in your <form> in your template?
If the route is post() (like it is in your routes) then you also need POST as method in your form.
If you have POST as method in the <form>-Tag, look if you have a hidden-input-field called _method.
More details here
https://laravel.com/docs/5.5/routing#form-method-spoofing
this is your route in web.php locatated in routes/ folder.
first create route in web.php
web.php
Route::post('upload-creation', 'CreationController#newCreation')->name('upload-creation');
And in form use route name to give action on file submit
<form action="{{route('upload-creation')}}" method="post">
{{ csrf_field() }}
<div class="modal-footer">
<button type="button" class="btn btn-link" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Send</button>
</div>
</form>
use enctype="multipart/form-data" in your form tag
example:
also don't forget to add {{ csrf_field() }}
You need to add a hidden input to your form to include your csrf token.
Laravel 5.6, 5.7
<form action="upload_creation" method="post">
#csrf
<div class="modal-footer">
<button type="button" class="btn btn-link" data-dismiss="modal">Cancel</button>
<button type="submit" class="btn btn-primary">Send</button>
</div>
</form>
For reference visit the Documentation.
For older versions of laravel, the syntax is slightly different:
{{ csrf_field() }}
you can use Form Helper using Laravel Collectives
Begin by installing this package through Composer. Run the following from the Terminal:
composer require "laravelcollective/html":"^5.2.0"
Next, add your new provider to the providers' array of config/app.php:
'providers' => [
// ...
Collective\Html\HtmlServiceProvider::class,
// ...
],
Finally, add two class aliases to the aliases array of config/app.php:
'aliases' => [
// ...
'Form' => Collective\Html\FormFacade::class,
'Html' => Collective\Html\HtmlFacade::class,
// ...
],
Opening & Closing Form
{{ Form::open(['url' => route('upload-creation')]) }}
// default method is post, you can change by adding **method** key
{{ Form::close() }}
it will automatically generate the #csrf code which will be hidden but will be available during request submission

Search result breaks delete action

I have a page where I display campaigns. I wont show all the code but the basic structure is like so
#foreach ($campaigns as $campaign)
{!! Form::open(array('class' => 'form-inline delete', 'method' => 'DELETE', 'route' => array('campaigns.destroy', $campaign->id))) !!}
<div class="panel panel-default">
#if (!empty($campaign->campaignName))
<div class="panel-heading campaignPanelHeading">
<h4>{{ $campaign->campaignName }}</h4>
</div>
<div class="panel-footer">
<a href="{{ route('campaigns.destroy', $campaign->id) }}" class="btn btn-danger" id="deleteCampaign" data-method="delete" data-token="{{ csrf_token() }}">
Delete
</a>
</div>
#endif
</div>
{!! Form::close() !!}
#endforeach
If I try to delete an item, the following is triggered.
$("#deleteCampaign").on("submit", function(){
return confirm("Do you want to delete this item?");
});
Now on this page where I display all campaigns I have a search box. You start typing and an autocomplete list displays. When you select an option, this is triggered
select: function (event, ui) {
$.ajax({
url: "/returnDataForCampaigns",
type: "GET",
datatype: "html",
data: {
value : ui.item.value
},
success: function(data) {
$('.container').html(data.html);
$('.selectpicker').select2();
}
});
},
This essentially calls a function which gets the selected Campaign, and injects it into the following partial
#if(!empty($campaign))
{!! Form::open(array('class' => 'form-inline delete', 'method' => 'DELETE', 'route' => array('campaigns.destroy', $campaign->id))) !!}
<div class="panel panel-default">
#if (!empty($campaign->campaignName))
<div class="panel-heading campaignPanelHeading">
<h4>{{ $campaign->campaignName }}</h4>
</div>
<div class="panel-footer">
<a href="{{ route('campaigns.destroy', $campaign->id) }}" class="btn btn-danger" id="deleteCampaign" data-method="delete" data-token="{{ csrf_token() }}">
<span class="glyphicon" aria-hidden="true"></span>
Delete
</a>
</div>
#endif
</div>
{!! Form::close() !!}
#endif
Finally, this data is then injected into the page's container. Now this all works fine. When I check the source after it has been injected everything looks correct.
I have 2 other buttons which I removed above which show or edit the campaign, these work fine. The thing that is not working is the delete button for the searched campaign. For some reason when I click this it goes to the campaigns show page. This button works when I display all campaigns, its only when search is performed it does not work.
I have checked the code for the delete button for when all campaigns are displayed vs a searched campaign. Everything is the same apart from the Javascript which has been applied to the delete button when all campaigns are shown as well as some hidden inputs
<a data-token="dsfsd" data-method="delete" id="deleteCampaign" class="btn btn-danger" onclick=" if ($(this).hasClass('action_confirm')) { if(confirm($(this).data('message') || "Are you sure you want to do this?")) { $(this).find("form").submit(); } } else { $(this).find("form").submit(); }">
Delete
<form style="display:none" method="POST" action="http://localhost:8000/campaigns/43">
<input type="hidden" value="delete" name="_method">
<input type="hidden" value="dsfsd" name="_token">
</form>
</a>
This is a searched button
<a data-token="dsfsd" data-method="delete" id="deleteCampaign" class="btn btn-danger" href="http://localhost:8000/campaigns/9">
Delete
</a>
So my main question is why this may be happening? I would also like to try and find out why the searched version of the delete button also takes you to the show page?
Any advice appreciated
Thanks
Try this for your delete jquery code:
$(document).on("submit", "#deleteCampaign", function(e){
e.preventDefault();
return confirm("Do you want to delete this item?");
});
Its because you are adding content after DOM load.

Laravel href with POST

I'm trying to pass some data to my controller with an action href. I don't know why, but laravel passes the data with GET method, but instead of GET I need a POST. I don't really understand why laravel does that and coulnd't find an answer. I did that multiple times and my syntax seems to be correct. Can somebody have a look over it?
Blade:
<td>
#foreach($products as $product)
<a href="{{ action('ProductsController#delete', $product->id ) }}">
<span class="glyphicon glyphicon-trash"></span></a>
{{ $product->name }},
#endforeach
</td>
My Route:
Route::post('delete', ['as' => 'delete', 'uses' => 'ProductController#delete']);
In my Controller is just a:
public function delete()
{
return 'hello'; // just testing if it works
}
Error:
MethodNotAllowedHttpException in RouteCollection.php line 219....
I know it's a get method, cause if I'm trying to pass the data to my controller, my URL looks like this:
blabla.../products/delete?10
Is anything wrong with my syntax? I can't really see why it uses the get method.
I also tried a: data-method="post" insite of my <a> tag but this haven't worked either.
Thanks for taking time.
When you make a link with an anchor like <a href=example.com> your method will always be GET. This is like opening a URL in your browser, you make a GET request.
You should use a form to make that POST request to the delete method of the controller. Assuming you have the Illuminate HTML package for HTML and forms, you could do this:
{!! Form::open(['method' => 'DELETE', 'route' => $route]) !!}
{!! Form::submit('delete', ['onclick' => 'return confirm("Are you sure?");']) !!}
{!! Form::close() !!}
EDIT:
With a button tag:
{!! Form::open(['method' => 'DELETE', 'route' => $route]) !!}
<button type="submit"><i class="glyphicon glyphicon-remove"></i>Delete</button>
{!! Form::close() !!}
Here's your problem:
<a href="{{ action('ProductsController#delete', $product->id ) }}">
Anchor tags are always submitted over GET. It's a HTTP built in and is not Laravel specific.
POST is used when a form is submitted that specifies the POST HTTP Verb or the HTTP method is invoked by an AJAX request that specifies POST as the HTTP Verb.
Instead consider a submit type button in a form that submits what you need.
<td>
#foreach($products as $product)
<form method="POST" action="{{ route('delete') }}">
<input type="hidden" name="product_id" value="{{ $product->id }}">
{!! csrf_field() !!}
<button type="submit" class="btn">
<span class="glyphicon glyphicon-trash"></span>
</button>
</form>
{{ $product->name }},
#endforeach
</td>
And then in your controller:
public function delete()
{
// 'Die Dump' all of the input from the form / request
dd( request()->input()->all() );
// 'Die Dump' the specific input from the form
dd( request()->input('product_id') );
}
You will begin to see how GET and POST requests differ in sending of key/value pairs.
For more information:
http://www.tutorialspoint.com/http/http_methods.htm
Best for laravel 7. First define the form with given form id.
#auth
<form id="logout-form" action="{{ route('logout') }}" method="POST"
style="display: none;">
#csrf
</form>
#endauth
Then you can use the anchor tag for logout operation.In background,javascript working.Wherever the logout was fire then action to given form method of post method and logout route was working.
<a class="nav-link dropdown-toggle text-muted waves-effect waves-dark"
href="{{ route('logout') }}" onclick="event.preventDefault();document.getElementById('logout-form').submit();"
id="2" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="mdi mdi-logout"></i>
</a>
Most benefit is the form was not loaded unnecesory.If the user was
logged in so far its load otherwise not
Laravel 7
By jQuery:
<form id="form" action="{{route('route_name')}}" method="POST">#csrf</form>
By JS:
<form id="form" action="{{route('route_name')}}" method="POST">#csrf</form>

laravel 5 not deleting user record

All i want to do is simply delete a user form the database.
My Route is a resource as seen below:
Route::resource('users', 'UserController');
So this should mean that the destroy action in my UserController should be the place for my code.
So my controller action is below:
public function destroy($id)
{
$user = User::find($id);
$user->delete();
return Redirect::back();
}
Now when i click the delete button, which links to /users/destroy/4
it should find the user with id 4 and then delete it.
Instead i get the error
NotFoundHttpException in RouteCollection.php line 145:
EDIT:
#foreach ($users as $user)
<tr>
<td>{{ $user->id }}</td>
<td>{{ $user->username }}</td>
<td>{{$user->HWID}}</td>
<td>{{$user->name}}</td>
<td class="tools">
<i class="fa fa-pencil-square-o fa-lg"></i>
<i class="fa fa-trash fa-lg"></i>
</td>
</tr>
#endforeach
I dont know if it's possible to directly delete a user from your database via a link as you specified in your table.
My work around for this is to first point the user to the show function in your controller. And giving the user an overview of the information of the user itself.
This page contains a form with the DELETE method. Below the information of the user I put a delete button which will submit the form with the DELETE method to the URL: /users/4
Cause the link: /users/destroy/4 is not a valid resource link.
See this link for extra information about the resource controller links: Resource Controller
Example delete/show page of my own application:
{!! Form::model($ManagementUser, array('method' => 'DELETE', 'url' => 'admin/management/' . $ManagementUser->id, 'role' => 'form')) !!}
<div class="box-body">
<div class="form-group">
<label>Name</label>
{!! Form::text('name', Input::old('name'), array('class' => 'form-control', 'placeholder' => 'Name', 'name' => 'name', 'disabled')) !!}
</div>
<div class="form-group">
<label>E-mailaddress</label>
{!! Form::text('email', Input::old('email'), array('class' => 'form-control', 'placeholder' => 'E-Mail', 'name' => 'email', 'disabled')) !!}
</div>
{!! Form::submit('Delete', array('class' => 'btn btn-block btn-default')) !!}
</div>
{!! Form::close() !!}
In Resource Controller, destroy action is handled by DELETE method. Not GET method. Currently you are accessing a route with GET method that is not registered. The following command will help you to understand Resource Routes that you registered.
php artisan route:list
GET
<i class="fa fa-trash fa-lg"></i>
DELETE (You can delete the record by using form and DELETE method as follows)
<form action="{{ route('users.destroy', $user->id) }}" method="POST">
<input type="hidden" name="_method" value="DELETE" />
<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>" />
<button><i class="fa fa-trash fa-lg"></i></button>
</form>
Reference
Resource Controller
Method Spoofing

Resources