I have built a simple web application. I have preferred to use Yajra Datatables. Everything is OK on my local computer. Then I uploaded all the files to a shared hosting.
After a few minutes of struggling with vite, finally, I have had the application work. Anyway, after testing pages, I have noticed that the pages with DataTable are not loading. An AJAX loader (blue points in the middle of the table) animates all the time and Datatable never loads data rows.
I have inspected the page using developer tools of the browser. There is no error at console panel and no warnings. I can see in the Response tab that the data is read from the DB server properly. But it is not rendering as table rows.
I think there is something wrong with Vite or any other javascript files. I cannot figure out that what could be the problem? In my opinion it is a .js file problem but I am not sure.
I think it is needless to share the controller and view files, anyway let me share them:
userlist.blade.php
@extends('layouts.app');
@section('content')
<h2 class="mt-2">Users</h2>
{{ $dataTable->table() }}
@endsection
@push('scripts')
{{ $dataTable->scripts(attributes: ['type' => 'module']) }}
@endpush
UsersDataTable.php
<?php
namespace App\DataTables;
use App\Models\User;
use Illuminate\Database\Eloquent\Builder as QueryBuilder;
use Yajra\DataTables\EloquentDataTable;
use Yajra\DataTables\Html\Builder as HtmlBuilder;
use Yajra\DataTables\Html\Button;
use Yajra\DataTables\Html\Column;
use Yajra\DataTables\Services\DataTable;
class UsersDataTable extends DataTable
{
/**
* Build the DataTable class.
*
* @param QueryBuilder $query Results from query() method.
*/
public function dataTable(QueryBuilder $query): EloquentDataTable
{
return (new EloquentDataTable($query))
->addColumn('Edit User', function ($row) {
return '<a href="/users/edit/' . $row->id . '" class="update btn btn-info btn-sm"><i class="text-white fas fa-pencil"></i></a>';
})->setRowId('id')
->rawColumns(['Edit User']);
}
/**
* Get the query source of dataTable.
*/
public function query(User $model): QueryBuilder
{
return $model->newQuery();
}
/**
* Optional method if you want to use the html builder.
*/
public function html(): HtmlBuilder
{
return $this->builder()
->setTableId('users-table')
->columns($this->getColumns())
->minifiedAjax()
//->dom('Bfrtip')
->orderBy(1)
->selectStyleSingle()
->buttons([
Button::make('excel'),
Button::make('csv'),
// Button::make('pdf'),
Button::make('print'),
Button::make('reset'),
Button::make('reload')
]);
}
/**
* Get the dataTable columns definition.
*/
public function getColumns(): array
{
return [
Column::make('id'),
Column::make('name'),
Column::make('email'),
Column::make('phone'),
Column::make('status'),
Column::make('role'),
Column::computed('Edit User')
->exportable(false)
->printable(false)
->addClass('text-center'),
];
}
/**
* Get the filename for export.
*/
protected function filename(): string
{
return 'Users_' . date('YmdHis');
}
public function index(UsersDataTable $dataTable)
{
return $dataTable->render('userlist');
}
}
resources/js/bootstrap.js
import 'bootstrap';
resources/js/app.js
import './bootstrap';
import 'laravel-datatables-vite';
resources/sass/app.scss
// Fonts
@import url('https://fonts.bunny.net/css?family=Nunito');
// Variables
@import 'variables';
// Bootstrap
@import 'bootstrap/scss/bootstrap';
// DataTables
@import 'bootstrap-icons/font/bootstrap-icons.css';
@import "datatables.net-bs5/css/dataTables.bootstrap5.min.css";
@import "datatables.net-buttons-bs5/css/buttons.bootstrap5.min.css";
@import 'datatables.net-select-bs5/css/select.bootstrap5.css';
resources/views/layouts/app.blade.php
...
<!-- Scripts -->
@vite(['resources/sass/app.scss', 'resources/js/app.js'])
...
There is a javascript code snippet at the bottom of the page in the browser on my local computer:
<script type="module">
$(function(){window.LaravelDataTables=window.LaravelDataTables||{};window.LaravelDataTables["users-table"]=$("#users-table").DataTable({"serverSide":true,"processing":true,"ajax":{"url":"http:\/\/localhost:8000\/admin\/users","type":"GET","data":function(data) {
for (var i = 0, len = data.columns.length; i < len; i++) {
if (!data.columns[i].search.value) delete data.columns[i].search;
if (data.columns[i].searchable === true) delete data.columns[i].searchable;
if (data.columns[i].orderable === true) delete data.columns[i].orderable;
if (data.columns[i].data === data.columns[i].name) delete data.columns[i].name;
}
delete data.search.regex;}},"columns":[{"data":"id","name":"id","title":"Id","orderable":true,"searchable":true},{"data":"name","name":"name","title":"Name and Surname","orderable":true,"searchable":true},{"data":"email","name":"email","title":"E-mail Address","orderable":true,"searchable":true},{"data":"phone","name":"phone","title":"Telephone Number","orderable":true,"searchable":true},{"data":"status","name":"status","title":"Activated","orderable":true,"searchable":true},{"data":"role","name":"role","title":"Role","orderable":true,"searchable":true},{"data":"account_creation_date","name":"account_creation_date","title":"Account Creation Date","orderable":true,"searchable":true},{"data":"Edit","name":"Edit","title":"Edit","orderable":false,"searchable":false,"className":"text-center"}],"order":[[1,"desc"]],"select":{"style":"single"},"buttons":[{"extend":"excel"},{"extend":"csv"},{"extend":"print"},{"extend":"reset"},{"extend":"reload"}]});});
</script>
Here the url value is "url":"http:\/\/localhost:8000\/admin\/users"
...
"url":"http:\/\/localhost:8000\/admin\/users"
...
However it is different in the script at the server:
<script type="module">$(function(){window.LaravelDataTables=window.LaravelDataTables||{};window.LaravelDataTables["users-table"]=$("#users-table").DataTable({"serverSide":true,"processing":true,"ajax":{"url":"http:\/\/mydomain.com\/admin\/users\?admin%2Fusers=","type":"GET","data":function(data) {
//remaining part is same
...
</script>
There is some additional suffix at the and of the url value:
http://mydomain.com/admin/users?admin%2Fusers=
One of Yajra requirements is Jquery DataTables.
Make sure you have installed it and the files are accessible. For instance, here's what I have configured in my blade file: