Laravel href with POST - laravel

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>

Related

Laravel get route view without redirect

I am making a search in website.
public function search(Request $request)
{
$search_value = $request->search_txt;
$data_res = Data::Where('text', 'like', '%' . $search_value . '%')->get();
$navbar_search = Navbar::where('id','183')->first();
return redirect(route('response', $navbar_search->slug))->with('data_res',$data_res);
}
This is my controller function. I'm getting problem that i want to display data in the same page. I need to return view to this exact 'response' route and send slug. This redirect does not work, because $data_res after redirect is empty..
Routes:
Route::post('/search/search_res', 'SearchController#search')->name('search.srch');
Route::get('/{slug}', 'FrontEndPagesController#index')->name('response');
HTML:
<form class="form-horizontal" method="POST" action="{{ route('search.srch') }}">
{{ csrf_field() }}
<div class="main search_field">
<div class="input-group">
<input type="search" name="search_txt" class="form-control" value="{{ old('search_txt') }}" placeholder=" tekstas apie paieska ?" required maxlength="200" style="padding-left: 10px !important;">
<div class="input-group-append">
<button class="btn btn-secondary" type="submit">
<i class="fa fa-search"></i>
</button>
</div>
</div>
</div>
</form>
#if(!empty($data_res))
#foreach($data_res as $data)
{{ $data->id }}
#endforeach
#endif
With my little experience, I think when you redirect to another route and includes 'with', it stores the data in session.
you may want to access in the function FrontEndPagesController#index by
$data_res = session()->get('data_res');
then, to make it available for blade file, put it in return response like
return view('your response view', compact('data_res')

the PUT method does not send messages

if necessary, I will also put the controller in check although it seems to
me that something is wrong with the method because on the output it shows me a "no message" error and nothing more
is on a piece of my view and the PUT method
{!! Form::model($cattle_inventory, array('route'=>
['cattle_inventories.update',$cattle_inventory->id,'method'=>'PUT']))!!}
<div class="form-group">
{!! Form::label('cow_name','Podaj NazwÄ™ krowy') !!}
{!! Form::text('cow_name',null, ['class'=>'form-control']) !!}
</div>
Route
Route::resource('cattle_inventories','Cattle_inventoryController')->middleware('verified');
The documentation states:
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. The value sent with the _method field will be used as the HTTP request method:
<form action="/foo/bar" method="POST">
#method('PUT')
#csrf
</form>
Hence you need to adjust your form as such. #method('PUT') simply generates the following HTML:
<input type="hidden" name="_method" value="PUT">
You can try this with Laravel collective
{!! Form::open(['route'=>['your.route', $id]]) !!}
// laravel <=5.5
{!! Form::hidden('_method', 'PUT') !!} //or {{ method_field('PUT') }}
//laravel >=5.6
#method('PUT')
{!! Form::close() !!}
Laravel collective Form model binding
{{ Form::model($cattle_inventory, ['route' => ['cattle_inventories.update', $cattle_inventory->id]]) }}

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 delete method not working with DELETE verb

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
}
});
});

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