How to add Laravel datatable(yajra) to existing project? - php

Is any possible way, to add yajra datatables to existing project?
If I implement it to blank view.blade.php it works good, but if I put it to my existing project it only show thead.
My controller:
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use Yajra\DataTables\DataTables;
class UserRecordController extends Controller
{
public function __construct()
{
$this->middleware(['role:admin']);
}
public function show()
{
$data = User::all()->all();
return view('management.admin-only.users.users_record')->with('data', $data);
}
public function index(Request $request)
{
if ($request->ajax()) {
$data = User::all()->all();
return Datatables::of($data)
->addIndexColumn()
->addColumn('action', function($row){
$btn = 'View';
return $btn;
})
->rawColumns(['action'])
->make(true);
}
return view('management.admin-only.users.users_record');
}
}
My view:
#extends('layouts.app')
#section('content')
<div class="row admin-panel">
#include('management.common.admin_sidebar')
<div class="col" id="main">
<div class="card panel-stats">
<div class="card-body">
<div class="flash-message">
#foreach (['danger', 'warning', 'success', 'info'] as $msg)
#if(Session::has('alert-' . $msg))
<p class="alert alert-{{ $msg }}">{{ Session::get('alert-' . $msg) }} ×</p>
#endif
#endforeach
</div>
<div class="card-title">
<div class="card-body">
<div class="card-body">
<h2><img class="py-2 mr-3" height="100px" width="auto" src="{{ asset('img/admin/group.jpg') }}">Users</h2>
</div>
Add user
Edit user
Delete user
</div>
<div class="card-body">
<div class="card">
<table class="table table-responsive-md table-striped table-hover data-table" id="users-table">
<thead>
<tr>
<th>#</th>
<th>Firstname</th>
<th>Lastname</th>
<th>E-mail</th>
<th>Add date</th>
<th>Option</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script>
$(function () {
var table = $('.data-table').DataTable({
processing: true,
serverSide: true,
ajax: "{{ route('users_record') }}",
columns: [
{data: 'id', name: 'id'},
{data: 'firstname', name: 'firstname'},
{data: 'surname', name: 'surname'},
{data: 'email', name: 'email'},
{data: 'created_at', name: 'created_at'},
{data: 'action', name: 'action', orderable: false, searchable: false},
]
});
});
function changeUrl(el){
let urlEdit = '{{Route("users_edit_form", ":id" )}}';
urlEdit = urlEdit.replace(':id', el.value);
let urlDelete = '{{Route("users_delete_form", ":id" )}}';
urlDelete = urlDelete.replace(':id', el.value);
document.getElementById('user-edit').href = urlEdit;
document.getElementById('user-delete').href = urlDelete;
}
function checkIfChecked(){
if(document.getElementById('id-selected').checked)
{
console.log(document.getElementById('id-selected').value);
return true
}
else
{
console.log(document.getElementById('id-selected').value);
alert('Choose user to edit/delete!');
return false
}
}
function confirmation(){
let message = confirm("Are you sure?");
if(message)
return true;
else
return false;
}
</script>
#endsection
My routes:
Route::get('/admin_panel/users_record','UserRecordController#index')->name('users_record');
I worked with multiple tutorials - every looked similar. I've just imported all the neccessary webpacks to app.blade.php.
What I've done wrong?

you need two function, one is for load view like
public function index(){
return view('management.admin-only.users.users_record');
}
and another function to get data like
public function get_users_record(Request $request){
if ($request->ajax()) {
$data = User::all()->all();
return Datatables::of($data)
->addIndexColumn()
->addColumn('action', function($row){
$btn = 'View';
return $btn;
})
->rawColumns(['action'])
->make(true);
}
}
route will be
Route::get('/admin_panel/users_record','UserRecordController#index')->name('users_record');
Route::get('/admin_panel/get_users_record','UserRecordController#get_users_record')->name('get_users_record');
and ajax url should be
ajax: "{{ route('get_users_record') }}",

Related

Laravel datatable ajax post request

I am developing a Laravel management application with Yajra datatables.
So I have various tables, and in particular in the user table I need to change the user's status (active / inactive) via ajax request by simply clicking a button or ticking a checkbox.
This is my first time using ajax and datatables, and I have no idea how to achieve this ... is it possible or are there better / quicker ways to do this?
I accept any advice or suggestion
My code:
controller
<?php
namespace Modules\User\Http\Controllers;
use Illuminate\Contracts\Support\Renderable;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use App\Models\User;
use DataTables;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Auth;
class UserController extends Controller
{
/**
* Display a listing of the resource.
* #return Renderable
*/
public function index(Request $request)
{
$user = User::select('id', 'name', 'email', 'attivo' , 'email_verified_at', 'created_at')->get();
if($request->ajax()){
return Datatables::of($user)
->addIndexColumn()
->addColumn('stato', function($row){
($row['attivo'] == 1 ) ? $btn1 = '<div class="btn-group" role="group" aria-label="Basic example"><a href="#" id="btn-post" dusk="postButton" class="btn btn-primary" role="button" data-toggle="modal" data-target="#addPost" style="color:white; font-size:small;">
<span class="ion-plus-circled"> Disattiva</span>
</a>'
: $btn1 = '<div class="btn-group" role="group" aria-label="Basic example"><button id="btnAttiva" class="btn btn-primary btn-rounded" style="color:white; font-size:small;">Attiva</button>';
return $btn1;
})
->addColumn('action', function($row){
$btn = '<div class="btn-group" role="group" aria-label="Basic example">View</div>';
$btn = $btn.'Edit';
$btn = $btn.'<form action="/user/delete" method="POST"><input type="hidden" name="_token" value="{{ #csrf() }}"><input type="hidden" name="_method" value="{{ #method(\'delete\') }}">
<input type="hidden" class="form-control" name="idu" value="'.$row['id'].'"><input type="submit" class="edit btn btn-danger btn-rounded" style="color:white; font-size:small;" value="Delete" /></form></div>';
return $btn;
})
->rawColumns(['action', 'stato'])
->make(true);
}
return view('user::index');
}
public function setState(Request $request){
// here i need to modify the user state
}
}
view:
#extends('layouts.master')
#section('title', 'Lista Utenti')
#section('content')
#if (\Session::has('error'))
<div class="alert alert-danger">
<ul>
<li>{!! \Session::get('error') !!}</li>
</ul>
</div>
#endif
#if (\Session::has('success'))
<div class="alert alert-success">
<ul>
<li>{!! \Session::get('success') !!}</li>
</ul>
</div>
#endif
<div class="col-lg-12 grid-margin stretch-card">
<div class="card">
<div class="card-body">
<h4 class="card-title">Utenti</h4>
<p class="card-description">
Lista degli utenti registrati
</p>
<div class="table-responsive">
<table class="table table-bordered" id="dtUserList">
<thead>
<th>Id</th>
<th>Name</th>
<th>Email</th>
<th>Email Verificata</th>
<th>Stato</th>
<th>Created</th>
<th>Action</th>
</thead>
</table>
</div>
</div>
</div>
</div>
<div>
<a href="{{ url('/user/create') }}" class="btn btn-primary btn-rounded"
style="color:white; font-size:small;">Aggiungi utente</a>
</div>
#endsection
#section('script')
<script>
$(function() {
var table = $('#dtUserList').DataTable({
processing: true,
serverSide: true,
ajax: '{{ url('user') }}',
columns: [
{ data: 'id', name: 'id', visible: false },
{ data: 'name', name: 'name' },
{ data: 'email', name: 'email' },
{ data: 'email_verified_at', name: 'email_verified_at'},
{ data: 'stato', name: 'stato', orderable: false, searchable: false},
{ data: 'created_at', name: 'created_at' },
{ data: 'action', name: 'action', orderable: false, searchable: false },
],
order: [[0, 'asc']]
});
});
</script>
#endsection
EDITED CODE WITH AJAX CALL:
view index.blade.php
#extends('layouts.master')
#section('title', 'Lista Utenti')
#section('content')
#if (\Session::has('error'))
<div class="alert alert-danger">
<ul>
<li>{!! \Session::get('error') !!}</li>
</ul>
</div>
#endif
#if (\Session::has('success'))
<div class="alert alert-success">
<ul>
<li>{!! \Session::get('success') !!}</li>
</ul>
</div>
#endif
<div class="col-lg-12 grid-margin stretch-card">
<div class="card">
<div class="card-body">
<h4 class="card-title">Utenti</h4>
<p class="card-description">
Lista degli utenti registrati
</p>
<div class="table-responsive">
<table class="table table-bordered" id="dtUserList">
<thead>
<th>Id</th>
<th>Name</th>
<th>Email</th>
<th>Email Verificata</th>
<th>Stato</th>
<th>Created</th>
<th>Action</th>
</thead>
</table>
</div>
</div>
</div>
</div>
<div>
<a href="{{ url('/user/create') }}" class="btn btn-primary btn-rounded"
style="color:white; font-size:small;">Aggiungi utente</a>
</div>
#endsection
#section('script')
<script type="text/javascript">
$(function() {
var table = $('#dtUserList').DataTable({
processing: true,
serverSide: true,
ajax: '{{ url('user') }}',
columns: [
{ data: 'id', name: 'id', visible: false },
{ data: 'name', name: 'name' },
{ data: 'email', name: 'email' },
{ data: 'email_verified_at', name: 'email_verified_at'},
{ data: 'stato', name: 'stato', orderable: false, searchable: false},
{ data: 'created_at', name: 'created_at' },
{ data: 'action', name: 'action', orderable: false, searchable: false },
],
order: [[0, 'asc']]
});
});
$.fn.myFunction = function(form){
//put the form elements in an array
id = $(form).serializeArray();
//Get the value of the first index(the id)
iduser = id[0]['value'];
idstato = id[1]['value'];
$.ajax({
// Post method
type: 'POST',
// Url to the route
url: "{{ url('/user/deactivate') }}",
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
// Data to submit to the function
data: {
//CRSF token for laravel form validations
_token: $('meta[name="csrf-token"]').attr('content'),
idu: iduser,
ids: idstato
},
success: function(response){
//if request is made successfully then the response represent the data
$( "#result" ).empty().append( response );
}
});
}
</script>
#endsection
Controller:
<?php
namespace Modules\User\Http\Controllers;
use Illuminate\Contracts\Support\Renderable;
use Illuminate\Http\Request;
use Illuminate\Routing\Controller;
use App\Models\User;
use DataTables;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Auth;
class UserController extends Controller
{
/**
* Display a listing of the resource.
* #return Renderable
*/
public function index(Request $request)
{
$user = User::select('id', 'name', 'email', 'attivo' , 'email_verified_at', 'created_at')->get();
if($request->ajax()){
return Datatables::of($user)
->addIndexColumn()
->addColumn('stato', function($row){
($row['attivo'] == 1 ) ? $btn1 = '<form><input type="hidden" name="user" value="'.$row['id'].'"><div class="form-group"><select onchange="$.fn.myFunction(this.form)" name="stato"><option value="0">Disattivo</option><option value="1" selected>Attivo</option></select></div></form>'
: $btn1 = '<form><div class="form-group"><input type="hidden" name="user" value="'.$row['id'].'"><select name="stato" onchange="$.fn.myFunction(this.form)"><option value="0" selected>Disattivo</option><option value="1">Attivo</option></select></div></form>';
return $btn1;
})
->addColumn('action', function($row){
$btn = '<div class="btn-group" role="group" aria-label="Basic example">View</div>';
$btn = $btn.'Edit';
$btn = $btn.'<form action="/user/delete" method="POST"><input type="hidden" name="_token" value="{{ #csrf() }}"><input type="hidden" name="_method" value="{{ #method(\'delete\') }}">
<input type="hidden" class="form-control" name="idu" value="'.$row['id'].'"><input type="submit" class="edit btn btn-danger btn-rounded" style="color:white; font-size:small;" value="Delete" /></form></div>';
return $btn;
})
->rawColumns(['action', 'stato'])
->make(true);
}
return view('user::index');
}
public function disattiva($idu, $ids){
dd($idu+":"+$ids);
}
}
My Route:
//rotte USER module with CRUD route
Route::middleware(['auth'])->prefix('user')->group(function() {
Route::get('/', 'UserController#index'); //dashboard -> lista utenti
Route::post('/deactivate', 'UserController#disattiva');
Route::get('/detail/{idu}', 'UserController#show'); // dettaglio specifico utente
Route::get('/edit/{idu}', 'UserController#showEditForm'); // form edit utente con dato idu
Route::patch('/edit', 'UserController#edit'); // scrivere le modifiche sul DB
Route::delete('/delete', 'UserController#destroy'); // eliminare utente dal DB
Route::get('/create', 'UserController#showCreateForm'); // form creazione nuovo utente
Route::post('/create', 'UserController#create'); // creare l'utente sul DB
Route::get('/profile', 'UserController#showProfile'); // mostra il profilo dell'utente loggato
});
Create a form inside your table and create a custom function in the select
(I assume you want to change it using a select)
<select onchange="$.fn.myFunction(this.form)">
After that you want to create a ajax request like this:
$.fn.myFunction = function(form){
//put the form elements in an array
id = $(form).serializeArray();
//Get the value of the first index(the id)
id = id[0]["value"];
$.ajax({
// Post method
type: 'POST',
// Url to the route
url: "/ajax/myfunction",
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
// Data to submit to the function
data: {
//CRSF token for laravel form validations
_token: $('meta[name="csrf-token"]').attr('content'),
id: id
},
success: function(response){
//if request is made successfully then the response represent the data
$( "#result" ).empty().append( response );
}
});
}

I am getting 500 Internal Error when trying to pass named route with two parameter in my controller

So when I put a route name with a single parameter it works flawlessly but when I pass named route with two parameters I get a 500 error in my console which looks like this:GET http://127.0.0.1:8000/admin/packages/package-programs/kathmandu/action?query= 500 (Internal Server Error).
<?php
namespace App\Http\Controllers\AdminVisible;
use Illuminate\Http\Request;
use Illuminate\Support\Str;
use App\Program;
use App\Package;
use DB;
class PackageProgramController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function index($packageSlug)
{
$showCounts = Program::count();
$packages = Package::firstOrFail();
return view('admin.pages.packageprogram',compact('showCounts','packageSlug','packages'));
}
function action($packageSlug,Request $request)
{
if($request->ajax())
{
$output = '';
$query = $request->get('query');
if($query != '')
{
$data = DB::table('programs')
->where('id', 'like', '%'.$query.'%')
->orWhere('day', 'like', '%'.$query.'%')
->orWhere('Package_Type', 'like', '%'.$query.'%')
->orWhere('title', 'like', '%'.$query.'%')
->orderBy('id', 'desc')
->get();
}
else
{
$data = DB::table('programs')
->orderBy('id', 'desc')
->get();
}
$total_row = $data->count();
if($total_row > 0)
{
foreach($data as $row)
{
$packageProgram = ['packageProgram' => $row->id];
$route = route('PackageProgram.edit',['packageSlug' => $packageSlug, 'packageProgram' => $packageProgram]);
$output .= '
<tr>
<th scope="row"><input type="checkbox" name="ids[]" class="selectbox" value="'.$row->id.'" onchange="change()"></th>
<td onClick="location.href=\''.$route.'\' " style="cursor: pointer">'.$row->id.'</td>
<td onClick="location.href=\''.$route.'\' " style="cursor: pointer">'.$row->day.'</td>
<td onClick="location.href=\''.$route.'\' " style="cursor: pointer">'.$row->title.'</td>
<td onClick="location.href=\''.$route.'\' " style="cursor: pointer">'.$row->description.'</td>
</tr>
';
}
}
else
{
$output = '
<tr>
<td align="center" colspan="12">No Data Found</td>
</tr>
';
}
$data = array(
'table_data' => $output,
'total_data' => $total_row
);
echo json_encode($data);
}
}
public function create($packageSlug, Package $package)
{
return view('admin.create.createPackageProgram',compact('packageSlug','package'));
}
public function store($packageSlug,Request $request)
{
$packages = Package::where('slug', $packageSlug)->firstOrFail();
$data = request()->validate([
'day' => 'required',
'title' => 'required',
'description' => 'required',
]);
$packages->program()->create($data);
switch ($request->input('action')) {
case 'preview':
return redirect()->intended(route('PackageProgram',$packageSlug))->with('message', 'Package Program has been added.');
break;
default:
return redirect()->back()->with('message', 'Package Program has been added.');
break;
}
}
public function edit($packageSlug,Program $packageProgram,Package $package)
{
return view('admin.edit.editPackageProgram',compact('packageSlug','packageProgram','package'));
}
public function update($packageSlug, Program $packageProgram)
{
$data = request()->validate([
'day' => 'required',
'title' => 'required',
'description' => 'required',
]);
$packageProgram->update($data);
return redirect()->intended(route('PackageProgram',$packageSlug))->with('message', 'Package Program has been updated.');
}
public function delete(Request $request) {
$data = request()->validate([
'deleteSelected' => 'required',
]);
$id = $request->get('ids');
$data = DB::delete('delete from programs where id in ('.implode(",",$id).')');
return redirect()->back()->with('message', 'Testimony has been deleted.');
}
}
My blade file looks something like this:
#extends('layouts.app')
#section('style')
<link href="{{ asset('css/Admin/sql-data-viewer.css') }}" rel="stylesheet">
<style></style>
#endsection
#section('content')
<section class="data-viewer">
<div class="d-flex justify-content-between px-3">
<h3 class="text-white">Select {{$package->Package_Name}} {{$package->Package_Type}} Days to change</h3>
<button type="button" class="btn add-data text-white rounded-pill">Add Day <i class="fas fa-plus"></i></button>
</div>
<form>
#csrf
#method('DELETE')
#if(session()->has('message'))
<div class="alert alert-success">
{{ session()->get('message') }}
</div>
#endif
<div class="d-flex justify-content-between selectDelete">
<div class="delete pl-3 mt-3 mb-3">
<label for="deleteSelected">Action:</label>
<select name="deleteSelected" id="deleteSelected" class="#error('deleteSelected') is-invalid #enderror" name="deleteSelected" >
<option disabled selected>---------</option>
<option>Delete Selected Package Program</option>
</select>
<button formaction="{{ route('PackageProgram.delete',$package) }}" formmethod="POST" type="submit" class="go" id="deleleGo" onclick="deleteBtn()">Go</button>
<span id="selected">0</span> of {{$showCounts}} selected
#error('deleteSelected')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
<strong id="selectError">You must check at least one checkbox</strong>
</div>
<div class="search pr-3 mt-3 mb-3">
<label for="search">Search:</label>
<input id="search" type="text" color="#000" class="rounded #error('search') is-invalid #enderror" name="search" value="{{ old('search') }}" autocomplete="search" placeholder="Search">
#error('search')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
#enderror
</div>
</div>
<table class="table table-hover table-striped table-dark">
<thead>
<tr>
<th scope="col"><input type="checkbox" id="checkHead" class="selectall"></th>
<th scope="col">Id</th>
<th scope="col">Day</th>
<th scope="col">Title</th>
<th scope="col">Description</th>
</tr>
</thead>
<tbody></tbody>
</table>
</form>
</section>
#endsection
#section('script')
<script src="{{ asset('/js/sqlData.js') }}"></script>
<script>
$(document).ready(function(){
fetch_data();
function fetch_data(query = '')
{
$.ajax({
url:"{{ route('PackageProgram.action',$packageSlug) }}",
method:'GET',
data:{query:query},
dataType:'json',
success:function(data)
{
$('tbody').html(data.table_data);
}
})
}
$(document).on('keyup', '#search', function(){
var query = $(this).val();
fetch_data(query);
});
});
function checkboxError(){
var number = document.querySelectorAll('.selectbox:checked').length;
if(number == 0) {
var a = document.getElementById("selectError").style.display = "block";
return false;
}
}
window.addEventListener('DOMContentLoaded', (event) => {
var deleteBtn = document.getElementById("deleleGo");
deleteBtn.onclick = checkboxError;
});
</script>
#endsection
So my route file looks something like this:
Route::prefix('package-programs')->group(function() {
Route::get('/', 'AdminVisible\packagePackageProgramController#index')->name('PackagePrograms');
Route::get('/action', 'AdminVisible\packagePackageProgramController#action')->name('PackagePrograms.action');
Route::prefix('{packageSlug}')->group(function() {
Route::get('/', 'AdminVisible\PackageProgramController#index')->name('PackageProgram');
Route::get('/action', 'AdminVisible\PackageProgramController#action')->name('PackageProgram.action');
Route::get('/create', 'AdminVisible\PackageProgramController#create')->name('PackageProgram.create');
Route::post('/create', 'AdminVisible\PackageProgramController#store')->name('PackageProgram.store');
Route::delete('/delete','AdminVisible\PackageProgramController#delete')->name('PackageProgram.delete');
Route::get('/{packageProgram}/edit', 'AdminVisible\PackageProgramController#edit')->name('PackageProgram.edit');
Route::patch('/{packageProgram}', 'AdminVisible\PackageProgramController#update')->name('PackageProgram.update');
});
});
It might be I do not know how to pass named route with two parameters but in my blade file, I been doing it like this, and there it works. Is it something different that must be done in the controller.
First start from blade (please check comments):
#extends('layout')
#section('content')
<div class="row">
<table class="table table-hover table-striped table-dark" id="slugTb">
<thead>
<tr>
<th scope="col"><input type="checkbox" id="checkHead" class="selectall"></th>
<th scope="col">Id</th>
<th scope="col">Day</th>
<th scope="col">Title</th>
<th scope="col">Description</th>
</tr>
</thead>
<tbody></tbody>
</table>
</div>
#endsection
#section('scripts')
<script>
$(document).ready(function() {
var query = 'damnSon';
$.ajax({
url: "{{ route('test.action') }}",
method: 'GET',
data: {
'slug': '{{ $packageSlug }}',
'query': query
},
dataType: 'json',
})
.done(function(data) {
console.log(data) //use console.log to debug
$('#slugTb tbody').html(data.table_data); //set table id so that you don't miss the right one
})
.fail(function(err) {
console.log(err) //in case if error happens
})
.always(function() {
console.log( "complete" ); //result despite the response code
});
});
</script>
#endsection
You used deprecated jquery method like success check
Better use this three: done,fail,always
Next route web.php:
Route::get('action', ['as' => 'test.action', 'uses' => 'TestController#action']);
In your case better to use Request params bag so that you can add as much params as you want.
Next controller:
function action(Request $request)
{
$total_row = 1;
$packageSlug = $request->get('slug'); //names that you set in ajax data tag: {'slug': '{{ $packageSlug }}','query': query}
$query = $request->get('query');
$output = '<tr>
<td align="center" colspan="1">' . $packageSlug . '</td>
<td align="center" colspan="1">' . $query .'</td>
</tr>';
$data = array(
'table_data' => $output,
'total_data' => $total_row
);
return response()->json($data);
}
You should return something from the controller so blade can show that data and json encode it so that js could parse it. That is why return response()->json($data);
Other way:
route:
Route::get('/action/{slug}/{query}',['as' => 'test.action', 'uses' => 'TestController#action']);
blade script:
<script>
$(document).ready(function() {
var query = 'damnSon';
$.ajax({
url: 'action/{{ $packageSlug }}/' + query,
method: 'GET',
dataType: 'json',
})
.done(function(data) {
console.log(data) //use console.log to debug
$('#slugTb tbody').html(data.table_data); //set table id so that you don't miss the right one
})
.fail(function(err) {
console.log(err) //in case if error happens
})
.always(function() {
console.log( "complete" ); //result despite the response code
});
});
</script>
and controller:
function action($slug, $query)
{
$total_row = 1;
$packageSlug = $slug;
$query = $query;
$output = '<tr>
<td align="center" colspan="1">' . $packageSlug . '</td>
<td align="center" colspan="1">' . $query .'</td>
</tr>';
$data = array(
'table_data' => $output,
'total_data' => $total_row
);
return response()->json($data);
}
Not recommended just because you manually type route in ajax request: url: 'action/{{ $packageSlug }}/' + query if your route changes you have to change it in js.

Laravel record not deleting with delete nor destroy

I am using laravel 7. In my CRUD application, I am having trouble deleting a user record. I have tried a variety of methods which I have left commented out so that you can see what I tried. I am using Sweetalert2 for the confirmation call and when I click confirm, it redirects to the correct page but I do not get a success message nor is the record deleted from the database. I am new to Laravel so if anyone can spot where I may have gone wrong, I would sure appreciate it.
Here are the following relevant codes.
(EDIT OF CODE BELOW!!!)
index.blade.php
#extends('layouts.admin')
#section('content')
<div class="container-fluid mt-5">
<!-- Heading -->
<div class="card mb-4 wow fadeIn">
<!--Card content-->
<div class="card-body d-sm-flex justify-content-between">
<h4 class="mb-2 mb-sm-0 pt-1">
Inicio
<span>/</span>
<span>Registered Users</span>
</h4>
</div>
</div>
<!-- Heading -->
<!--Grid row-->
<!--Grid column-->
<div class="row">
<!--Card-->
<div class="col-md-12 mb-4">
<!--Card content-->
<div class="card">
<!-- List group links -->
<div class="card-body">
<h5>Users Online:
#php $u_total = '0'; #endphp
#foreach ($users as $user)
#php
if($user->isUserOnline()) {
$u_total = $u_total + 1;
}
#endphp
#endforeach
{{ $u_total }}
</h5>
<table id="datatable1" class="table table-bordered">
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Email</th>
<th>Role</th>
<th class="text-center">Online/Offline</th>
<th class="text-center">Banned/Unban</th>
<th>Action</th>
</tr>
</thead>
<tbody>
#foreach ($users as $user)
<tr>
<input type="hidden" name="id" value="{{ $user->id }}">
<td>{{ $user->id }}</td>
<td>{{ $user->name }}</td>
<td>{{ $user->email }}</td>
<td>{{ $user->role_as }}</td>
<td>
#if($user->isUserOnline())
<label class="py-2 px-3 badge btn-success" for="">Online</label>
#else
<label class="py-2 px-3 badge btn-warning" for="">Offline</label>
#endif
</td>
<td>
#if($user->isBanned == '0' )
<label class="py-2 px-3 badge btn-primary">Not Banned</label>
#elseif($user->isBanned == '1')
<label class="py-2 px-3 badge btn-danger">Banned</label>
#endif
</td>
<td>
<a class="badge badge-pill btn-primary px-3 py-2" href="{{ url('role-edit/'.$user->id) }}">Editar</a>
<a class="delete badge badge-pill btn-danger px-3 py-2" data-toggle="modal" href="{{ url('user-delete/'.$user->id) }}" data-target="#delete" data-id="{{ $user->id }}">Borrar</a>
</td>
</tr>
#endforeach
</tbody>
</table>
{{-- <div>
{{ $users->links() }}
</div> --}}
</div>
<!-- List group links -->
</div>
</div>
<!--/.Card-->
</div>
<!--Grid row-->
</div>
#endsection
#section('scripts')
<script>
$(document).ready(function() {
$(document).on('click', '.delete', function (e) {
e.preventDefault();
var id = $(this).data('id');
swal.fire({
title: "¿Estás Seguro/a?",
text: "¡No podrás revertir esto!",
icon: 'warning',
showCancelButton: true,
cancelButtonText: 'Cancelar',
confirmButtonColor: '#3085d6',
cancelButtonColor: '#d33',
confirmButtonText: 'Sí, Borralo!'
},
function() {
$.ajax({
type: "POST",
url: "{{url('/user-delete/{id}')}}",
data: {id:id},
success: function (data) {
//
}
});
});
});
});
</script>
#endsection
Within my web.php (relevant code only)
Route::group(['middleware' => ['auth', 'isAdmin']], function () {
Route::get('/dashboard', function () {
return view('admin.dashboard');
});
Route::get('registered-user', 'Admin\RegisteredController#index');
Route::delete('/user-delete/{id}', 'Admin\RegisteredController#destroy');
Route::get('registered-empresa', 'Admin\EmpresaController#index');
Route::get('registered-empleado', 'Admin\EmpleadoController#index');
Route::get('role-edit/{id}', 'Admin\RegisteredController#edit');
Route::put('role-update/{id}', 'Admin\RegisteredController#updaterole');
Route::post('save-empresa', 'Admin\EmpresaController#store');
Route::get('/edit-empresa/{id}', 'Admin\EmpresaController#edit');
Route::put('/empresa-update/{id}', 'Admin\EmpresaController#update');
Route::get('/edit-empleado/{id}', 'Admin\EmpleadoController#edit');
Route::put('/empleado-update/{id}', 'Admin\EmpleadoController#update');
Route::post('save-empleado', 'Admin\EmpleadoController#store');
});
RegisteredController.php (delete function only)
public function destroy(Request $request, $id)
{
// $user = User::findOrFail($id)->delete();
// return redirect()->back()->with('status', 'Usuario ha sido borrado.');
// $user = User::find($id);
// $user->delete();
// return redirect()->back()->with('status', 'Usuario ha sido borrado.');
User::destroy($id);
}
EDIT!!!
I changed the way I am calling the sweetalert2 but am still getting errors. I changed my delete button in index.blade.php to
<a class="delete badge badge-pill btn-danger px-3 py-2" onclick="deleteConfirmation({{ $user->id }})">Borrar</a>
In the same file, I changed the script to the following:
function deleteConfirmation(id) {
swal.fire({
title: "Borrar?",
text: "¿Estás seguro/a?",
icon: "warning",
showCancelButton: !0,
confirmButtonText: "Sí,Borralo!",
cancelButtonText: "Cancelar",
reverseButtons: !0
}).then(function (e) {
if (e.value === true) {
var CSRF_TOKEN = $('meta[name="csrf-token"]').attr('content');
$.ajax({
type: 'POST',
url: "{{url('/user-delete')}}/" + id,
data: {_token: CSRF_TOKEN},
dataType: 'JSON',
success: function (results) {
if (results.success === true) {
swal.fire("Done!", results.message, "success");
} else {
swal.fire("Error!", results.message, "error");
}
}
});
} else {
e.dismiss;
}
}, function (dismiss) {
return false;
})
}
I also removed the .ready function as it was causing a conflict with sweetalert2
My Delete function in my RegisteredController now looks like this:
public function delete($id)
{
$delete = User::where('id', $id)->delete();
// check data deleted or not
if ($delete == 1) {
$success = true;
$message = "Usuario borrado exitosamente";
} else {
$success = true;
$message = "Usuario no encontrado";
}
// Return response
return response()->json([
'success' => $success,
'message' => $message,
]);
}
}
And in my web.php, I changed the route to:
Route::post('/user-delete/{id}', 'Admin\RegisteredController#delete');
The sweet alert now pops up and when I click delete, I get the console error:
POST http://ecomsivendo.test/user-delete/4 419 (unknown status)
You also need the headers section for jquery ajax calls.
$.ajax({
type: "POST",
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
//.......
Also make sure you have the meta tag in the <head> on the page.
<meta name="csrf-token" content="{{ csrf_token() }}">
Thank you for all those who tried to help me on this. I ended up giving the code another overhaul and this is what I had to do to get it to work.
I had to change my ajax request in the index.blade.php
function deleteConfirmation(id) {
swal.fire({
title: "Borrar?",
text: "¿Estás seguro/a?",
icon: "warning",
showCancelButton: true,
confirmButtonText: "Sí,Borralo!",
cancelButtonText: "Cancelar"
}).then(function (e) {
if (e.value === true) {
var CSRF_TOKEN = $('meta[name="csrf-token"]').attr('content');
$.ajax({
type: 'POST',
url: "{{url('/user-delete')}}/" + id,
headers: {
'X-CSRF-TOKEN': '<?php echo csrf_token() ?>'
},
data: {"id": id, _method: 'delete'},
dataType: 'JSON',
success: function (results) {
if (results.success === true) {
swal.fire("¡Hecho!", results.message, "success");
setTimeout(function() {
location.reload();
}, 1000);
} else {
swal.fire("¡Error!", results.message, "error");
}
}
});
} else {
e.dismiss;
}
}, function (dismiss) {
return false;
})
}
I am not happy with the setTimout function to get the page to reload and if someone can offer a better solution to avoid reload, I would really appreciate it.
in the controller, I had to change the delete function to the following:
public function delete($id)
{
$delete = User::where('id', $id)->delete();
// check data deleted or not
if ($delete == 1) {
$success = true;
$message = "Usuario borrado exitosamente";
} else {
$success = true;
$message = "Usuario no encontrado";
}
// Return response
return response()->json([
'success' => $success,
'message' => $message,
]);
}
And finally in my web.php, I have the route as:
Route::delete('/user-delete/{id}', 'Admin\RegisteredController#delete');
like I mentioned earlier, I feel like the setTimeout is a hack and I would prefer something a bit more elegant.
In the end, the code does what it is supposed to do and that is delete the entry and update the view.

Integration Laravel with database.net - html tags visible in row

I use this component in my project: yajra/laravel-datatables
I have controller:
public function dataTable(Request $request)
{
if ($request->ajax()) {
return Datatables::of($this->model->all())
->addIndexColumn()
->editColumn('enable', function ($row) {
if ($row->enable == 1)
return '<span class="label font-weight-bold label-lg label-light-success label-inline">aktywny</span>';
else return '<span class="label font-weight-bold label-lg label-light-danger label-inline">nieaktywny</span>';
})
->editColumn('name', function ($row) {
return Str::limit($row->name, 80, '...');
})
->addColumn('action', function ($row) {
$btn = '<i class="far fa-edit"></i> ';
$btn .= '<i class="removeItem far fa-trash-alt"></i> ';
return $btn;
})
->rawColumns(['action'])
->make(true);
}
}
and html:
<table class="table table-bordered data-table ">
<thead>
<tr class="resources">
<th>ID</th>
<th>Nazwa produktu</th>
<th>Status</th>
<th width="100px" class="text-center">Akcja</th>
</tr>
</thead>
<tbody class="data-table-center">
</tbody>
</table>
</div>
<div class="datatable datatable-bordered datatable-head-custom" id="kt_datatable"></div>
$(function () {
var table = $('.data-table').DataTable({
processing: true,
serverSide: true,
ajax: "{{ route('product.dataTable') }}",
language: {
url: "{{ asset('js/lang/Polish.json') }}"
},
iDisplayLength: 50,
render: function (data, type, row) {
return data;
},
columns: [
{data: 'DT_RowIndex', name: 'DT_RowIndex'},
// {data: 'id', name: 'id'},
{data: 'name', name: 'name'},
{data: 'enable', name: 'enable'},
{data: 'action', name: 'action', orderable: false, searchable: false},
]
});
});
In the status (enable) column I see this html instead of the final string. As if a blade would replace such html badly.
My result:
<span class="label font-weight-bold label-lg label-light-success label-inline">aktywny</span>
Prview: https://ibb.co/6tXdH65
How can I fix it?
just add enable in your action in dataTable function
->rawColumns(['action','enable'])
->make(true);

I can't understand how the destroy function work here?

I am working on old laravel project and I have to modify existing one. So I am now trying to understand the code. The project is on laravel and yajra datatable. I can't understand how the destroy function work ? In the view there is a no call for destroy function but when I click the delete button still it is working.
Controller
public function loadSizes()
{
$sizes = Size::select(['id', 'name', 'code'])->get();
return DataTables::of($sizes)
->addColumn('action', function ($size) {
return '<i class="fa fa-wrench" aria-hidden="true"></i>
<button type="button" data-id="' . $size->id . '" class="btn btn-default remove-size remove-btn" data-toggle="tooltip" data-placement="top" title="Delete"><i class="fas fa-trash-alt" aria-hidden="true"></i></button>';
})
->rawColumns(['action'])
->make(true);
}
public function destory(Request $request)
{
$result = Size::where('id', $request->input('size_id'))->delete();
if ($result) {
return "SUCCESS";
} else {
return "FAIL";
}
}
view
#extends('layouts.sidebar')
#section('content')
<div class="row">
<div class="col-sm-12 pad-main">
<div class="row">
<div class="col-md-6">
<h4 class="cat-name"> Size List</h4>
</div>
</div>
<div class="row">
<div class="col-md-12 table-responsive pad-tbl">
<table class="table table-striped" id="size_table">
<thead>
<tr>
<th scope="col"> Name</th>
<th scope="col"> Code</th>
<th scope="col"> Action</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
</div>
#if (Session::has('action'))
#if (Session::get('action') == "create")
#if (Session::has('status_success'))
<script > showAlert("SUCCESS", "Size creation successful");</script >
#elseif(Session::has('status_error')))
<script > showAlert("FAIL", "Size creation fail");</script >
#endif
#elseif(Session::get('action') == "update")
#if (Session::has('status_success'))
<script > showAlert("SUCCESS", "Size update successful");</script >
#elseif(Session::has('status_error')))
<script > showAlert("FAIL", "Size update fail");</script >
#endif
#endif
#endif
<script>
$(document).ready(function () {
$('#size_table').DataTable({
language: {
searchPlaceholder: "Search records"
},
"columnDefs": [
{"className": "dt-center", "targets": "_all"}
],
processing: true,
serverSide: true,
ajax: '{!! url(' / load - sizes') !!}',
columns: [
{data: 'name', name: 'name'},
{data: 'code', name: 'code'},
{data: 'action', name: 'action'},
]
});
});
$(document.body).on("click", ".remove-size", function () {
var size_id = $(this).data('id');
showConfirm("DELETE", "Do you want to delete this Size ?", "deleteSize(" + size_id + ")");
});
function deleteSize(id) {
$.ajax({
type: 'get',
url: '{!! url('delete-size') !!}',
data: {size_id: id},
success: function (data) {
if (data == "SUCCESS") {
$('[data-id="' + id + '"]').closest('tr').remove();
showAlert("SUCCESS", "Delete Size successful");
}
}, error: function (data) {
showAlert("FAIL", "Delete Size fail");
}
});
}
</script>
#endsection
At the bottom of the blade view there is an AJAX in function destory(id).
That AJAX is sending a GET request to a URL delete-size with size id.
Now, if you search your web.php file for that URL (location - routes/web.php), you'll find something like this:
Route::get('delete-size', 'SizeController#destory');
This route would be sending the size id to your destory function, which is in turn searching the Size in your DB and deleting it.
// Controller
public function destroy($id)
{
Tag::find($id)->delete();
Toastr::success('Tag Successfully Deleted',"Success");
return redirect()->back();
}
// Route
Route::group(['as'=>'admin.','prefix'=>'admin','namespace'=>'Admin','middleware'=>['auth','admin']], function (){
Route::resource('tag','TagController');
});
// HTML file
<form id="delete-form-{{ $tag->id }}" action="{{ route('admin.tag.destroy',$tag->id) }}" method="POST" style="display: none;">
#csrf
#method('DELETE')
</form>

Categories