Reputation: 199
I am working on the CRUD part of a Laravel app.
It is supposed that when the delete button of an entry is clicked, a modal show up and ask user to confirm delete the corresponding entry or not.
This is my frontend code.
My plan A:
You can see the confirm button in the modal is inside the form in the code but it went outside the form element in the actual HTML document.
The button which make the modal visible when clicked
<button id="pj_btn_delete-{{ $project->id }}"
class="btn btn-danger pj_btn_delete" type="button"
data-toggle="modal" data-target="#pj_modal_delete-{{ $project->id }}">
Delete</button>
The delete modal in blade
<div id="pj_modal_delete-{{ $project->id }}" class="modal fade pj_modal_delete"
tabindex="-1" role="dialog" aria-labelledby="myLargeModalLabel">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">X</h4>
</div>
<div class="modal-body">
<p>Are you sure to delete it?</p>
</div>
<div class="modal-footer">
<button type="button" id="pj_cancel-{{ $project->id }}" class="btn btn-default pj_cancel" data-dismiss="modal">Cancel</button>
<form id="pj_form_delete-{{ $project->id }}"
action="{{ route('projects.destroy',$project->id) }}" method="POST">
@csrf
@method('DELETE')
<button type="submit" id="pj_delete-{{ $project->id }}"
class="btn btn-primary pj_delete">Confirm
</button>
</form>
</div>
</div>
</div>
</div>
Btw, these are the code of routing and controller
the routes
Route::resource('admin/projects','ProjectController');
the delete method in controller
public function destroy(Project $project)
{
$project->clients()->detach();
$project->staff()->detach();
// $project->slack_channels()->detach();
$project->delete();
return redirect()->route('projects.index')
->with('success','The deletion is complete');
}
My plan B:
I have also tried to submit the delete form by JS like this but it didn't change anything.
$( ".pj_delete" ).click(function() {
let pj_id = $(this).attr('id').split('-')[1];
let pj_form_delete_id = "pj_form_delete-" + pj_id;
$(pj_form_delete_id).submit();
});
My plan C:
I also turned the confirm button of the modal into a link to the delete method. Also didn't work.
<a class="btn btn-primary" href="{{
route('projects.destroy',$project->id) }}">Confirm</a>
the plan C delete route
Route::delete('admin/project/delete/{id}',array('uses' => 'ProjectController@destroy', 'as' => 'project.delete'));
Neither of these approaches generated a confirm button that can delete the item with corresponding id and I got no error in all these approaches. Please help. Thanks!
Upvotes: 1
Views: 1626
Reputation: 4285
Here is the solution I have came up with for you (It a completed plan A). Please note I left in language files calls because I figured it would come in handy:
Please let me know if you have any questions or need to see an open source project a working example.
For ease I am using this package Form Builder https://laravelcollective.com/docs/master/html#installation It is not needed but you would need to change out the calls for normal HTML forms and HTML buttons.
Best of luck!
Jeremy
// Web Admin Routes web.php
Route::group(['prefix' => 'admin'], function () {
Route::resource('projects', 'ProjectController', [
'names' => [
'destroy' => 'destroyproject',
]
]);
});
//HTML Form Blade View File: /resources/views/admin/modals/delete-project-modal-form.php
<div class="modal fade modal-danger" id="modal_delete" role="dialog" aria-labelledby="confirmDeleteLabel" aria-hidden="true" tabindex="-1">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header bg-danger text-white">
<h5 class="modal-title">
<i class="fa fa-question-circle fa-fw mr-1 text-white"></i>
{!! trans('admin.modals.delete-project.title') !!}
</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
<span class="sr-only">
{!! trans('admin.modals.delete-project.close') !!}
</span>
</button>
</div>
<div class="modal-body">
<p>
{!! trans('admin.modals.delete-project.message') !!}
</p>
</div>
<div class="modal-footer">
{!! Form::open(['method' => 'DELETE', 'route' => ['destroyproject', $projectId], 'role' => 'form', 'id' => 'delete_project_form', 'name' => 'delete_project_form']) !!}
<input type="hidden" name="_token" value="{{ csrf_token() }}">
<input type="hidden" name="_method" value="DELETE">
<meta name="_token" content="{!! csrf_token() !!}" />
{!! Form::button('<i class="fa fa-fw fa-close" aria-hidden="true"></i> ' . trans('admin.modals.delete-project.cancel'), array('class' => 'btn btn-outline pull-left btn-light', 'type' => 'button', 'data-dismiss' => 'modal' )) !!}
{!! Form::button('<i class="fa fa-fw fa-trash-o" aria-hidden="true"></i> ' . trans('admin.modals.delete-project.confirm'), array('class' => 'btn btn-danger pull-right', 'type' => 'submit', 'id' => 'confirm' )) !!}
{!! Form::close() !!}
</div>
</div>
</div>
</div>
// Include the above modal blade from your blade
@include('admin.modals.delete-project-modal-form', ['projectId' => $project->id])
// Modal HTML Trigger in your blade
<button type="button" class="btn btn-danger btn-sm btn-block delete-project-trigger" data-toggle="modal" data-target="#modal_delete" data-projectid="{{ $project->id }}">
<i class="fa fa-trash-o fa-fw" aria-hidden="true"></i>
<span class="hidden-xs hidden-sm hidden-md">
{{ trans('admin.buttons.delete') }}
</span>
</button>
// Javascript to include in your blade to trigger the modal
@push('scripts')
<script type="text/javascript">
$('.delete-project-trigger').click(function(event) {
var projectId = $(this).data("projectid");
$('#modal_delete').on('show.bs.modal', function (e) {
document.delete_project_form.action = "{{ url('/') }}" + "/admin/projects/" + projectId;
});
});
</script>
@endpush
// Include this in your app.blade.php
or whatever layout you are using to make sure you can include the sciprts:
@stack('scripts')
// In ProjectController.php // Make sure you include the call to the project model at the top of the file something like:
use App\Models\Project;
// Here is the destroy
method in ProjectController.php
/**
* Remove the specified resource from storage.
*
* @param Request $request
* @param int $id
*
* @return \Illuminate\Http\Response
*/
public function destroy(Request $request, $id)
{
$project = Project::findOrFail($id);
$project->clients()->detach();
$project->staff()->detach();
// $project->slack_channels()->detach();
$project->delete();
return redirect()
->route('projects.index')
->withSuccess(trans('messages.success.project-deleted'));
}
// The Language lines file: /resources/lang/en/admin.php
<?php
return [
/*
|--------------------------------------------------------------------------
| Admin language lines
|--------------------------------------------------------------------------
|
*/
'modals' => [
'delete-project' => [
'close' => 'Close',
'title' => 'Confirm Delete',
'message' => 'Delete this project?',
'cancel' => 'Cancel',
'confirm' => 'Confirm Delete',
]
],
];
// The Language lines file: /resources/lang/en/messages.php
<?php
return [
/*
|--------------------------------------------------------------------------
| Message language lines
|--------------------------------------------------------------------------
|
*/
'success' => [
'project-deleted' => 'Project deleted.',
],
];
Working file of outlined examples for reference:
Example Project 1
Routes https://github.com/jeremykenedy/larablog/blob/master/routes/web.php#L48
Request https://github.com/jeremykenedy/larablog/blob/master/app/Http/Requests/DestroyPostRequest.php
Blade Files https://github.com/jeremykenedy/larablog/blob/master/resources/views/admin/post/edit.blade.php#L70
https://github.com/jeremykenedy/larablog/blob/master/resources/views/admin/post/edit.blade.php#L87
https://github.com/jeremykenedy/larablog/blob/master/resources/views/admin/post/edit.blade.php#L93
Example Project 2
Routes https://github.com/jeremykenedy/laravel-users/blob/master/src/routes/web.php#L15
Example Project 3
Routes https://github.com/jeremykenedy/laravel-logger/blob/master/src/routes/web.php#L21
This can be done and there are 3 live projects with it working.
Upvotes: 1
Reputation: 1725
You should indicate what the error was with your first attempt. You just say that it didn't work.
For your plan B, you need to add a # to your selector:
let pj_form_delete_id = "#pj_form_delete-" + pj_id;
... and for your plan C you need a GET route instead of DELETE to make it work with a link. A clicked link generates a GET request.
Route::get('admin/project/delete/{id}',array('uses' => 'ProjectController@destroy', 'as' => 'project.delete'));
That being said, you should try to get your first attempt using a DELETE and a form working. If you can provide more details on what didn't work someone might be able to help you.
Upvotes: 1