I want to export data from the database to .xlsx using Laravel-Excel.
I want to pass three parameters to query the data and download into excel file.
I already search and read a few examples but still failed to make the excel file to download.
This is my blade file.
#section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-3"></div>
<div class="col-md-6">
<div class="card">
<div class="card-header">Download Report</div>
<div class="card-body">
<div class="col-md-12" style="margin-bottom:15px">
<select class="form-control" name="plant" id="plant">
<option selected value="All">Please Select Plant</option>
#foreach($plants as $plant)
<option value="{{ $plant->id }}">{{ $plant->name }}</option>
#endforeach
</select>
</div>
<div class="col-md-12" style="">
<div class="input-group input-daterange" align="center">
<input type="text" name="from_date" id="from_date" readonly class="form-control" value="<?php echo date("Y-m-d");?>" />
<div class="input-group-addon" >To</div>
<input type="text" name="to_date" id="to_date" readonly class="form-control" value="<?php echo date("Y-m-d");?>"/>
</div>
</div>
<br>
<div class="col-md-12" align="center">
<button type="button" name="search" id="search" class="btn btn-info btn-block">Download</button>
</div>
</div>
</div>
</div>
<div class="col-md-3"></div>
</div>
</div>
<script type="text/javascript">
$(function() {
var date = new Date();
$('.input-daterange').datepicker({
todayBtn: 'linked',
format: 'yyyy-mm-dd',
autoclose: true
});
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$('#search').click(function(e){
e.preventDefault();
var from_date = $('#from_date').val();
var to_date = $('#to_date').val();
var plant = $('#plant').val();
if(plant != 'All')
{
$.ajax({
url:"{{ route('export') }}",
data:{from_date:from_date, to_date:to_date, plant:plant},
dataType:"json",
})
}
else
{
alert('Please Select Plant');
}
});
});
</script>
#endsection
This is my function at the controller
public function export(Request $request)
{
return (new DetailReportDownload($request->plant,$request->from_date,$request->to_date))->download('Report Details.xlsx');
}
and This is my Export file
class DetailReportDownload implements FromQuery, WithHeadings
{
use Exportable;
protected $plant,$from,$to;
public function __construct(String $from,String $to,String $plant)
{
$this->plant = $plant;
$this->from = $from;
$this->to = $to;
}
public function headings(): array
{
return [
'plandate',
'workcentre',
'partno',
'prodduration',
'totaldowntime',
'planout',
'cumout',
];
}
public function query()
{
return DB::table('plannings')
->select(DB::raw('plandate, workcentre, partno, prodduration, coalesce(sum(downduration),0) as totaldowntime, planout, cumout'))
->join('prodstatuses', 'plannings.id', '=', 'prodstatuses.id')
->leftJoin('downtimes', 'plannings.id', '=', 'downtimes.plan_id')
->whereBetween('plandate', array($this->from, $this->to))
->where('plant_id',$this->plant)
->where('status','Finished')
->groupBy('plannings.id')
->orderBy('plannings.id');
}
}
I wanted to download excel file from parameter given in blade file.
Thanks in advance for any help
create a provider to add below code & register to app.php file
Sheet::macro('styleCells', function (Sheet $sheet, string $cellRange, array $style) {
$sheet->getDelegate()->getStyle($cellRange)->applyFromArray($style);
});
And create class to download data using parameters,
<?php
namespace App\Modules\User\Http\Exports;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\FromView;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\AfterSheet;
/**
* Class ExportUsers
* #package App\Exports
*/
class ExportUsers implements FromView, ShouldAutoSize, WithEvents
{
protected $plannings;
/**
* ExportUsers constructor.
* #param Collection $plannings
*/
public function __construct(Collection $plannings) {
$this->plannings = $plannings;
}
/**
* #return View
*/
public function view() : View {
return view('plannings_list', [
'plannings' => $this->plannings,
]);
}
/**
* #return array
*/
public function registerEvents() : array {
return [
AfterSheet::class => function (AfterSheet $event) {
$this->createStyle($event, 'A1:N1', 9);
$event->sheet->styleCells(
'A1:N1',
[
'font' => [
'bold' => true,
]
]
);
},
];
}
/**
* #param $event
* #param $cell
* #param $size
* #throws \PhpOffice\PhpSpreadsheet\Exception
*/
private function createStyle($event, $cell, $size) {
/** #var AfterSheet $event */
$event->sheet->getDelegate()->getStyle($cell)->getFont()->setSize($size);
}
}
add this code to controller
private function downloadCsv($exportCsvList) {
return Excel::download(new ExportUsers($exportCsvList),
'students.xlsx');
}
Related
I am having issue with saving attendance record of student in attendance listings. The frontend part is working well but record saved in backend of attendance table is not shown. How can I save record in backend table of attendance which consists of level_id, teacher_id and student_id
Here is my attendance migrations table
$table->id();
$table->unsignedBigInteger('level_id');
$table->unsignedBigInteger('teacher_id');
$table->unsignedBigInteger('student_id');
$table->foreign('level_id')->references('id')->on('levels');
$table->foreign('teacher_id')->references('id')->on('teachers');
$table->foreign('student_id')->references('id')->on('students');
$table->date('attendance_date');
$table->string('attendance_status');
$table->timestamps();
Here is my students migrations tables
$table->id();
// The Parents table must exist and Must have 'id' as Primary Key
$table->unsignedbiginteger('parent_id');
$table->unsignedbiginteger('level_id');
$table->foreign('parent_id')->references('id')->on('parents')
->onDelete('cascade');
$table->foreign('level_id')->references('id')->on('levels');
$table->string('student_roll_no');
$table->string('student_surname');
$table->string('student_middle_name')->nullable();
$table->string('student_given_name');
$table->string('student_place_of_birth');
$table->date('student_date_of_birth');
$table->string('student_gender');
$table->text('student_home_address');
$table->string('student_suburb')->nullable();
$table->string('student_post_code');
$table->string('student_home_phone')->nullable();
$table->string('student_work_phone')->nullable();
$table->string('student_mobile_phone');
$table->string('student_email')->nullable();
$table->string('student_photo')->nullable();
$table->string('language_spoken_at_home')->nullable();
$table->string('school_name');
$table->string('student_semester')->nullable();
$table->string('school_suburb')->nullable();
$table->text('school_address')->nullable();
$table->string('student_oversea_full_paying')->nullable();
$table->string('emergency_person_one_name')->nullable();
$table->string('emergency_person_one_mobile_number');
$table->string('emergency_person_one_house_number')->nullable();
$table->string('emergency_person_two_name')->nullable();
$table->string('emergency_person_two_mobile_number')->nullable();
$table->string('emergency_person_two_house_number')->nullable();
$table->string('medical_condition')->nullable();
$table->boolean('medical_health_support')->nullable();
$table->boolean('family_court_orders');
$table->string('family_court_file')->nullable();
$table->boolean('authority_to_school_staff');
$table->boolean('authorize_school_staff_to_arrange_medical_treatment');
$table->boolean('authorize_school_staff_administering_medication');
$table->boolean('notify_the_school_absent');
$table->boolean('withdraw_child_from_school');
$table->boolean('authorize_photograph_to_school');
$table->boolean('authorize_child_name_school_newsletter_website');
$table->boolean('authorize_short_local_walks');
$table->boolean('authorize_participate_in_any_incursions');
$table->boolean('information_contained_in_this_form_correct');
$table->boolean('status')->default(1);
$table->timestamps();
Here is my levels tables
$table->bigIncrements('id');
$table->string('level_name');
$table->timestamps();
Here is my Teachers migrations tables
$table->id();
// The Parents table must exist and Must have 'id' as Primary Key
$table->unsignedbiginteger('user_id')->nullable();
$table->foreign('user_id')->references('id')->on('users');
$table->string('teacher_name');
$table->string('teacher_email')->unique();
$table->string('teacher_home_phone')->nullable();
$table->string('teacher_mobile_phone');
$table->string('teacher_work_phone')->nullable();
$table->string('teacher_home_address');
$table->string('teacher_suburb')->nullable();
$table->string('teacher_postcode');
$table->timestamps();
Here is my Attendance Controller
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use App\Models\Levels;
use App\Models\Teacher;
use App\Models\Student;
use App\Models\Attendance;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
class AttendanceController extends Controller
{
/**
* Create a new controller instance
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
}
/**
* Show the application dashboard
*
* #return \Illuminate\Contracts\Support\Renderable
*/
public function index($level_id = NULL)
{
$levels = Levels::all();
$students = Student::all();
return view('admin.attendance.list', compact( 'levels', 'students','level_id'));
}
/**
* Perform Actions in attendance.add
*
* #return \Illuminate\Contracts\Support\Renderable
*/
public function add()
{
$levels = array();
$students = array();
return view('admin.attendance.add', compact('levels', 'teachers'));
}
/**
* Store values in application dashboard
*
* #return \Illuminate\Contracts\Support\Renderable
*/
public function store(Request $request, $level_id)
{
//get form data
$data = $request->all();
//Creeate Student record
$students = Student::all();
$levels = Levels::all();
if($level_id){
$levels = Levels::find($level_id);
if($levels){
$attendance = Attendance::with(['student', 'levels'])->first();
return view('admin.attendance.add', compact('students','level_id', 'levels', 'attendance'));
}
}
}
}
Here is my Attendance model
public function student()
{
return $this->belongsTo(Student::class,'student_id');
}
public function teacher()
{
return $this->belongsTo(Teacher::class, 'teacher_id');
}
public function levels()
{
return $this->belongsTo(Levels::class, 'level_id');
}
Here is my list.blade.php file of containing attendance
#section('content')
#if(session()->has('message'))
<div class="row">
<div class="col-md-12">
<div class="alert alert-success">
{{ session()->get('message') }}
</div>
</div>
</div>
#endif
#if(isset($levels) || $levels == '')
<div class="form-row justify-content-center">
<div class="form-group col-xs-6">
<label for="Date"> Please Select Date</label>
<input type="date" name="attendance_date" value="{{ date('Y-m-d') }}" class="form-control" required>
</div>
<div class="form-group col-xs-6">
<label for="Attendance">Please Select Level to see registered students</label>
<select class="form-control" id="level_id" name="student_id">
<option value="" disabled selected>Select Level</option>
#foreach($levels as $level)
<option value="{{#$level->id}}">{{#$level->level_name}}</option>
#endforeach
</select>
</div>
</div>
#endif
#stop
#section('js')
<script>
jQuery(document).ready(function($) {
// get your select element and listen for a change event on it
$('#level_id').change(function() {
// set the window's location property to the value of the option the user has selected
window.location = '/attendance/add/'+$(this).val();
});
});
</script>
#endsection
Here is my add.blade.php file containing attendance
<form action="{{ route('attendance.index') }}" method="GET" class="w-full max-w-xl px-6 py-12" enctype="multipart/form-data">
#csrf
#php
$heads = [
'Name',
'Roll Number',
'Semester',
['label' => 'Attendance', 'no-export' => true, 'width' => 5],
];
/*$btnDetails = '<button class="btn btn-xs btn-default text-teal mx-1 shadow" title="Details">
<i class="fa fa-lg fa-fw fa-eye"></i>
</button>';*/
$config = [
'data' => $students,
'order' => [[1, 'asc']],
'columns' => [null, null, null, null, ['orderable' => true]],
];
#endphp
{{-- Minimal example / fill data using the component slot --}}
<x-adminlte-datatable id="table6" :heads="$heads" head-theme="light" theme="light custom-head-theme dt-responsive"
striped>
#if($config['data'])
#foreach($config['data'] as $row)
<tr class="{{ (isset($row['status']) && $row['status']==0) ? 'table-danger' : ''}}">
<td>{!! $row['student_given_name'] !!}</td>
<td>{!! $row['student_roll_no']!!}</td>
<td>{!! $row['student_semester']!!}</td>
<td>
<nobr>
<select class="form-control" name="attendance_status" value="{{old('attendance_status'), #$attendance->attendance_status}}" id="attendance_status" required>
<option value="" {{#$attendance->attendance_status == '' ? 'selected' : ''}} disabled selected>Select Option</option>
<option value="Present" {{#$attendance->attendance_status == 'present' ? 'selected' : ''}} selected>Present</option>
<option value="Absent" {{#$attendance->attendance_status == 'absent' ? 'selected' : ''}}>Absent</option>
</select>
<input type="text" name="textinput" id="level_id" placeholder="Reason">
</nobr>
</td>
</tr>
#endforeach
#endif
</x-adminlte-datatable>
<div class="row mt-3">
<div class="col-md-12">
<div class="card-footer">
<div class="float-left col-md-4 mb-2">
<button type="submit" name="save_close" value="true" class="btn btn-primary btn-lg btn-block">Save & Close</button>
</div>
<div class="float-right col-md-4 mb-2">
<button type="button" class="btn btn-secondary btn-lg btn-block">Cancel</button>
</div>
</div>
</div>
</div>
</form>
#stop
What modifications are required in attendance controller in order to save record in table and I can view it on frontend side as well
On your AttendanceController you just show data, not insert data to database, you should get the request data and insert data to database, but first check your blade file, you must make an input for level_id, teacher_id, and student_id
to check your attachment you can use
dd($request);
die();
on your first line AttendanceController function store
public function store(Request $request, $level_id)
{
dd($request);
die();
//get form data
$data = $request->all();
//Create Student record
$students = Student::all();
$levels = Levels::all();
if($level_id){
$levels = Levels::find($level_id);
if($levels){
$attendance = Attendance::with(['student', 'levels'])->first();
return view('admin.attendance.add', compact('students','level_id', 'levels', 'attendance'));
}
}
}
if your system catch the good request
you should try this
public function store(Request $request, $level_id)
{
$levels_id = $request->level_id;
$teachers_id = $request->teacher_id;
$students_id = $request->student_id;
$data = [$levels_id,teachers_id,students_id];
attendance::create($data);
}
there's the code to save data into your laravel project, you should approve my solution
I have implemented a notification system in my app and it works fine, but when I want to use it in another controller that uses ajax, the notifications are not loaded in the database. Is there any limitation with Ajax to do this kind of notifications?
Suggestions?
index view:
#extends('layouts.app')
#section('content')
<section class="section">
<div class="section-header">
<h3 class="page__heading">Derivar IP</h3>
</div>
<div class="section-body">
<div class="row">
<div class="col-sm-9">
<div class="card">
<div class="card-header">
<h4>Siniestros para derivar</h4>
</div>
<div class="card-body">
<table class="table table-sm m-1 p-1 table-bordered table-hover table-striped tablita" style="width:100%">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">Siniestro</th>
<th scope="col">Fecha IP</th>
<th scope="col">Modalidad</th>
<th scope="col">Dirección</th>
<th scope="col">Localidad</th>
<th scope="col">Inspector</th>
<th scope="col">Acciones</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
</div>
</div>
<div class="col-sm-3" style="position:fixed; bottom:250px; right:0px">
<div class="card">
<div class="card-header">
<span id="addT">Asignar IP</span>
<span id="updateT">Asignar IP</span>
</div>
<div class="card-body">
<div class="col-xs-4 col-sm-4 col-md-4">
<div class="form-group">
<label for="siniestro">Siniestro</label>
<input type="text" name="siniestro" id="siniestro" class="form-control">
</div>
</div>
<div class="col-xs-4 col-sm-4 col-md-4">
<label for="inspector">inspector</label>
<select class="form-select col-xs-12 col-sm-12 col-md-12" aria-label="Default select example" id="inspector"´for="inspector" name="inspector"">
#foreach ($users as $user)
<option value="{{ $user->id }}">{{ $user->name }}</option>
#endforeach
</select>
</div>
<div class="col-xs-4 col-sm-4 col-md-4">
<div class="form-group">
<label for="patente">Patente</label>
<input type="text" name="patente" id="patente" class="form-control">
</div>
</div>
<div class="col-xs-4 col-sm-4 col-md-4">
<div class="form-group">
<label for="fechaip">Fecha IP</label>
<input type="date" name="fechaip" id="fechaip" class="form-control">
</div>
</div>
<input type="hidden" id="id">
<!-- <button type="button" href="#" data-target="#ModalEnviar" class="btn btn-primary m-2" data-toggle="modal">Enviar IP</button> -->
<button type="submit" id="updateButton" class="btn btn-primary btn-sm" onclick="updateData(event)">Update</button>
</div>
</div>
</div>
</div>
</div>
</section>
#endsection
<!-- DataTables JS -->
<script src="{{ asset('assets/js/jquery.min.js') }}"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/pdfmake.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/vfs_fonts.js"></script>
<script type="text/javascript" src="https://cdn.datatables.net/v/bs4/jszip-2.5.0/dt-1.11.5/b-2.2.2/b-colvis-2.2.2/b-html5-2.2.2/b-print-2.2.2/r-2.2.9/datatables.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/js/bootstrap.min.js"></script>
<!-- searchPanes -->
<script src="https://cdn.datatables.net/searchpanes/1.0.1/js/dataTables.searchPanes.min.js"></script>
<!-- select -->
<script src="https://cdn.datatables.net/select/1.3.1/js/dataTables.select.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.1.1/js/all.min.js" integrity="sha512-6PM0qYu5KExuNcKt5bURAoT6KCThUmHRewN3zUFNaoI6Di7XJPTMoT6K0nsagZKk2OB4L7E3q1uQKHNHd4stIQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
#section('javas')
<script>
$('.tablita').DataTable({
"processing": "true",
"serverSide": "true",
"ajax": "{{route('datatable.paraderivar')}}",
"select": "true",
"columns":[
{data: 'id'},
{data: 'siniestro'},
{data: 'fechaip'},
{data: 'modalidad'},
{data: 'direccion'},
{data: 'localidad'},
{data: 'inspector'},
]
});
</script>
<script>
$('#addT').hide();
$('#addButton').hide();
$('#updateT').show();
$('#updateButton').show();
$.ajaxSetup({
headers:{
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
})
//---------------------------------------------- Llamar datos de la BD ---------------------------------------------------------------
function allData(){
$.ajax({
type: "GET",
dataType: "json",
url: "/teacher/all",
success: function (response){
var data = ""
$.each(response, function(key, value){
data = data + "<tr>"
data = data + "<td>"+value.id+"</td>"
data = data + "<td>"+value.siniestro+"</td>"
data = data + "<td>"+value.fechaip+"</td>"
data = data + "<td>"+value.modalidad+"</td>"
data = data + "<td>"+value.direccion+"</td>"
data = data + "<td>"+value.localidad+"</td>"
data = data + "<td>"+value.inspector+"</td>"
data = data + "<td>"
data = data + "<button class='btn btn-info btn-sm' onclick='editData("+value.id+")'>Asignar</button>"
data = data + "</td>"
data = data + "</tr>"
})
$('tbody').html(data);
}
})
}
// --------------------------------------------- fin de llamar datos de la DB ----------------------------------------------------------
allData();
// --------------------------------------------- Limpiar los campos despues del submit -------------------------------------------------
function clearData(){
$('#siniestro').val('');
$('#fechaip').val('');
$('#inspector').val('');
$('#nameError').text('');
$('#titleError').text('');
$('#instituteError').text('');
}
// --------------------------------------------- fin de limpiar los campos despues del submit -------------------------------------------------
// --------------------------------------------- Agregar registros a la table de BD -------------------------------------------------
function addData(){
var siniestro = $('#siniestro').val();
var fechaip = $('#fechaip').val();
var inspector = $('#inspector').val();
var fechaip = $('#fechaip').val();
var patente = $('#patente').val();
$.ajax({
type: "POST",
dataType: "Json",
data: {siniestro:siniestro, fechaip:fechaip, inspector:inspector, patente:patente},
url:"/teacher/store/",
success: function(data){
allData();
clearData();
console.log('datos agregados con éxito');
},
error: function(error){
$('#nameError').text(error.responseJSON.errors.name);
$('#titleError').text(error.responseJSON.errors.title);
$('#instituteError').text(error.responseJSON.errors.institute);
}
})
}
// --------------------------------------------- fin de agregar registros a la table de BD -------------------------------------------------
// --------------------------------------------- Editar registros a la table de BD ---------------------------------------------------------
function editData(id){
$.ajax({
type:"get",
dataType:"json",
url:"/teacher/edit/"+id,
success: function(data){
$('#addT').hide();
$('#addButton').hide();
$('#updateT').show();
$('#updateButton').show();
$('#id').val(data.id);
$('#siniestro').val(data.siniestro);
$('#fechaip').val(data.fechaip);
$('#inspector').val(data.inspector);
$('#patente').val(data.patente);
console.log(data);
}
})
}
// --------------------------------------------- Fin de editar registros a la table de BD -------------------------------------------------
// --------------------------------------------- Update de registros a la table de BD -----------------------------------------------------
function updateData(event){
event.preventDefault();
var id = $('#id').val();
var siniestro = $('#siniestro').val();
var fechaip = $('#fechaip').val();
var inspector = $('#inspector').val();
var patente = $('#patente').val();
$.ajaxSetup({
headers:{
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
})
$.ajax({
type: "PUT",
dataType: "json",
data: {inspector:inspector, siniestro:siniestro, fechaip:fechaip, patente:patente},
url: "/teacher/update/"+id,
success: function(response){
allData();
clearData();
console.log('Siniestro asignado con éxito');
}
})
}
</script>
#endsection
Controller:
<?php
namespace App\Http\Controllers;
use App\Models\Teacher;
use App\Models\Siniestro;
use App\Models\User;
//Notificaciones
use App\Notifications\DataEstadoNotificacion;
use App\Events\DataEstadoEvent;
use Illuminate\Support\Facades\Notification;
use Illuminate\Http\Request;
class TeacherController extends Controller
{
public function allUser(){
$data = User::orderBy('fechaip','DESC')->get();
dd($data);
return response()->json($data);
}
//-----------storeData------------
public function storeData(Request $request){
$request->validate([
]);
$data = Siniestro::insert($request->all()
);
return response()->json($data);
}
// public function editData($id){
// $data = Siniestro::findOrFail($id);
// return response()->json($data);
// }
public function updateData(Request $request, $id)
{
$data = Siniestro::findOrFail($id)->update($request->all();
// event(new DataEstadoEvent($data));
);
return response()->json($data);
auth()->user()->notify(new DataEstadoNotification($data));
/**
* Remove the specified resource from storage.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
}
}
Notification:
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use App\Models\Siniestro;
use Carbon\Carbon;
class DataEstadoNotificacion extends Notification
{
use Queueable;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct(Data $data)
{
$this->data = $data;
}
/**
* Get the notification's delivery channels.
*
* #param mixed $notifiable
* #return array
*/
public function via($notifiable)
{
return ['database'];
}
/**
* Get the mail representation of the notification.
*
* #param mixed $notifiable
* #return \Illuminate\Notifications\Messages\MailMessage
*/
public function toMail($notifiable)
{
return (new MailMessage)
->line('The introduction to the notification.')
->action('Notification Action', url('/'))
->line('Thank you for using our application!');
}
/**
* Get the array representation of the notification.
*
* #param mixed $notifiable
* #return array
*/
public function toArray($notifiable)
{
return [
'siniestro' => $this->data->siniestro,
'patente' => $this->data->patente,
'fechaip' => $this->data->fechaip,
'tiempo' => Carbon::now()->diffForHumans(),
];
}
}
EventServiceProvider
<?php
namespace App\Providers;
use Illuminate\Auth\Events\Registered;
use Illuminate\Auth\Listeners\SendEmailVerificationNotification;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Event;
use App\Events\SiniestroEstadoEvent;
use App\Listeners\SiniestroEstadoListener;
use App\Events\DataEstadoEvent;
use App\Listeners\DataEstadoListener;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* #var array<class-string, array<int, class-string>>
*/
protected $listen = [
Registered::class => [
SendEmailVerificationNotification::class,
],
SiniestroEstadoEvent::class => [
SiniestroEstadoListener::class,
],
DataEstadoEvent::class => [
DataEstadoListener::class,
],
];
/**
* Register any events for your application.
*
* #return void
*/
public function boot()
{
//
}
/**
* Determine if events and listeners should be automatically discovered.
*
* #return bool
*/
public function shouldDiscoverEvents()
{
return false;
}
}
Listener:
<?php
namespace App\Listeners;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Support\Facades\Notification;
use App\Models\User;
use App\Notifications\DataEstadoNotificacion;
class DataEstadoListener
{
/**
* Create the event listener.
*
* #return void
*/
public function __construct()
{
//
}
/**
* Handle the event.
*
* #param object $event
* #return void
*/
public function handle($event)
{
$users = User::find($event->data->inspector);
Notification::send($users, new DataEstadoNotificacion($event->data));
}
}
Event:
<?php
namespace App\Events;
use Illuminate\Broadcasting\Channel;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;
class DataEstadoEvent
{
public $data;
use Dispatchable, InteractsWithSockets, SerializesModels;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct($data)
{
$this->data = $data;
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new PrivateChannel('channel-name');
}
}
We have been using Yajra DataTables with Laravel 5 for a few years and have built up a library of over 50 of them, basically for the index page of a BREAD UI. It's finally time to upgrade, and We're using the service implementation, which looks like this.
The current code is working against
"yajra/laravel-datatables-oracle": "^6.0",
Here is the Controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use App\DataTables\WidgetDataTable;
use App\Models\Widget;
use Illuminate\Support\Facades\Auth;
use App\Models\Widgetaccount;
use App\Events\Widgetcrud;
use App\DataTables\WidgetHistoryDataTable;
use Illuminate\Support\Facades\DB;
class WidgetController extends Controller
{
/**
* Create a new controller instance
*
* #return void
*/
public function __construct()
{
$this->middleware('permission:widget_view', ['only' => ['index', 'history']]);
$this->middleware('permission:widget_create', ['only' => ['create','store']]);
$this->middleware('permission:widget_edit', ['only' => ['edit','update']]);
$this->middleware('permission:widget_delete', ['only' => ['destroy']]);
}
/**
* Display a listing of the resource.
*
* #param object $dataTable
* #return \Illuminate\Http\Response
*/
public function index(WidgetDataTable $dataTable)
{
return $dataTable->render('widget.index', [
'title' => 'Manage Widgets',
]);
}
// other methods here
}
Here is the DataTables class:
<?php
namespace App\DataTables;
use Illuminate\Support\Facades\DB;
use Yajra\DataTables\Services\DataTable;
use Illuminate\Support\Facades\Auth;
class widgetDataTable extends DataTable
{
/**
* Display ajax rwidgetonse.
*
* #return \Illuminate\Http\JsonResponse
*/
public function ajax()
{
return $this->datatables
->queryBuilder($this->query())
->editColumn(
'edit accounts',
function ($widget) {
return '<a href="' . route('widgetaccounts.index', 'widgetid=' . $widget->id)
. '" class="btn btn-xs btn-primary"><i class="glyphicon glyphicon-edit"></i> </a>';
}
)
->editColumn(
'documentation',
function ($widget) {
if ($widget->documentation != null) {
return '<a href="javascript:void(0)" data-value="' . $widget->documentation .
'" class="btn btn-xs btn-primary opendocument">View</a>';
} else {
return '';
}
}
)
->addColumn(
'action',
function ($widget) {
return '<a href="' . route('widgets.edit', $widget->id) .
'" class="btn btn-xs btn-primary" dusk="widget-edit-button-'.$widget->id .'"><i class="glyphicon glyphicon-edit"></i> Edit</a>
<a href="javascript:void(0)" data-remote="' . route('widgets.destroy', $widget->id) .
'" class="btn btn-xs btn-danger btn-delete" dusk="widget-delete-button-'.$widget->id .'"><i class="glyphicon glyphicon-trash"></i>Delete</a>';
}
)
->make(true);
}
/**
* Get the query object to be processed by dataTables.
*
* #return \Illuminate\Database\Eloquent\Builder|
*/
public function query()
{
$widget_id = null;
if ($this->request()->has("widgetid")) {
$widget_id = $this->request()->get("widgetid");
}
$query = DB::connection('dashboard')
->table('widgets')
->join('users', 'users.id', '=', 'widgets.user_id')
->whereNull('widgets.deleted_at')
->when($widget_id,
function ($queryvar, $widget_id) {
return $queryvar->where('widgets.id', $widget_id);
})
->select(
'widgets.id',
'widgets.name',
'widgets.active',
'users.name as username',
'widgets.documentation',
'widgets.created_at',
'widgets.updated_at',
'widgets.deleted_at'
);
return $this->applyScopes($query);
}
/**
* Optional method if you want to use html builder.
*
* #return \Yajra\Datatables\Html\Builder
*/
public function html()
{
if (Auth::user()->can('distribution_manage_widget_lists_edit')) {
return $this->builder()
->columns($this->getColumns())
->ajax('')
->addAction(['width' => '80px'])
->parameters([
'dom' => 'lBfrtip',
'buttons' => ['csv', 'excel'],
'pageLength' => 50
]);
}else{
return $this->builder()
->columns($this->getColumns())
->ajax('')
->parameters([
'dom' => 'lBfrtip',
'buttons' => ['csv', 'excel'],
'pageLength' => 50
]);
}
}
/**
* Get columns.
*
* #return array
*/
protected function getColumns()
{
return [
'id',
'name',
'active',
'documentation' => ['searchable' => false, 'orderable' => false],
'edit accounts' => ['searchable' => false, 'orderable' => false],
'last edited by' => ['name' => 'users.name', 'data' => 'username'],
'created_at',
'updated_at',
];
}
/**
* Get filename for export.
*
* #return string
*/
protected function filename()
{
return 'widgetdatatables_'.time();
}
}
Here is the view:
#extends('layouts.main')
#section('content')
#include('partials.panel-open', [ 'title' => "Manage widgets" ])
<form action="{{route('widgetsearch')}}" method="POST">
{{ csrf_field() }}
<div class="search_button_group">
<div class="row">
<div class="col-sm-4 col-sm-offset-2">
<label>Search for widget-related Settings: </label>
</div>
<div class="col-sm-6">
<div class="input-group">
<input type="text" class="form-control" placeholder="" name="search" aria-describedby="basic-addon1" required="required">
<button class="input-group-addon btn btn-primary" id="basic-addon1" type="submit">Go</button>
</div>
</div>
</div>
</div>
</form>
<div class="row form-group">
<div class="col-sm-6">
#permission(('widget_create'))
Add New widget
#endpermission
</div>
<div class="col-sm-6">
<div class="text-right">
widget History
</div>
</div>
</div>
{!! $dataTable->table(['class' => 'table table-bordered','id' =>'widget-table']) !!}
#permission(('widget_create'))
Add New widget
#endpermission
#include('partials.panel-close')
<div id="myModal" class="modal fade" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Documentation</h4>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
#endsection
#push('scripts')
<script src="/vendor/datatables/buttons.server-side.js"></script>
{!! $dataTable->scripts() !!}
<script type="text/javascript">
$('#widget-table').on('click', '.btn-delete[data-remote]', function (e) {
e.preventDefault();
if (confirm("Are you sure you want to delete"))
{
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
var url = $(this).data('remote');
$.ajax({
url: url,
type: 'DELETE',
dataType: 'json',
data: {method: '_DELETE', submit: true}
})
.always(function (data) {
var count = data.count;
if (count == 0) {
$('#widget-table').DataTable().draw(false);
} else {
alert("widget can't be deleted as there are associated widget Account/s (#" + count + ") under the same. Kindly remove the widget Account/s first.");
}
});
}
});
$(document).on("click",".opendocument",function(){
$(".modal-body").html($(this).data('value'));
$('#myModal').modal('show');
});
</script>
#endpush
Now I've updated composer and am trying to use:
"yajra/laravel-datatables-oracle": "^9.0",
"yajra/laravel-datatables-buttons": "^4.0",
And when I view the widget index, I get the ajax error dialog
DataTables warning: table id=widget-table -
Ajax error. For more information about this error,
please see http://datatables.net/tn/7
When I look in the Laravel.log:
[2020-07-24 10:30:55] local.ERROR: Call to a member function queryBuilder() on null
{"userId":19,"exception":"[object]
(Symfony\\Component\\Debug\\Exception\\FatalThrowableError(code: 0): Call to a member function queryBuilder() on null at /Projects/my-app/app/DataTables/WidgetDataTable.php:20)
[stacktrace]
#0 [internal function]: App\\DataTables\\WidgetDataTable->ajax()
So, it seems that on this line:
return $this->datatables
->queryBuilder(...
the datatables property is not set. So, I am stuck as to how to proceed, and have broken my entire application. Looking for advice on what to try or a guide on how to upgrade the Yajra service implementation without having to modify hundreds of files.
It's been a while, but as I myself was stuck at this point in the process of upgrading, I thought I would share the solution as the documentation lacks a bit of detail.
I only got to understand what to change after finding and comparing this example sheet in the documentation:
https://yajrabox.com/docs/laravel-datatables/master/quick-starter
Further changes are then introduced in yajra's upgrade guide:
https://yajrabox.com/docs/laravel-datatables/8.0/upgrade
Changes to the DataTables class:
1.
/**
* Display ajax rwidgetonse.
*
* #return \Illuminate\Http\JsonResponse
*/
public function ajax()
{
return $this->datatables
->queryBuilder($this->query())
becomes:
use Yajra\DataTables\DataTables;
public function dataTable(DataTables $dataTables, $query) {
return $dataTables->eloquent($query)
If you're ajax / datatables function contains the ->editColumn() api, remove the ->render(); at the end. Otherwise html will be parsed as string.
3.
private function getColumns()
{
...
}
becomes protected:
protected function getColumns()
{
...
}
Return Object of the html function is now CamelCased too:
* #return \Yajra\Datatables\Html\Builder
to
* #return \Yajra\DataTables\Html\Builder
the getColumns() function now returns Columns as Array of Columns:
return [
[
'name' => 'users.firstname',
'data' => 'firstname',
'title' => 'Vorname',
],
];
becomes:
return [
Column::computed('firstname')
->name('users.firstname')
->title('Vorname'),
];
For which you need to import:
use Yajra\DataTables\Html\Column;
Even though that's the new way, your way of returning columns should still work as well.
Actually that's all
Many things are possible with sublime's find and replace so it shouldn't be that costly.
I hope that helps someone else who is struggling with the update.
Cheers
Dominik
I am working on a demo for instant chat and I was able to display the number of logged in users and show their names in the "Online Users" list, but the problem is that I created a laravel event to show messages in real time, and here I get the following error message in my console: Error: Syntax error, unrecognized expression: #user=1 .
demo app details :
laravel : 5.8.*
php : ^7.1.3
redis & laravel echo & laravel echo serveur
view :
<div class="container">
<div class="row">
<div class="col-md-4">
<h2>Online Users</h2>
<hr>
<h5 id="no-online-users">No Online Users</h5>
<ul class="liste-group" id="online-users">
</ul>
</div>
</div>
<div class="row">
<div class="col-md-9 d-flex flex-column" style="height: 80vh">
<div class="h-100 bg-white mb-4 p-5" id="chat" style="overflow-y: scroll;">
#foreach($messages as $message)
#if(\Auth::user()->id == $message->user_id)
<div class="mt-4 w-50 text-white p-3 rounded float-right bg-primary">
#else
<div class="mt-4 w-50 text-black p-3 rounded float-left bg-warning">
#endif
<p>{{ $message->body }}</p>
</div>
<div class="clearfix"></div>
#endforeach
</div>
<form action="" class="d-flex">
<input type="text" id="chat-text" name="" data-url="{{ route('messages.store') }}" style="margin-right: 10px" class="col-md-9 d-flex flex-column">
<button class="btn btn-primary col-md-3">Send</button>
</form>
</div>
</div>
</div>
MessageController :
namespace App\Http\Controllers;
use App\Message;
use Illuminate\Http\Request;
class MessageController extends Controller
{
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('auth');
}
//index
public function index()
{
$messages = Message::all();
return view('messages.index',compact('messages'));
}
// store
public function store(Request $request)
{
//$message = auth()->user()->messages()->create($request->all());
//return $request->body;
$message = new Message();
$message->user_id = \Auth::user()->id;
$message->body = $request->body;
$message->save();
broadcast(new MessageDelivered($message))->toOthers();
}
}
the event MessageDelivered:
namespace App\Events;
use App\Message;
use Illuminate\Broadcasting\Channel;
use Illuminate\Queue\SerializesModels;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class MessageDelivered implements ShouldBroadcast
{
use Dispatchable, InteractsWithSockets, SerializesModels;
public $message;
/**
* Create a new event instance.
*
* #return void
*/
public function __construct(Message $message)
{
$this->message = $message;
}
/**
* Get the channels the event should broadcast on.
*
* #return \Illuminate\Broadcasting\Channel|array
*/
public function broadcastOn()
{
return new Channel('chat-group');
}
}
app.js
require('./bootstrap');
import Echo from "laravel-echo"
window.io = require('socket.io-client');
window.Echo = new Echo({
broadcaster: 'socket.io',
host: window.location.hostname + ':6001'
});
// online users :
let onlineUsersLength = 0;
window.Echo.join('online')
.here((users) => {
onlineUsersLength = users.length;
console.log(onlineUsersLength);
let userId = $('meta[name=user-id]').attr('content');
//console.log(userId);
users.forEach(function(user){
if (user.id == userId) { return; }
$('#no-online-users').css('display','none');
$('#online-users').append('<li id="user='+user.id+'" class="liste-group-item">'+user.name+'</li>');
})
//console.log(users);
})
.joining((user) => {
$('#no-online-users').css('display','none');
$('#online-users').append('<li id="user='+user.id+'" class="liste-group-item">'+user.name+'</li>');
})
.leaving((user) => {
$('#user='+user.id).css('display','none');
$('#no-online-users').css('display','yes');
});
// submit chat text :
$('#chat-text').keypress(function(e){
//console.log(e.which);
if(e.which == 13){
e.preventDefault();
let body = $(this).val();
let url = $(this).data('url');
let data = {
'_token': $('meta[name=csrf-token]').attr('content'),
body
}
//console.log(body);
$.ajax({
url: url,
method: 'post',
data: data,
});
}
});
window.Echo.channel('chat-group')
.listen('MessageDelivered', (e) => {
console.log('message');
});
problem :
in first user console (user id 1 in database)
in second user console (user id 2 in database)
When I refresh the page for a specific user, the error appears for the second user
I guess you have a typo here $('#user='+user.id).css('display','none')
^^^
and here $('#online-users').append('li id="user='+user.id+'" class="liste-group-item">'+user.name+'</li>'); ^^^
You may fix it
//...
users.forEach(function(user){
if (user.id == userId) { return; }
$('#no-online-users').css('display','none');
$('#online-users').append('<li id="user-'+user.id+'" class="liste-group-item">'+user.name+'</li>');
})
//...
.joining((user) => {
$('#no-online-users').css('display','none');
$('#online-users').append('<li id="user='+user.id+'" class="liste-group-item">'+user.name+'</li>');
})
.leaving((user) => {
$('#user-'+user.id).css('display','none');
$('#no-online-users').css('display','yes');
});
//...
Problem:
The $errors variable is empty in the views. There's talk that this has been fixed in 5.2 so hopefully the problem is on my end.
Environment:
Mac OS X
Laravel 5.2.45
The Codez:
Routes.php
Route::get('/', 'AlleleController#index');
Route::get('/register', function () {
return view('auth.register');
});
Route::auth();
Route::get('/home', 'HomeController#index');
Route::get('/alleles', 'AlleleController#index');
Route::post('/allele', 'AlleleController#store');
Route::delete('/allele/{allele}', 'AlleleController#destroy');
AlleleController.php:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\Allele;
class AlleleController extends Controller {
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct() {
// All methods require authentication except index.
$this->middleware('auth', ['except' => ['index']]);
}
/**
* Root page.
*
* #return Response
*/
public function index() {
return view('welcome');
}
/**
* Create a new allele.
*
* #param Request $request
* #return Response
*/
public function store(Request $request) {
$allele = new Allele();
// Get all input as an array.
$input = $request->all();
// Validate input.
if ($allele->validate($input)) {
// Valid input. Write to database.
// The inserted model instance is returned.
$result = $allele::create($input);
if ($result) {
// Insert successful.
$message = array('message' => 'Data added!');
return view('home', $message);
} else {
// Insert failed. Send errors to view.
$errors = array('errors' => 'Error saving data.');
return view('home', $errors);
}
} else {
// Invalid input. Get errors.
$errors = $allele->errors();
// Send errors to view.
return view('home', $errors);
}
}
}
?>
HomeController.php:
<?php
namespace App\Http\Controllers;
use App\Http\Requests;
use Illuminate\Http\Request;
class HomeController extends Controller {
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct() {
$this->middleware('auth');
}
/**
* Show the application dashboard.
*
* #return \Illuminate\Http\Response
*/
public function index() {
return view('home');
}
}
Model: Allele.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Allele extends Validation {
/**
* The attributes that are mass assignable.
*/
protected $fillable = ['allele'];
/**
* Validation rules.
*/
protected $rules = array (
'allele' => 'required|max:20',
);
}
Model: Validation.php
<?php
namespace App;
use Validator;
use Illuminate\Database\Eloquent\Model;
class Validation extends Model {
protected $rules = array();
protected $errors;
public function validate($input) {
// Make a new validator object.
$v = Validator::make($input, $this->rules);
// Check for failure.
if ($v->fails()) {
// Set errors and return false.
$this->errors = $v->errors();
return false;
}
// Validation passed.
return true;
}
// Retrieves the errors object.
public function errors() {
return $this->errors;
}
}
View: views/common/errors.blade.php
#if (count($errors) > 0)
<!-- Form Error List -->
<div class="alert alert-danger">
<strong>Whoops! Something went wrong!</strong>
<br><br>
<ul>
#foreach ($errors->all() as $error)
<li>{{ $error }}</li>
#endforeach
</ul>
</div>
#endif
View: views/home.blade.php
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row">
<div class="col-md-10 col-md-offset-1">
<div class="panel panel-default">
<div class="panel-heading">Dashboard</div>
<div class="panel-body">
You are logged in!
</div>
</div>
</div>
</div>
</div>
<!-- Create New Allele -->
<div class="panel-body">
<!-- Display Validation Errors -->
#include('common.errors')
<!-- New Allele Form -->
<form action="{{ url('allele') }}" method="POST" class="form-horizontal">
{{ csrf_field() }}
<!-- Allele Name -->
<div class="form-group">
<label for="allele-name" class="col-sm-3 control-label">Allele</label>
<div class="col-sm-6">
<input type="text" name="allele" id="allele-name" class="form-control">
</div>
</div>
<!-- Add Allele Button -->
<div class="form-group">
<div class="col-sm-offset-3 col-sm-6">
<button type="submit" class="btn btn-default">
<i class="fa fa-plus"></i> Add Allele
</button>
</div>
</div>
</form>
</div>
#endsection
All validation methods should be placed inside web middleware . I do not see any other error. Replace your route.php like this.
Route::group(['middleware' => ['web']], function ()
{
Route::get('/', 'AlleleController#index');
Route::get('/register', function () {
return view('auth.register');
});
Route::auth();
Route::get('/home', 'HomeController#index');
Route::get('/alleles', 'AlleleController#index');
Route::post('/allele', 'AlleleController#store');
Route::delete('/allele/{allele}', 'AlleleController#destroy');
});