use DELETE method in route with Laravel 5.4 - php

I'm working on a Laravel (v 5.4) project and i did the CRUD to manage categories. Currently, i can create a new category and i would be able to delete.
I created the view (with blade) to delete the categories :
<table class="table">
<thead>
<th>Name</th>
<th>Action</th>
</thead>
<tbody>
#foreach ($categories as $category)
<tr>
<td>$category->name</td>
<td>
<a href="{{ url('/categories', ['id' => $category->id]) }}">
<button class="btn btn-default">
Delete
</button>
</a>
</td>
</tr>
#endforeach
</tbody>
</table>
And in the routing file web.php, i wrote :
Route::delete('/categories/{id}', CategoryController#destroy);
I have a controller CategoryController with a method destroy() who delete category and redirect to list of categories. But when i click on the button to delete, i get an error that explain this route is not define. If i replace Route::delete with Route::get it works. I think the url is called with GET but i would keep that for an other action.
I tried to replace the link with a form and "DELETE" as the value of "method" attribute but it didn't work.
How can i call url with DELETE method to catch it with Route::delete ?
Thanks in advance.

If you click on an url it will always be a GET method.
Since you wish to define it as DELETE, you should remake it into a post form and add
<input type="hidden" name="_method" value="delete" />
in it. Like replace:
<a href="{{ url('/categories', ['id' => $category->id]) }}">
<button class="btn btn-default">Delete</button>
</a>
with:
<form action="{{ url('/categories', ['id' => $category->id]) }}" method="post">
<input class="btn btn-default" type="submit" value="Delete" />
<input type="hidden" name="_method" value="delete" />
<input type="hidden" name="_token" value="{{ csrf_token() }}">
</form>
Same goes for PUT request.
Since Laravel 5.1 method_field:
<form action="{{ url('/categories', ['id' => $category->id]) }}" method="post">
<input class="btn btn-default" type="submit" value="Delete" />
{!! method_field('delete') !!}
{!! csrf_field() !!}
</form>
Since Laravel 5.6 just with # tag:
<form action="{{ url('/categories', ['id' => $category->id]) }}" method="post">
<input class="btn btn-default" type="submit" value="Delete" />
#method('delete')
#csrf
</form>

For laravel 5.7 please look my example:
<form action="{{route('statuses.destroy',[$order_status->id_order_status])}}" method="POST">
#method('DELETE')
#csrf
<button type="submit">Delete</button>
</form>

Any method other than GET and POST requires you to specify the method type using a hidden form input. That's how laravel detects them. In your case you need to send the delete action using a form. Do this.
<table class="table">
<thead>
<th>Name</th>
<th>Action</th>
</thead>
<tbody>
#foreach ($categories as $category)
<tr>
<td>$category->name</td>
<td>
<form action="/categories/{{ $category->id }}" method="post">
{{ method_field('delete') }}
<button class="btn btn-default" type="submit">Delete</button>
</form>
</td>
</tr>
#endforeach
</tbody>
</table>

Related

How to pass correct data from a dynamic button in Laravel 5.8

I have a dynamic buttons where it produced from my database
My code for that in blade file
<div class="input-group col-sm-12">
<!--start of the form-->
<form class="form-horizontal" method="POST" action="{{ route('call.store') }}">
{{ csrf_field() }}
<!--input type hidden department code below -->
#foreach($departments as $department)
<input type="hidden" id="dept_name" name="dept_name" value="{{ $department->dept_name }}">
<input type="hidden" id="called" name="called" value="NO">
<!--buttons -->
<button type="submit" class="btn btn-success btn-fill pull-right" id="form-button-add">
{{ $department->dept_name }}
</button>
#endforeach
</form>
<!--end-->
</div>
Whenever I click either one, they'all add a data in my call database based on the values per button. My problem is when I click the cashier button, the values that would add would be the assessments.
My code in CallController
public function store(Request $request)
{
$dept_id = Department::select('id')
->where('dept_name', $request->input('dept_name'))
->first();
$let = Department::select('letter')
->where('dept_name', $request->input('dept_name'))
->first();
$number = Department::select('start')
->where('id', $dept_id->id)
->first();
$call = Call::create([
'dept_id' => $dept_id->id,
'letter' => $let->letter,
'number' => $number->start,
'called' => $request->input('called')
]);
Department::where('id', $dept_id->id)
->increment('start');
return redirect()->route('call.index')->with('success' , 'NEW CALL');
}
I also dd each query and found out that the values would get are the values from assessment or the last value from the foreach loop in my blade file. How could I get the value of cashier when I click the cashier button instead of assessment.
I would show my database so that you understand my question
Department Table: id, dept_name, letter, start(int, it'll increment after producing a call)
Counter: id, counter_num, dept_id
Call Table: id, dept_id, letter, number, counter_id, called
When you click either button, they will submit their parent form. Because both are under the same form, the data from the first button will be submitted. You will have to make a separate form for each button in order to have them submit their own data.
<div class="input-group col-sm-12">
#foreach($departments as $department)
<form class="form-horizontal" method="POST" action="{{ route('call.store') }}">
{{ csrf_field() }}
<input type="hidden" id="dept_name" name="dept_name" value="{{ $department->dept_name }}">
<input type="hidden" id="called" name="called" value="NO">
<button type="submit" class="btn btn-success btn-fill pull-right" id="form-button-add">
{{ $department->dept_name }}
</button>
</form>
#endforeach
</div>
You're creating multiple submit buttons in the same form.
Add the tag inside the loop so you have a unique form per case.
When there's multiple submit buttons inside the same form, the loop will finish and only the last results will be mapped to the buttons, thus is will submit the last information in your loop.
#foreach($departments as $department)
<form class="form-horizontal" method="POST" action="{{ route('call.store') }}">
{{ csrf_field() }}
<input type="hidden" id="dept_name" name="dept_name" value="{{ $department->dept_name }}">
<input type="hidden" id="called" name="called" value="NO">
<!--buttons -->
<button type="submit" class="btn btn-success btn-fill pull-right" id="form-button-add">
{{ $department->dept_name }}
</button>
</form>
#endforeach

Laravel Blade template Form::open() to Html

I am following a tutorial about Laravel.
However, I want to convert the blade template Form::open() to html/php form, to make it easier to read & understand.
This is the Blade template:
{{ Form::open(['action'=> ['StudentController#destroy', $student->id], 'method'=>'POST']) }}
{{ method_field('DELETE') }}
{{ Form::submit('Delete',['class'=>'btn btn-danger']) }}
{{ Form::close() }}
I need to convert the blade code to html/php
I tried it multiple times, something like this. but failed.
<form action="url('StudentController#destroy', $student->id)" method="POST">
<?php method_field('Delete'); ?>
<button class="btn btn-danger" type="submit">Delete</button>
</form>
Anyone know the correct html/php form?
[edit] Route:list
try this way
use {{}} and use route
<form action="{{route('StudentController#destroy', ['id'=>$student->id])}}" method="POST">
<?php method_field('Delete'); ?>
<button class="btn btn-danger" type="submit">Delete</button>
</form>
To call a controller action you need to use url()->action(...) (or action()) for short.
<form action="{{url()->action('StudentController#destroy', ['id'=>$student->id])}}" method="POST">
#csrf
{{ method_field('DELETE'); }}
<button class="btn btn-danger" type="submit">Delete</button>
</form>
This is also described in the manual
you should use this code
<form action="{{ url('StudentController#destroy', $student->id) }}" method="POST">
<input type='_method' value='DELETE' />
<button class="btn btn-danger" type="submit">Delete</button>
</form>
In your 'action' on the form, you need to enclose any helper functions within brackets so that Blade knows what to do with this, otherwise, it's just text.
Also note, I removed 'method_field' and replaced it with the hidden field, as this is essentially what method_field helper creates.
<form action="{{route('StudentController#destroy', ['id' => $student->id])}}" method="POST">
<input type='hidden' value='DELETE'>
<button class="btn btn-danger" type="submit">Delete</button>
</form>
If using the route helper isn't working, you could use a more simple approach for the 'action' param of the form tag:
<form action="/student/destroy/{{$student->id}}" method="POST">

Laravel delete button with HTML form

I'm using the HTML form, not Laravel Collective.
For now I've successfully created a CRUD for a users in my CMS, but one thing bothers me:
How can I set a Delete button in my list of users, instead of the specific edit page?
Also, it will be nice when a user clicks on the Delete button to show up confirmation popup for deleting the specific user.
So, here's my code:
The controller:
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function destroy($id)
{
$user = User::findOrFail($id);
$user->delete();
return redirect('/admin/users');
}
The list of users page:
#extends('layouts.backend')
#section('content')
<h1>Users</h1>
<a class="btn btn-primary" href="/admin/users/create">Create new user</a>
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Email</th>
<th>Role</th>
<th>Status</th>
<th>Created</th>
<th>Updated</th>
<th>Operations</th>
</tr>
</thead>
<tbody>
#if($users)
#foreach($users as $user)
<tr>
<td>{{$user->id}}</td>
<td>{{$user->name}}</td>
<td>{{$user->email}}</td>
<td>{{$user->role ? $user->role->name : 'User has no role'}}</td>
<td>{{$user->status == 1 ? 'Active' : 'Not active'}}</td>
<td>{{$user->created_at->diffForHumans()}}</td>
<td>{{$user->updated_at->diffForHumans()}}</td>
<td>
Edit
<a class="btn btn-danger" href="">Delete</a> // HOW TO ACHIEVE THIS?
</td>
</tr>
#endforeach
#endif
</tbody>
</table>
#endsection
The specific edit user page:
#extends('layouts.backend')
#section('content')
<h1>Edit user</h1>
<form method="POST" action="/admin/users/{{$user->id}}">
{{ csrf_field() }}
{{ method_field('PATCH') }}
<div class="form-group">
<label>Name:</label>
<input type="text" name="name" class="form-control" value="{{$user->name}}">
</div>
<div class="form-group">
<label>Email:</label>
<input type="text" name="email" class="form-control" value="{{$user->email}}">
</div>
<div class="form-group">
<label>Role:</label>
<select name="role_id" class="form-control">
#if($user->role_id == 1)
<option value="1" selected>Administrator</option>
<option value="2">Editor</option>
#else
<option value="1">Administrator</option>
<option value="2" selected>Editor</option>
#endif
</select>
</div>
<div class="form-group">
<label>Status:</label>
<select name="status" class="form-control">
#if($user->status == 1)
<option value="1" selected>Active</option>
<option value="0">Not active</option>
#else
<option value="1">Active</option>
<option value="0" selected>Not active</option>
#endif
</select>
</div>
<div class="form-group">
<label>Password</label>
<input type="password" name="password" class="form-control" value="{{$user->password}}">
</div>
<div class="form-group">
<input type="submit" name="submit" value="Update user" class="btn btn-primary">
</div>
</form>
<form id="delete-form" method="POST" action="/admin/users/{{$user->id}}">
{{ csrf_field() }}
{{ method_field('DELETE') }}
<div class="form-group">
<input type="submit" class="btn btn-danger" value="Delete user">
</div>
</form>
#include('inc.errors')
#endsection
The route:
Route::group(['middleware'=>'admin'], function(){
Route::resource('admin/users', 'AdminUsersController');
Route::get('/admin', function(){
return view('admin.index');
});
// Route::resource('admin/posts', 'AdminPostsController');
});
It's not obvious from the code you posted, but your DELETE route expects DELETE method. As it should!
But on your list you're trying to access it with GET method.
Really you should just reuse the code from the edit page, which fakes DELETE method already.
Something like this:
...
<td>
Edit
<form method="POST" action="/admin/users/{{$user->id}}">
{{ csrf_field() }}
{{ method_field('DELETE') }}
<div class="form-group">
<input type="submit" class="btn btn-danger delete-user" value="Delete user">
</div>
</form>
</td>
...
...
// Mayank Pandeyz's solution for confirmation customized for this implementation
<script>
$('.delete-user').click(function(e){
e.preventDefault() // Don't post the form, unless confirmed
if (confirm('Are you sure?')) {
// Post the form
$(e.target).closest('form').submit() // Post the surrounding form
}
});
</script>
As you have stated it will be nice when a user clicks on the Delete button to show up confirmation popup for deleting the specific user. For this you have to use jquery and ajax. Change the following code:
<a class="btn btn-danger" href="">Delete</a>
to
<a class="btn btn-danger delete_user" href="javascript:void(0);" id="{{$user->id}}">Delete</a>
and put an event listener like:
$('.delete_user').click(function(){
if( confirm('Are you sure?') )
{
var id = $(this).attr('id');
// Make an ajax call to delete the record and pass the id to identify the record
}
});
You can update your code like:
<a class="btn btn-danger" href="/admin/users/{{$user->id}}/delete" >Delete</a>
OR you should delete user using route name like:
Delete
option with "laravel form helper" and jquery
<div class="actions">
<a href="#" class="list-icons-item delete-action">
<i class="icon-trash"></i>
</a>
{{ Form::open(['url' => route('admin.users.destroy', $user), 'method' => 'delete']) }}
{{ Form::close() }}
</div>
<script>
$(document).ready(function () {
$('.delete-action').click(function (e) {
if (confirm('Are you sure?')) {
$(this).siblings('form').submit();
}
return false;
});
});
</script>
Using route closures to delete
show.blade.php
<form>
<h1>Title: {{$tutorial->title}}</h1>
<p>Title Description: {{$tutorial->title_description}}</p>
<p>Video: {{$tutorial->video}}</p>
<form action="{{ route('delete-tutorial', [$tutorial->id])}}"
method="post">
#csrf
#method('DELETE')
<button class="btn btn-primary" onclick="return confirm('Are you sure?')"
type="submit" name="Delete">Delete</button>
</form>
for the route for deleting
Route::delete('tutorial/{id}',function($id){
$tutorial = Tutorial::findOrFail($id)->first();
$tutorial->delete();
return redirect('tutorial');
})->name('delete-tutorial');
Also don't forget to add this on your routes/web.php
use App\Models\Tutorial;

Delete a record gave me NotFoundException in laravel 5

How can I create multiple requests for the same route like below.
Route.php
Route::get('/home', 'HomeController#index');//->middleware('auth');
Route::get('/home/{$user}','HomeController#showStudent');
Route::delete('/home/{$studentId}','HomeController#deleteStudent');
the form was working fine until I have added the delete request. In my blade template I have code something like this.
home.blade.php
<form class="" role="form" method="DELETE" action="/home/{{$student->id}}">
{{ csrf_field() }}
<td><button type="submit" class="btn btn-primary pull-right">Remove Student</button></td>
</form>
I believe because of the same routes it's showing NotFoundHTTPException.
On one route /home I am trying to Add, Show, Edit and Delete a record with different buttons.
Thanks in Advance.
You could add a form and use Laravel's Form Method Spoofing
<input type="hidden" name="_method" value="DELETE">
See more here...http://laravel.com/docs/master/routing#form-method-spoofing
Try as below....
<form class="" role="form" method="DELETE" action="/home/{{$student->id}}">
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<td><button type="submit" class="btn btn-primary pull-right">Remove Student</button></td>
</form>
1) Change you route from:
Route::delete('/home/{$studentId}','HomeController#deleteStudent');
To:
Route::get('/delete/{$Id}','HomeController#deleteStudent')->name('delete');
2) change you form tag from:
<form class="" role="form" method="DELETE" action="/home/{{$student->id}}">
To:
<form class="" role="form" method="get" action="route('delete', ['id' => $student->id])">
HTML forms doesn't support methods other than get and post. If you need to simulate it, include a hidden input to simulate delete:
<input name="_method" type="hidden" value="DELETE">
Then in your code, update it to:
<form class="" role="form" method="POST" action="/home/{{$student->id}}">
{{ csrf_field() }}
<input name="_method" type="hidden" value="DELETE">
<td><button type="submit" class="btn btn-primary pull-right">Remove Student</button></td>
</form>
Reference:
Are the PUT, DELETE, HEAD, etc methods available in most web browsers?
http://laraveldaily.com/theres-no-putpatchdelete-method-or-how-to-build-a-laravel-form-manually/

Laravel Route resource destroy not working

Here is my form :
<form action="{{ route('invoice.destroy' , $invoice->id)}}" method="DELETE">
<div class="modal-footer no-border">
<button type="button" class="btn btn-info" data-dismiss="modal">No</button>
<button type="submit" class="btn btn-primary">Yes</button>
<input type="hidden" name="_method" value="DELETE" />
</div>
</form>
Here is my controller :
public function destroy($id)
{
$invoice = Invoice::find($id);
if(!$invoice){
return redirect()->route('invoice.index')->with(['fail' => 'Page not found !']);
}
$invoice->delete();
return redirect()->route('invoice.index')->with(['success' => 'Invoice Deleted.']);
}
But it can not delete where is the problem ? How solve this ?
You need to use POST method for the form and add input element with name _method and value DELETE. Also, add token:
<form action="{{ route('invoice.destroy' , $invoice->id)}}" method="POST">
<input name="_method" type="hidden" value="DELETE">
{{ csrf_field() }}
<div class="modal-footer no-border">
<button type="button" class="btn btn-info" data-dismiss="modal">No</button>
<button type="submit" class="btn btn-primary">Yes</button>
</div>
</form>
I think you must add a hidden input to the form which will contain the method used:
<form action="{{ route('invoice.destroy' , $invoice->id)}}" method="POST">
<input type="hidden" name="_method" value="DELETE" />
</form>
Read more on Laravel documentation about Form method spoofing
In order to get PUT and DELETE methods to work, you need an additional field, since only POST and GET are possible within HTML (out-of-the-box).
The additional field will be made with the code:
{!! method_field('DELETE') !!}
So your form will look like this:
<form action="{{ route('invoice.destroy' , $invoice->id)}}" method="DELETE">
{!! method_field('DELETE') !!}
<div class="modal-footer no-border">
<button type="button" class="btn btn-info" data-dismiss="modal">No</button>
<button type="submit" class="btn btn-primary">Yes</button>
</div>
</form>
Also, if you are using blade templates, you can add the method field like so:
#method('DELETE')
More Laravel way you can do this
<form action="{{ route('invoice.destroy',$invoice->id)}}" method="POST">
#method('DELETE')
<button type="submit" class="btn btn-primary">Yes</button>
</form>

Categories