CRUD Laravel 5 how to link to destroy of Resource Controller? - php

I have a link
<a class="trashButton" href="{{ URL::route('user.destroy',$members['id'][$i]) }}" style="cursor: pointer;"><i class="fa fa-trash-o"></i></a>
this link is supposed to direct to the destroy method of the Usercontroller , this is my route Route::resource('/user', 'BackEnd\UsersController');
UserController is a Resource Controller. But at this moment it is directing me to the show method rather than directing to the destroy method

You need to send a DELETE request instead of a GET request. You can't do that with a link, so you have to use an AJAX request or a form.
Here is the generic form method:
<form action="{{ URL::route('user.destroy', $members['id'][$i]) }}" method="POST">
<input type="hidden" name="_method" value="DELETE">
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<button>Delete User</button>
</form>
If you're using Laravel 5.1 or later then you can use Laravel's built-in helpers to shorten your code:
<form action="{{ route('user.destroy', $members['id'][$i]) }}" method="POST">
{{ method_field('DELETE') }}
{{ csrf_field() }}
<button>Delete User</button>
</form>
If you're using Laravel 5.6 or later then you can use the new Blade directives to shorten your code even further:
<form action="{{ route('user.destroy', $members['id'][$i]) }}" method="POST">
#method('DELETE')
#csrf
<button>Delete User</button>
</form>
You can read more about method spoofing in Laravel here.

This is because you are requesting the resources via GET method instead DELETE method. Look:
DELETE /photo/{photo} destroy photo.destroy
GET /photo/{photo} show photo.show
Both routes have the same URL, but the header verb identifies which to call. Looks the RESTful table. For example, via ajax you can send a DELETE request:
$.ajax({
url: '/user/4',
type: 'DELETE', // user.destroy
success: function(result) {
// Do something with the result
}
});

I use this template 'resources/views/utils/delete.blade.php'
<form action="{{ $url or Request::url() }}" method="POST">
{{ method_field('DELETE') }}
{{ csrf_field() }}
<button type='submit' class="{{ $class or 'btn btn-danger' }}" value="{{ $value or 'delete' }}">{!! $text or 'delete' !!}</button>
</form>
Called as this:
#include('utils.delete',array( 'url' => URL::route('user.destroy',$id),'text' => '<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> delete me'))

If you're looking to do this via a regular link instead of through AJAX or another type of form request you can set up a special route that will respond to a normal GET request:
In your routes, define this in addition to the resource:
Route::get('user/{site}/delete', ['as' => 'user.delete', 'uses' => 'UserController#destroy']);
In your view:
Delete this user
In your controller:
public function destroy(User $user)
{
$user->delete();
return redirect()->route('users.index');
}

If we need to use an anchor to trigger the destroy route, and we don't want to use ajax, we can put a form inside our link, and submit the form using the onclick attribute:
<a href="javascript:void(0);" onclick="$(this).find('form').submit();" >
<form action="{{ url('/resource/to/delete') }}" method="post">
<input type="hidden" name="_method" value="DELETE">
</form>
</a>

If you really want to visit the destroy action on delete route by HTML, then there is an approach to use HTTP Method Spoofing which means that you could visit a delete HTTP method by adding a hidden input named _method with the value of `"DELETE". Same way can be used for "PUT" and "PATCH" HTTP method.
Below is a sample for DELETE method.
<form action="/tasks/5" method="POST">
<input type="hidden" name="_method" value="DELETE">
</form>
will get the route
DELETE /tasks/{id} destroy tasks.destroy
if you use laravel collective, you can write this way in your views.
{!! Form::open(['url' => '/tasks/'.$cat->id, 'method' => 'delete']) !!}
{!! Form::submit('Delete', ['class' => 'btn btn-primary']) !!}
{!! Form::close() !!}

In case someone came here to find how to replace standard laravel form for delete, from button in it to link, you can just replace:
{!! Form::open(['method' => 'DELETE', 'route' => ['tasks.destroy', $task->id],'onsubmit' => 'return confirm("Are you sure?")', 'id'=>'himan']) !!}
{!! Form::submit('Delete') !!}
{!! Form::close() !!}
TO
{!! Form::open(['method' => 'DELETE', 'route' => ['tasks.destroy', $task->id],'onsubmit' => 'return confirm("Are you sure?")', 'id'=>'himan']) !!}
Delete
{!! Form::close() !!}
Just replace button with simple <a href="#"... but with onclick attribute to submit the form!

If you want to use a link, you can use a library I have created that lets people make links that behave like POST, DELETE... calls.
https://github.com/Patroklo/improved-links

GET and DELETE Both routes have the same URL, but the header verb identifies which to call.
Here are my code snippets for edit and delete. I use bootstrap modal confirmation for delete action
<div class="btn-group">
<a href="{{ route('locations.edit', $location->id) }}"
class="btn btn-default btn-sm">
<i class="fa fa-pencil"></i>
</a>
<span class="btn btn-danger btn-sm formConfirm"
data-form="#frmDelete-{{$location->id}}"
data-title="Delete Location"
data-message="Are you sure you want to delete this Location ?">
<i class="fa fa-times"></i>
</span>
<form method="POST"
style="display: none"
id="frmDelete-{{$location->id}}"
action="{{ route('locations.destroy' , $location->id) }}">
{!! csrf_field() !!}
{{ method_field('DELETE') }}
<input type="submit">
</form>
BootStrap Modal
<div class="modal fade" id="formConfirm" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span
class="sr-only">Close</span></button>
<h4 class="modal-title" id="frm_title">Delete</h4>
</div>
<div class="modal-body" id="frm_body"></div>
<div class="modal-footer">
<button style='margin-left:10px;' type="button" class="btn btn-primary col-sm-2 pull-right"
id="frm_submit">Yes
</button>
<button type="button" class="btn btn-danger col-sm-2 pull-right" data-dismiss="modal" id="frm_cancel">
No
</button>
</div>
</div>
</div>
And Finally JS code
$('.formConfirm').on('click', function (e) {
e.preventDefault();
var el = $(this);
var title = el.attr('data-title');
var msg = el.attr('data-message');
var dataForm = el.attr('data-form');
$('#formConfirm')
.find('#frm_body').html(msg)
.end().find('#frm_title').html(title)
.end().modal('show');
$('#formConfirm').find('#frm_submit').attr('data-form', dataForm);
});
$('#formConfirm').on('click', '#frm_submit', function (e) {
var id = $(this).attr('data-form');
$(id).submit();
});

My, non-ajax version. I use it in dropdowns (bootstrap) in resource list (datatables as well). Very short and universal.
Global jQuery method:
$('.submit-previous-form').click(function (e) {
e.preventDefault();
$($(this)).prev('form').submit();
});
And then we can use everywhere something like this:
{{ Form::open(['route' => ['user.destroy', $user], 'method' => 'delete']) }} {{ Form::close() }}
<i class="icon-trash"></i> Delete him
Recommend: It's easy to integrate with confirms scripts for example swal.

you can try this: (you can pass your id)
<form action="{{ route('tasks.destroy', $dummy->id) }}" method="post">
#csrf
#method('DELETE')
<a href="#" class="btn btn-danger" title="Delete" data-toggle="tooltip" onclick="this.closest('form').submit();return false;">
<i class="bi bi-trash-fill" style="color:white"></i>
</a>
</form>
requires route like:
Route::get('/tasks/delete/{id}', 'TasksController#destroy')
->name('tasks.destroy');
your controller:
public function destroy($id)
{
$task = Task::find($id);
$task->delete();
return redirect('/home')->with('success','Task Deleted Successfully');
}
or you can try this
{!! Form::open(['method' => 'DELETE','route' => ['reports.destroy', $dummy->id],'class'=>'']) !!}
{{ Form::button('<i class="bi bi-trash-fill" style="color:white"></i>', ['type' => 'submit', 'class' => 'delete get-started-btn-two'] ) }}
{!! Form::close() !!}

Related

Having trouble using onclick on my form when deleting a post. (laravel-9)

When I try to delete a post from my model Perk and click "cancel" in deleting it using onclick the data is still deleted. Here's the code that I did:
<form method="POST" onclick="return confirm('Are you sure you want to delete this item?');" action="{{ route('perk.destroy', $perk->id) }}">
{{ method_field('DELETE') }}
{{ csrf_field() }}
<i class="cursor-pointer fas fa-trash text-secondary"></i>
</form>

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

I am trying to use Resource Controller and having a problem with destroying method, can't find a solution.
I get this error
The DELETE method is not supported for this route. Supported methods: GET, HEAD, POST.
web.php
Route::resource('honor', 'HonorController');
HonorController.php
public function destroy(Honor $honor)
{
dd($honor);
$honor->delete();
return redirect()->back();
}
blade
<form action="{{ route('honor.destroy', $honor->id) }}" method="post">
#csrf
#method('DELETE')
<div class="btn-group">
Edit
<button type="submit" class="btn btn-danger btn-sm">Delete</button>
</div>
</form>
Try changing the key (uses honor, not id) to match the name of the parameter in the route.
For example:
<form action="{{ route('honor.destroy', ['honor' => $honor->id]) }}" method="post">
#csrf
#method('DELETE')
<div class="btn-group">
Edit
<button type="submit" class="btn btn-danger btn-sm">Delete</button>
</div>
</form>

Retrieving input from Form Select - Laravel

When I select a class from in my view and click on Genrate, I try to retrieve the value of the selected class but I am not able to get the value of the class selected.
When I return $condition, it returns empty. In the url after submitting, it shows like http://localhost:8000/generate/timetable?class=
Why is this happening?
<div class="row">
<div class="col-xl-4 col-lg-12 col-md-12 mb-1">
<fieldset class="form-group">
<label for="squareText">Type</label>
{{ Form::select('class',$classes,$selectedClass,['class'=>'form-control','required'=>'true'])}}
<br>
<button class="btn btn-primary pull-left square" type="submit"><i class="glyphicon glyphicon-th"></i> Generate</button>
</fieldset>
</div>
</div>
Controller
$condition = Input::get('class');
if (!isset($condition['class']))
$condition['class'] = 0;
$courses = $course->where('class',$condition)->get()->toArray();
return $condition;
Your button is inside a link:
<a href="/generate/timetable?class={{ request('class') }}">
<button class="btn btn-primary pull-left square" type="submit"> ... </button>
</a>
Clicking it is actually clicking the <a href> link, not clicking the button and submitting the form. So instead of submitting the form, you are simply browsing to the URL the the link points to.
It isn't clear from your question what the link is there for, but if clicking the button is supposed to submit the form, you probably want to put your form elements inside an actual <form>.
It looks like you're using Laravel Collective ({{ Form::select('class .... looks like that), so see those docs on how to open a form:
{!! Form::open(['url' => '/generate/timetable?class=' . request('class')]) !!}
{{ Form::select('class' .... }}
<button class="btn btn-primary pull-left square" type="submit"> ... </button>
{!! Form::close() !!}
You'll probalby also need to add a CSRF token, it is also described in the Laravel Collective docs, as well as in the Laravel docs.

How to prompt message if field is empty, Laravel

So I have this field for search and image field , in search form I have a button submit it works but when I clicked it and there's no input in the input field it shows error and in the image field if I don't add an image it shows error... Do I solve this through a prompt message? to let the users know that that field is empty. Here's my code for search
building.blade.php
{!! Form::open(['method'=> 'GET','url'=>'offices','role'=>'search']) !!}
<div class="input-group col-xs-4 col-md-6" >
<input type="text" name="search" class="form-control" placeholder="Search...">
<span class="input-group-btn">
<button type="submit" class="btn btn-info btn-md"><span class="glyphicon glyphicon-search"></span> Search
</button>
</span>
</div>
{!! Form::close()!!}
OfficeController.php
public function index()
{
$search = \Request::get('search');
$offices = Office::where('name','LIKE','%'.$search.'%')->get();
return view('search',compact('offices','search'));
}
createbuilding.blade.php
{!! Form::label('Building Photo') !!}
{!! Form::file('buildingpics',array('onchange'=>'previewFile()')) !!}
<img src="../assets/imageholder.png" id="previewImg" style="height:300px; width:300px;" alt="">
</div>
<div class="form-group">
<button type="submit" class="btn btn-default btn-md">
<span class="glyphicon glyphicon-plus"></span> Add Building
</button>
<!-- {!! Form::submit('Create Building',
array('class'=>'btn btn-primary')) !!} -->
<span class="glyphicon glyphicon-arrow-left"></span> Back
</div>
</div>
{!! Form::close() !!}
<script type="text/javascript">
function previewFile() {
var preview = document.querySelector('#previewImg');
var file = document.querySelector('input[type=file]').files[0];
var reader = new FileReader();
reader.addEventListener("load", function () {
preview.src = reader.result;
}, false);
if (file) {
reader.readAsDataURL(file);
}
}
</script>
#endsection
#section('scripts')
#endsection
You can validate it by using laravel validate method in your controller just put the validate code in your controller like
$this->validate($request, [
'field_name1' => 'required',
'field_name2' => 'required',
]);
and in your view just popup the error message so if the user is not fill the field or the field is empty then it show the error message on the submit of the request so user can easily understand what is required.
#if ($errors->any())
<div class="alert alert-danger">
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
<!--error ends-->
Hope this code will help you to shortout the what you want.
You can either go with HTML5 required attribute like so
<input type="text" name="search" class="form-control" placeholder="Search..." required>
or
You can user Laravel's Form Request Validation
https://laravel.com/docs/5.5/validation#form-request-validation

on DELETE MethodNotAllowedHttpException in RouteCollection.php line 251:

Hello i try to delete my comments in Laravel 5.4, but unfortunately i get this error. Can't really get where is the problem.
This is my form:
<form action="{{route('comments.destroy', $comment->id) }}">
<div class="form-group">
<button type="submit" class="btn btn-danger">DELETE</button>
</div>
{{ method_field('DELETE') }}
</form>
This is my routes:
// Comments
Route::post('/lots/{lot}/comments', 'CommentsController#store');
Route::get('/comments', 'CommentsController#show');
Route::get('comments/{id}/edit', ['uses' => 'CommentsController#edit', 'as' => 'comments.edit']);
Route::put('comments/{id}', ['uses' => 'CommentsController#update', 'as' => 'comments.update']);
Route::delete('comments/{id}', ['uses' => 'CommentsController#destroy', 'as' => 'comments.destroy']);
Route::get('comments/{id}/delete', ['uses' => 'CommentsController#delete', 'as' => 'comments.delete']);
This is the controller:
public function delete($id)
{
$comment = Comment::find($id);
return view('comments.delete')->withComment($comment);
}
public function destroy($id)
{
$comment = Comment::find($id);
$comment->delete();
return back();
}
Any ideas what i'm doing wrong?
This is the error message:
This should work:
<form action="{{ route('comments.destroy', ['id' => $comment->id]) }}" method="post">
{{ csrf_field() }}
{{ method_field('DELETE') }}
<div class="form-group">
<button type="submit" class="btn btn-danger">DELETE</button>
</div>
</form>
I think I found the problem, Its your form action's route syntax which is wrong. route helper
<form action="{{route('comments.destroy', ['id' => $comment->id]) }}">
{{ csrf_field() }}
<div class="form-group">
<button type="submit" class="btn btn-danger">DELETE</button>
</div>
<input type="hidden" name="_method" value="DELETE">
</form>
In my case my error was that I was not setting the id property on the object sent to the view, and that was why the form action URL didn't have it.
Check that you are setting id property in your comment object, so the URL is parsed as: .../comments/####
e.g.
$photos = Photo::all()->select('id', 'name')->get();
return view('photos.index')->with('photos', $photos);

Categories