Reputation: 1423
I'm using laravel 5.4 and the latest version of yajra/laravel-datatables as a service.
I have it working fine with one datatable on a page. I want to create a dashboard of unrelated tables. Users, products, bookings etc.
I was hoping to have my controller look something like this:
public function index(ProductsDataTable $productDatatable, UsersDataTable $userDatatable)
{
$user = Auth::user();
$products = $user->products;
return view('admin.dashboard', compact('products', 'user', 'productDatatable', 'userDatatable'));
}
and in my blade do
@section('content')
{!! $productDatatable->table() !!}
{!! $userDatatable->table() !!}
@endsection
@push('scripts')
{!! $dataTable->scripts() !!}
@endpush
However this obviously doesn't work. I'm unsure how to proceed.
I tried to create a route for each datatable but wasn't sure how to reference it from my dashboard controller.
Upvotes: 6
Views: 13324
Reputation: 333
I'm sure there's a better way of implementing multiple tables in one view, but this is what I came up with after reviewing this. Comments/improvements would be highly appreciated.
Controller
The controller will render the tables once in the index()
method but will fetch data from both the getUsers()
method or getProducts()
method.
// DashboardController.php
public function index(UsersDataTable $usersDataTable, ProductsDataTable $productsDataTable)
{
return view('dashboard.index', [
'usersDataTable' => $usersDataTable->html(),
'productsDataTable' => $productsDataTable->html()
]);
}
//Gets Users JSON
public function getUsers(UsersDataTable $usersDataTable)
{
return $usersDataTable->render('admin.dashboard');
}
//Gets Products JSON
public function getProducts(ProductsDataTable $productsDataTable)
{
return $productsDataTable->render('admin.dashboard');
}
Routes
Add two extra routes that will be used to fetch Users and Projects data.
// web.php
Route::get('/', 'DashboardController@index')->name('dashboard.index');
Route::get('projects', 'DashboardController@getProjects')->name('dashboard.projects');
Route::get('users', 'DashboardController@getUsers')->name('dashboard.users');
DataTables Service Class
For both the UsersDataTable
and ProductsDataTable
service classes, include the relevant routes we created above.
// UsersDataTable.php
public function html()
{
return $this->builder()
->minifiedAjax( route('dashboard.users') );
}
View
// dashboard.blade.php
@section('content')
{!! $productsDataTable->table() !!}
{!! $usersDataTable->table() !!}
@endsection
@push('scripts')
{!! $productsDataTable->scripts() !!}
{!! $usersDataTable->scripts() !!}
@endpush
Upvotes: 6
Reputation: 369
Step 1: Define a route '/home-page' in web.php/route.php' (depending on the laravel version you are using) that returns the view called 'dt.blade.php'. (we will create this view in step 4)
i.e. Route::get('/home-page', function(){
return view('dt');
});
Step 2: Suppose you want to display two dataTables in 'dt.blade.php' view. (first datatable shows all the students in a school while other shows all the classes in a school)
To do that, you need to create two Builder instances ('Builder' class belongs to DataTables package) in the '/home-page' route's callback function and pass them to the 'dt.blade.php' view . i.e
Route::get('/home-page', function() {
$student_dt = app(Builder::class)->columns(['id', 'student_name'])->ajax('/show-students-datatable')->setTableId('t1');
$classes_dt = app(Builder::class)->columns(['id', 'class_name'])->ajax('show-classes-datatable')->setTableId('t2');
return view('dt', compact('student_dt', 'classes_dt'));
});
Step 3 Now define two more routes in web.php/route.php file:
Route::get('/show-students-datatable', function () {
return datatables(App\Student::query()->select(['id', 'student_name']))->toJson();
});
Route::get('/show-classes-datatable', function () {
return datatables(App\Class::query()->select(['id', 'class_name'])))->toJson();
});
Step 4 Define the 'db.blade.php' view, this view show both the dataTables that were passed to it in step 1.
@extends('layouts.master')
@section('content')
{{ $student_dt->table() }}
{{ $classes_dt->table() }}
@endsection
@push('scripts')
{{$student_dt->scripts()}}
{{$classes_dt->scripts()}}
@endpush
Upvotes: 1
Reputation: 1423
Submitted a question to the creator of the package. This is his response:
Unfortunately, DataTable service class is designed to handle single instance. However, I think we can make a workaround for it by adding additional query param in our request for us to identify which class is being requested to handle the request.
Maybe something like below:
public function index(ProductsDataTable $productDatatable, UsersDataTable $userDatatable)
{
if (request()->has('product') {
return $productDatatable->render('view');
}
if (request()->has('user') {
return $productDatatable->render('view');
}
$user = Auth::user();
$products = $user->products;
return view('admin.dashboard', compact('products', 'user', 'productDatatable', 'userDatatable'));
}
Upvotes: 3