Step 01: Changing index() method in ProductController
public function index( Request $request ) { $meta_title = 'All Products'; $query = Product::query(); $products = $query->orderBy( 'sequence', 'desc' )->paginate( 10 )->withQueryString(); return view( 'products.list', compact( 'meta_title','products' ) ); }
Step 02: Changing list.blade.php under views/resources/products folder fetching and showing database rows using loop and adding a confirm delete modal for deleting a row of data
<div class="container"> <div class="row justify-content-center"> <div class="col-md-8"> <h2>All Productsh2> <table class="table mt-3"> <thead class="table-dark"> <tr> <th>Idth> <th class="text-center">Nameth> <th class="text-center">Costth> <th class="text-center">Createdth> <th class="text-center">Orderth> <th class="text-center">Actionsth> tr> thead> <tbody> @foreach ($products as $product) <tr> <td>{{$product->id}}td> <td class="text-center">{{$product->name}}td> <td class="text-center">${{ number_format($product->cost,2) }}td> <td class="text-center">{{ date('y-m-d', strtotime($product->created_at)) }}td> <td class="text-center" style="width:20%;"> <form action="{{ route('products.save_order',$product->id) }}" method="POST" enctype="multipart/form-data"> @csrf <input type="text" name="order" value="{{ $product->sequence }}" data-post-id="{{ $product->id }}" class="resource-order form-control text-center" placeholder=""> form> td> <td class="text-center"> <a class="text-black" href="{{ route('products.edit', $product->id) }}"><i class="bi bi-pencil">i>a> <a class="text-black delete-row" href="javascript:void(0);" data-base-url=" echo url('') ?>" data-rowname=" echo $product->name ?>" data-rowid=" echo $product->id ?>"><i class="bi bi-trash">i>a>td> td> tr> @endforeach @if (count($products) == 0) <tr><td colspan="6"><span class="">Nothing foundspan>td>tr> @endif tbody> table> <div class="justify-content-center mt-3"> {!! $products->links() !!} div> div> div> div> <div id="modal-delete-confirm" class="modal fade"> <div class="modal-dialog modal-md modal-dialog-centered" > <div class="modal-content" > <div class="modal-header"> <h4><strong >Confirm Delete strong>h4> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-hidden="true">button> div> <div class="modal-body text-center"> <p>Would you like to delete this row <span id="modal-delete-title">span>? <br>Once deleted it cannot be reverted.p> <div class="row justify-content-center"> <div class="col-3"> <form id="list-frm-modal" class="float-start" method="POST" action=""> @csrf @method('DELETE') <button type="submit" class="btn btn-sm btn-danger white">Yesbutton> form> <a href="javascript:void(0);" class="btn btn-sm btn-info white float-end" data-bs-dismiss="modal">Noa> div> div> div> div> div> div>
Step 03: Adding bootstrap paginator in AppServiceProvider.php to display correct bootstrap pagination html under product list or any list site wide. Otherwise pagination html rendering will be broken.
// at the top use Illuminate\Pagination\Paginator; public function boot() { // Schema::defaultStringLength(200); Paginator::useBootstrap(); }
Step 04: Adding route for products.save_order in routes/web.php inside middleware auth and is_admin.
Route::group(['middleware'=> [ 'auth']], function() { Route::resource('orders', \App\Http\Controllers\OrderController::class); Route::group(['middleware'=> ['is_admin']], function() { Route::resource('users', \App\Http\Controllers\UserController::class); Route::post('/products/save_order/{product}', [\App\Http\Controllers\ProductController::class, 'saveOrder'])->name('products.save_order'); Route::resource('products', \App\Http\Controllers\ProductController::class); Route::resource('profiles', \App\Http\Controllers\ProfileController::class); Route::resource('frame_widths', \App\Http\Controllers\FrameWidthController::class); }); });
Step 05: Creating ordering.js under resources/js/utilities folder for change of ordering of product rows. Please note that we only have created ajax method for calling saveOrder() method in ProductController.php however, actual saveOrder() method is not created. We will be doing it next coming tutorial.
const ordering = { change : () => { $( ".resource-order" ).on( "change", function() { let postOrderEle = $(this); $(this).css('opacity',0.5); let rowId = $(this).data('row-id'); let orderVal = $(this).val(); //console.log($(this).parents("form").attr('action')); return false; //console.log(postId); $.ajax({ headers: { 'X-CSRF-TOKEN' : $(this).prev().val() }, url : $(this).parents("form").attr('action'), method: "POST", data: { order: orderVal }, success: function(data) { //console.log(data); postOrderEle.css('opacity',1); } }); }); } }
Step 06: Optimizing code in modal.js for using baseurl from blade directive on class of delete-row click event
const modal = { delete : () => { //console.log('in modal'); $( ".delete-row" ).on( "click", function() { // http://localhost:8000 $('#modal-delete-title').html($(this).data('rowname')); $('#list-frm-modal').attr('action', $(this).data('baseUrl') + '/'+ $(this).data('resource') +'/' + $(this).data('rowid')); let delModal = document.getElementById("modal-delete-confirm"); let modal = new bootstrap.Modal(delModal, { backdrop: false }); modal.show(); }); } } export default modal;
Step 07: Optimizing js file modal.js by taking it under resources/js/utilities folder like ordering which was previously under resources/js/users folder
Step 08: Back in app.js importing modal.js and ordering.js from resources/js/utilities and calling proper methods of respective esm module
window.bootstrap = require('bootstrap/dist/js/bootstrap.bundle.js'); window.$ = window.jQuery = require('jquery'); import bsModel from './utilities/modal'; import ordering from './utilities/ordering'; bsModel.delete(); ordering.change();
Please note "npm run watch" must be running to pick all these changes and compiled in public/js/app.js