
Créer un blog – le tableau des articles
Nous avons dans le précédent article installé notre interface d’administration avec comme choix AdminLTE. Pour se simplifier la vie on a prévu d’automatiser les titres et le menu latéral en ajoutant deux fichiers de configuration qu’on va lire pour générer les éléments correspondants. On a aussi prévu d’afficher sur le tableau de bord les nouveaux enregistrements : utilisateurs, articles, commentaires et contacts. De cette manière on a une vue globale de la vie du blog sur une même page.
Dans le présent article on va se pencher sur la gestion des articles. Pour le moment on sait juste afficher l’image et le résumé sur la page d’accueil du blog et l’article complet sur une page. Mais on doit pouvoir également créer et modifier les articles. De même il doit être possible de les supprimer et aussi les dupliquer.
Pour la gestion de toutes les entités du blog on va faire appel systématiquement à des tableaux. Comme je l’avais fait pour mon exemple de commerce en ligne je vais utiliser le package laravel-datatables qui me semble le plus performant en la matière.
Vous pouvez télécharger le code final de cet article ici.
Edit au 22/02/2021 : j’ai modifié la Datatable pour supprimer le bouton de duplication pour l’administrateur pour les articles dont il n’est pas l’auteur.
Laravel Datatables
Pour l’administration on va gérer tous les tableaux avec le package laravel-datatables, on va donc l’installer :
composer require yajra/laravel-datatables
Une fois le package installé on dispose d’une commande pour créer une datatable, on l’utilise pour les articles :
php artisan datatables:make Posts
Contrôleur et routes
On crée un contrôleur pour la gestion des articles :
php artisan make:controller Back\PostController --resource --model=Post
On aura besoin de toutes les méthodes sauf show puisque l’affichage d’un article se fait dans le frontend.
Dans le contrôleur on prévoit l’injection de la Datatable créée ci-dessus :
use App\DataTables\PostsDataTable; ... public function index(PostsDataTable $dataTable) { return $dataTable->render('back.shared.index'); }
On va créer la vue plus loin.
Pour les routes on peut aussi grouper :
use App\Http\Controllers\Back\{ AdminController, PostController as BackPostController }; ... Route::prefix('admin')->group(function () { Route::middleware('redac')->group(function () { ... Route::resource('posts', BackPostController::class)->except('show'); }); Route::middleware('admin')->group(function () { Route::name('posts.indexnew')->get('newposts', [BackPostController::class, 'index']); }); });
Je crée une route spéciale réservée à l’administrateur pour afficher seulement les nouveaux articles. On pointe sur la méthode index, il faudra prévoir de distinguer les deux situations : tous les articles ou juste les nouveaux, c’est le nom de la route utilisée qui nous renseignera.
Une vue partagée pour les tableaux
Le code pour l’affichage des tableaux avec Laravel Datatable va être quelque peu systématique. On ne crée donc qu’une vue qu’on adaptera si nécessaire pour les différences rencontrées :
Voici le code de base en prévoyant les textes en français :
@extends('back.layout') @section('css') <link rel="stylesheet" href="https://cdn.datatables.net/1.10.23/css/dataTables.bootstrap4.min.css"> <style> a > * { pointer-events: none; } </style> @endsection @section('main') {{ $dataTable->table(['class' => 'table table-bordered table-hover table-sm'], true) }} @endsection @section('js') <script src="https://cdn.datatables.net/1.10.23/js/jquery.dataTables.min.js"></script> <script src="https://cdn.datatables.net/1.10.23/js/dataTables.bootstrap4.min.js"></script> <script src="https://cdn.jsdelivr.net/npm/sweetalert2@10"></script> @if(config('app.locale') == 'fr') <script> (($, DataTable) => { $.extend(true, DataTable.defaults, { language: { "sEmptyTable": "Aucune donnée disponible dans le tableau", "sInfo": "Affichage des éléments _START_ à _END_ sur _TOTAL_ éléments", "sInfoEmpty": "Affichage de l'élément 0 à 0 sur 0 élément", "sInfoFiltered": "(filtré à partir de _MAX_ éléments au total)", "sInfoPostFix": "", "sInfoThousands": ",", "sLengthMenu": "Afficher _MENU_ éléments", "sLoadingRecords": "Chargement...", "sProcessing": "Traitement...", "sSearch": "Rechercher :", "sZeroRecords": "Aucun élément correspondant trouvé", "oPaginate": { "sFirst": "Premier", "sLast": "Dernier", "sNext": "Suivant", "sPrevious": "Précédent" }, "oAria": { "sSortAscending": ": activer pour trier la colonne par ordre croissant", "sSortDescending": ": activer pour trier la colonne par ordre décroissant" }, "select": { "rows": { "_": "%d lignes sélectionnées", "0": "Aucune ligne sélectionnée", "1": "1 ligne sélectionnée" } } } }); })(jQuery, jQuery.fn.dataTable); </script> @endif {{ $dataTable->scripts() }} @endsection
Comme on n’a pas encore créé de section CSS et pour le javascript dans back.layout on va le faire. On en profite pour mettre à jour le titre de la page :
<title>@lang('Administration')</title> ... <!-- Theme style --> <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/admin-lte/3.0.5/css/adminlte.min.css" /> @yield('css') ... <!-- AdminLTE App --> <script src="https://cdnjs.cloudflare.com/ajax/libs/admin-lte/3.0.5/js/adminlte.min.js"></script> @yield('js') </body>
Le tableau des articles
Revenons-en maintenant à notre Datatable.
Les données
Quelles sont les données qu’on va afficher dans le tableau ?
- le titre
- l’auteur
- les catégories
- le nombre de commentaires
- la date de publication ou de dernière modification
- le statut : publié ou pas
- des boutons d’action :
- voir l’article
- le modifier
- le cloner
- le supprimer
Dans le Datatable c’est la méthode query qui s’occupe de récupérer les données. Par défaut on a juste une amorce de requête :
public function query(Post $model) { return $model->newQuery(); }
On complète pour aller chercher toutes les données nécessaires :
use Illuminate\Support\Facades\Route; ... public function query(Post $post) { $query = isRole('redac') ? auth()->user()->posts() : $post->newQuery(); if(Route::currentRouteNamed('posts.indexnew')) { $query->has('unreadNotifications'); } return $query->select( 'posts.id', 'slug', 'title', 'active', 'posts.created_at', 'posts.updated_at', 'user_id') ->with( 'user:id,name', 'categories:title') ->withCount('comments'); }
On doit tenir compte du fait que :
- les rédacteurs ne doivent voir que leurs articles
- si on a la route posts.indexnew on doit avoir seulement les nouveaux articles
- on doit éviter de charger trop de données en utilisant un SELECT (en particulier on évite de charger le corps des articles)
- on doit charger les relations
- on doit compter les commentaires
Le colonnes
On va un peu épurer la méthode html :
public function html() { return $this->builder() ->setTableId('posts-table') ->columns($this->getColumns()) ->minifiedAjax() ->dom('Blfrtip') ->lengthMenu(); }
Les colonnes sont définies dans la méthode getColumns, on ajoute les colonnes en fonction des données qu’on a définies ci-dessus :
protected function getColumns() { $columns = [ Column::make('title')->title(__('Title')) ]; if(auth()->user()->role === 'admin') { array_push($columns, Column::make('user.name')->title(__('Author')) ); } array_push($columns, Column::computed('categories')->title(__('Categories')), Column::computed('comments_count')->title(__('Comments'))->addClass('text-center align-middle'), Column::make('created_at')->title(__('Date')), Column::computed('action')->title(__('Action'))->addClass('align-middle text-center') ); return $columns; }
On n’ajoute la colonne de l’auteur que si c’est l’administrateur, sinon ce n’est pas la peine.
On dispose de la méthode computed pour une colonne calculée. C’est le cas par exemple des catégories parce qu’on va mettre toutes les catégories auxquelles apartient l’article.
Un trait
Comme on aura à afficher des badges et boutons dans plusieurs tableaux on crée un trait :
<?php namespace App\DataTables; trait DataTableTrait { public function badge($text, $type, $margin = 0) { return '<span class="badge badge-' . $type . ' ml-' . $margin . '">' . __($text) . '</span>'; } public function button($route, $param, $type, $title, $icon, $name = '', $target = '_self') { return '<a title="'. $title . '" data-name="' . $name . '" href="' . route($route, $param) . '" class="px-3 btn btn-xs btn-' . $type . '" target="' . $target . '"> <i class="far fa-' . $icon . '"></i> </a>'; } }
Et on l’ajoute dans le Datatable :
class PostsDataTable extends DataTable { use DataTableTrait;
Un helper
On a besoin de mettre en forme l’heure, on l’avait déjà fait pour la date dans le fichier app/helpers, on ajoute la fonction pour l’heure :
if (!function_exists('formatHour')) { function formatHour($date) { return ucfirst(utf8_encode ($date->formatLocalized('%Hh%M'))); } }
On va d’ailleurs fixer la locale dans AppServiceProvider :
public function boot() { setlocale(LC_TIME, config('app.locale')); ...
La génération
La génération du Datatable se fait dans la méthode dataTable :
public function dataTable($query) { return datatables() ->eloquent($query) ->editColumn('categories', function ($post) { return $this->getCategories($post); }) ->editColumn('created_at', function ($post) { return $this->getDate($post); }) ->editColumn('comments_count', function ($post) { return $this->badge($post->comments_count, 'secondary'); }) ->editColumn('action', function ($post) { $buttons = $this->button( 'posts.display', $post->slug, 'success', __('Show'), 'eye', '', '_blank' ); if(Route::currentRouteName() === 'posts.indexnew') { return $buttons; } $buttons .= $this->button( 'posts.edit', $post->id, 'warning', __('Edit'), 'edit' ); if($post->user_id === auth()->id()) { $buttons .= $this->button( 'posts.create', $post->id, 'info', __('Clone'), 'clone' ); } return $buttons . $this->button( 'posts.destroy', $post->id, 'danger', __('Delete'), 'trash-alt', __('Really delete this post?') ); }) ->rawColumns(['categories', 'comments_count', 'action', 'created_at']); }
Le traitement des publications, dates et catégories se fait dans deux fonctions distinctes :
protected function getDate($post) { if(!$post->active) { return $this->badge('Not published', 'warning'); } $updated = $post->updated_at > $post->created_at; $html = $this->badge($updated ? 'Last update' : 'Published', 'success'); $html .= '<br>' . formatDate($updated ? $post->updated_at : $post->created_at) . __(' at ') . formatHour($updated ? $post->updated_at : $post->created_at); return $html; } protected function getCategories($post) { $html = ''; foreach($post->categories as $category) { $html .= $category->title . '<br>'; } return $html; }
Pour la date je regarde s’il y a eu une modification après la création et j’affiche cette date là.
Maintenant avec l’url monblog.ext/admin/posts (et newposts pour uniquement les nouveaux) on obtient le tableau :
Pour le moment au niveau des boutons on n’a que le premier qui fonctionne pour voir l’article.
Menu et titres
Pour les titres on complète le fichier app/config/titles.php :
<?php return [ 'admin' => 'Dashboard', 'posts' => [ 'index' => 'Posts', 'create' => 'Post Creation', 'edit' => 'Post Edit', 'indexnew' => 'New Posts', ], ];
Pour le menu latéral ça se passe dans app/config/menu.php :
<?php return [ 'Dashboard' => [ 'role' => 'redac', 'route' => 'admin', 'icon' => 'tachometer-alt', ], 'Posts' => [ 'icon' => 'file-alt', 'role' => 'redac', 'children' => [ [ 'name' => 'All posts', 'role' => 'redac', 'route' => 'posts.index', ], [ 'name' => 'New posts', 'role' => 'admin', 'route' => 'posts.indexnew', ], [ 'name' => 'Add', 'role' => 'redac', 'route' => 'posts.create', ], [ 'name' => 'fake', 'role' => 'redac', 'route' => 'posts.edit', ], ], ], ];
Si tout se passe bien vous devez avoir menu et titre pour les articles :
Pour les nouveaux articles :
Conclusion
On a obtenu l’affichage des articles sous forme de tableau dans l’administration avec les renseignements essentiels. Le code de base nous servira aussi pour les autres entités. Mais on a encore du travail avec les articles : création, modification, duplication, suppression. On continuera dans le prochain article.


56 commentaires
DIM
Bonjour Best , j’espère que tout va bien pour toi.
j’ai un souci au niveau de l’affichage des boutons d’actions , ils ne s’affichent tout simplement pas.
voici le code de mon datatable :
namespace App\DataTables;
use App\Models\Membre;
use App\Exports\MembresExport;
use Yajra\DataTables\Html\Button;
use Yajra\DataTables\Html\Column;
use App\DataTables\DataTableTrait;
use Illuminate\Support\Facades\Route;
use Yajra\DataTables\WithExportQueue;
use Yajra\DataTables\EloquentDataTable;
use Yajra\DataTables\Html\Editor\Editor;
use Yajra\DataTables\Html\Editor\Fields;
use Yajra\DataTables\Services\DataTable;
use Yajra\DataTables\Html\Builder as HtmlBuilder;
use Illuminate\Database\Eloquent\Builder as QueryBuilder;
class MembresDataTable extends DataTable
{
use DataTableTrait;
/**
* Build the DataTable class.
*
* @param QueryBuilder $query Results from query() method.
*/
public function dataTable(QueryBuilder $query): EloquentDataTable
{
return (new EloquentDataTable($query))
->editColumn('created_at', function($membre){
return $this->getDate($membre);
})
->editColumn('action', function ($membre) {
$buttons = $this->button(
'membres.edit',
$membre->id,
'warning',
__('Edit'),
'edit'
). $this->button(
'membres.destroy',
$membre->id,
'danger',
__('Delete'),
'trash-alt',
__('Really delete this post?')
);
})
->rawColumns(['action', 'created_at']);
}
/**
* Get the query source of dataTable.
*/
public function query(Membre $model): QueryBuilder
{
if(Route::currentRouteNamed('membres.indexnew')) {
return $model->has('unreadNotifications');
}
return $model->newQuery();
}
/**
* Optional method if you want to use the html builder.
*/
public function html(): HtmlBuilder
{
return $this->builder()
->setTableId('membres-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
{
$columns = [
Column::make('name')->title(__('Nom'))->addClass('align-middle text-center')
];
array_push($columns,
Column::make('status')->title(__('Status'))->addClass('align-middle text-center'),
Column::make('year')->title(__('Année'))->addClass('align-middle text-center'),
Column::make('reason')->title(__('Motif'))->addClass('align-middle text-center'),
Column::make('church')->title(__('Eglise'))->addClass('align-middle text-center'),
Column::make('area')->title(__('Quartier'))->addClass('align-middle text-center'),
Column::make('phone')->title(__('Téléphone'))->addClass('align-middle text-center'),
Column::make('email')->title(__('Email'))->addClass('align-middle text-center'),
Column::make('created_at')->title(__('Date')),
Column::computed('action')->title(__('Action'))->addClass('align-middle text-center')
);
return $columns;
}
/**
* Get the filename for export.
*/
protected function filename(): string
{
return 'Membres_' . date('YmdHis');
}
protected function getDate($membre)
{
$html = formatDate( $membre->created_at) . __(' at ') . formatHour($membre->created_at);
return $html;
}
}
bestmomo
Salut,
Le code semble bon. Tu devrais essayer deux choses :
composer dumpautoload
et
php artisan view:clear
DIM
Bonjour Bestmomo , stp c’est possible que tu puisses expliquer le code de la génération ?
bestmomo
Salut, c’est une question assez vaste…
Il faut consulter la documentation du DataTable qui est plutôt bien faite.
Pour les colonnes, j’utilise Edit Column avec closure.
Pour ajouter les boutons, je crée le code HTML dans le trait. Et comme il y a une protection XSS j’utilise rawColumns pour envoyer ce HTML.
DIM
salut , j’ai une table membres et je veux afficher les membres dans une datatable voici le code qui ne fonctionne pas :
eloquent($query)
->editColumn('action', function ($membre) {
$buttons .= $this->button(
'membres.edit',
$membre->id,
'warning',
__('Edit'),
'edit'
). $this->button(
'posts.destroy',
$post->id,
'danger',
__('Delete'),
'trash-alt',
__('Really delete this post?')
);
})
->rawColumns(['action']);
}
/**
* Get the query source of dataTable.
*/
public function query(Membre $model): QueryBuilder
{
if(Route::currentRouteNamed('membres.indexnew')) {
return $model->has('unreadNotifications');
}
return $model->newQuery();
}
/**
* Optional method if you want to use the html builder.
*/
public function html(): HtmlBuilder
{
return $this->builder()
->setTableId('membres-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
{
$columns = [
Column::make('name')->title(__('Nom'))->addClass('align-middle text-center')
];
array_push($columns,
Column::make('firstname')->title(__('Prenom'))->addClass('align-middle text-center'),
Column::make('status')->title(__('Status'))->addClass('align-middle text-center'),
Column::make('year')->title(__('Année de bapteme'))->addClass('align-middle text-center'),
Column::make('reason')->title(__('Motif de séjour'))->addClass('align-middle text-center'),
Column::make('church')->title(__('Eglise'))->addClass('align-middle text-center'),
Column::make('area')->title(__('Quartier'))->addClass('align-middle text-center'),
Column::make('phone')->title(__('Téléphone'))->addClass('align-middle text-center'),
Column::make('email')->title(__('Adresse Email'))->addClass('align-middle text-center'),
Column::make('created_at')->title(__('Date'))->addClass('align-middle text-center'),
Column::computed('action')->title(__('Action'))->addClass('align-middle text-center')
);
return $columns;
/* return [
Column::computed('action')
->exportable(false)
->printable(false)
->width(60)
->addClass('text-center'),
Column::make('id'),
Column::make('add your columns'),
Column::make('created_at'),
Column::make('updated_at'),
]; */
}
/**
* Get the filename for export.
*/
protected function filename(): string
{
return 'Membres_' . date('YmdHis');
}
}
bestmomo
C’est difficile de répondre sans pouvoir faire de débogage mais il me semble qu’il y a un souci dans la fonction query, je verrais plutôt ça :
public function query(Membre $model): QueryBuilder
{
$model->newQuery();
if(Route::currentRouteNamed('membres.indexnew')) {
return $model->has('unreadNotifications');
}
return $model;
}
DIM
Salut Bestmomo, j’ai une erreur au niveau de la fonction isAdmin() , laravel me renvoie que la fonction n’est pas définie au niveau de mon back/layout.blade.php.
Où peut se situer le problème ?
Merci
bestmomo
Salut,
Pour que ça fonctionne, il faut deux choses, premièrement le middleware Admin doit exister dans App\Http\Middleware.
D’autre part, il doit être déclaré and le kernel :
protected $routeMiddleware = [
...
'admin' => \App\Http\Middleware\Admin::class,
];
DIM
Dans laravel 10 ça se présente plutot de cette manière
protected $middlewareAliases = [
……
c’est là que dois les déclarer ?
];
DIM
j’ai pu résoudre le problème en enlevant les parenthèses donc au lieu de isAdmin() j’ai plutot mis isAdmin et ça marche
bestmomo
J’ai mieux regardé, en fait, j’ai prévu cette fonction dans me modèle User :
public function isAdmin()
{
return $this->role === 'admin';
}
jnn
Re Bonjour Best Momo.
Je suis un peu à l’ouest actuellement.
D’abord, mon problème de relation est résolu grâce au « Laravel Eager loading », mais il n’empêche que quand je me connecte comme rédac, ma datatable ne charge pas et j’ai « DataTables warning: table id=posts-table – Ajax error. For more information about this error, please see http://datatables.net/tn/7 » en log et une erreur 500 en console.
Ensuite, quel que soit mon statut, le clic sur le bouton de création d’article me renvoie une page blanche, vide, déserte, et rien en console, tandis que la duplication marche bien.
Merci d’avance pour ta sollicitude et ta bonne volonté.
jnn
Ah je tiens à préciser que j’ai récupéré le code final pa peur d’avoir loupé un truc mais rien n’y fait.
bestmomo
Salut,
Si avec le code final téléchargé ça ne marche pas, c’est que c’est un problème de configuration du serveur local. Tu utilises quoi et avec quelle version de PHP ?
jnn
Bonjour BestMomo.
Merci pour la réponse. J’utilise la version 7.3.10 de PHP;
bestmomo
Salut,
Difficile de savoir comme ça, il faudrait déboguer pour voir où ça coince. Sinon c’est quoi comme serveur local ?
DIM
merci c’est reglé
jnn
Bonjour BestMomo.
La ligne $query = isRole(‘redac’) ? auth()->user()->posts() : $post->newQuery(); me renvoie que la méthode posts() est indéfinie. Elle l’est pourtant bien dans mon model User.
J ai donc essayé avec d’autres méthodes du model mais le résultat est le même. Elles sont toutes indéfinies.
Des pistes de solutions s’il te plaît ?
bestmomo
Salut,
C’est un peu bizarre ça. Il faudrait explorer le modèle en faisant un dd(auth()->user()).
jnn
En effet. Le dd me renvoie bien le model mais pas les relations à l’intérieur. Je ne sais pas si c’est ce qu’il fallait vérifier mais bon….
J’aimerais vraiment comprendre ce qui ne va pas
PS: Je n’ai vu ta réponse qu’aujourd’hui donc pardon pour le retard
jnn
Bonjour BestMomo.
Problème résolu en précisant la classe visée User::posts().
Merci bien
korrthar
Bonjour BESTMOMO,
Dans la function query de PostsDataTable,
$query = isRole(‘redac’) ? auth()->user()->posts() : $post->newQuery();
la méthode posts() est indéfinie. D’où peut venir le problème?
bestmomo
Bonjour,
Il faut vérifier que la relation posts a bien été définie dans le modèle User.
bensa
Bonjour,
svp quelle est la partie du code résponsable sur rechercher dans le tableau des articles car cette fonction ne marche pas chez moi.
Merci
bestmomo
Salut,
Le code est dans le package de DataTable donc ça devrait fonctionner…
DIM
Bonjour bestmomo , à quel endroit tu as déclaré la fonction isRole() ?
bestmomo
Salut,
C’est dans Services/helpers.php.
DIM
tu peux me la mettre ici stp ?
bensa
Bonjour,
svp c’est quoi le rôle de « data-name » dans DataTableTrait
Merci
bestmomo
Salut,
C’est un attribut de données qui permet de mémoriser des informations de façon standardisée sans inventer de nouveaux attributs. Cette information est ensuite récupérée par le Javascript.
DIM
c’est bon je l’ai retrouvé mais quand je me connecte en tant que redac j’ai l’erreur datatbles net.7 mais en tant qu’admin tout marche toutes les données sont disponibles .
Best autre comportement bizzare , lors de la création d’un article le champ body où est utilisé ckeditor les données sont enregistrés dans la base de données entourées de la balise p et les accents ne sont pas reconnus
bestmomo
Salut,
je viens de faire un essai en tant que rédacteur et je n’ai aucun souci…
Thibaut
Bjr BESTMOMO,
je ne veux pas utiliser jquery dans mon blog, quelle alternative j’ai , ou comment proceder pour utiliser datatable sans jquery
merci!
bestmomo
Salut,
On ne peut pas utiliser DataTable sans JQuery parce que c’est un plugin de JQuery. Il y a eu une discussion sur le fait de se passer de JQuery sur leur forum, mais pour le moment rien n’a été planifié en ce sens.
Thibaut
ok merci ,j’ai alors utiliser le repository car je ne veux vraiment pas utiliser jquery, avec le fetch et peut etre meme livewire pour le cote filtre
bestmomo
Je comprends qu’on ne veuille plus utiliser JQuery mais le fait est qu’il sert encore de base à de très nombreux plugins qui n’ont pas d’équivalent. Je pense que tout ça va se décanter progressivement. Je ne l’utilise plus depuis pas mal de temps mais ça ne me gêne pas de l’intégrer pour bénéficier d’un bon outil qui en dépend.
AmmaLove
Salut ! le tableau s’affiche mais il y’a aucun élément a l’intérieur.
120_
Bonjour,
Lorsque j’appelle ma page monsite.fr/admin/posts ou /newposts, un dialogue d’alerte s’affiche :
« DataTables warning: table id=posts-table – Ajax error. For more information about this error, please see http://datatables.net/tn/7 »
J’ai suivi les instructions du liens donné mais rien ne change.
Je n’ai rien dans les logs.
Et dans ma console j’ai une ligne en erreur 500 :
http://localhost:8000/admin/posts?draw=1&columns%5B0%5D%5Bdata%5D=title&columns%5B1%5D%5Bdata%5D=user.name&columns%5B2%5D%5Bdata%5D=categories&columns%5B2%5D%5Bsearchable%5D=false&columns%5B2%5D%5Borderable%5D=false&columns%5B3%5D%5Bdata%5D=comments_count&columns%5B3%5D%5Bsearchable%5D=false&columns%5B3%5D%5Borderable%5D=false&columns%5B4%5D%5Bdata%5D=created_at&columns%5B5%5D%5Bdata%5D=action&columns%5B5%5D%5Bsearchable%5D=false&columns%5B5%5D%5Borderable%5D=false&order%5B0%5D%5Bcolumn%5D=0&order%5B0%5D%5Bdir%5D=asc&start=0&length=10&search%5Bvalue%5D=&_=1616582007528
Je suis un peu perdu avec Ajax..
bestmomo
Salut,
Il faudrait voir la réponse du serveur qui apparemment n’est pas une 200, tu trouves ça dans l’onglet réseaux des outils développeurs du navigateur. Il faut aussi vérifier s’il n’y a pas un module complémentaire du navigateur qui bloque Ajax. Personnellement j’ai eu ce problème avec Privacy Badger et j’ai cherché un moment d’où venait le problème !
fabBlab
J’avais une erreur similaire qui venait en fait d’une erreur de ma part en recopiant le code de PostsDataTable.
L’erreur php étant « cachée » par JS, ce n’était très facile à debugger.
J’ai donc téléchargé la version correcte fournie en début d’article pour comparer à mon code.
Dans mon cas l’erreur venait d’un oubli au début du script PostsDataTable :
use Illuminate\Support\Facades\Route;
Cet ajout est bien indiqué, mais j’avais loupé.
Bref, avec une erreur 500, il y a de fortes chances que cela soit une erreur côté PHP.
120_
Bonsoir BESTMOMO,
J’ai suivi jusque ici le cours sans aucun problème. (Merci et félicitation au passage, c’est vraiment top !)
Je recontre une erreur pour installer le package laravel-datatables. Voici un screen de ma console : https://www.zupimages.net/up/21/12/vye5.png
J’ai beau chercher, je ne trouve pas la solution.
Saurais-tu m’aider ?
Merci !
bestmomo
Salut,
En lisant tes erreurs on voit :
– L’extension GD de PHP n’est pas activée
– Tu utilises PHP 8 qui n’est pas digéré par maatwebsite
120_
Effectivement la ligne « extension=gd » était en commentaire dans mon php.ini.
J’ai relancé la commande d’installation du package et tout fonctionne.
J’ai vérifié, maatwebsite accepte bien php 8.
Merci pour l’éclaircissement, continues ainsi !
Bonne soirée
webwatson
Merci pour le tuto qui est super!
J’ai un problème je suppose mais je ne sais plus où ?
J’ai suivi toutes les étapes et pas d’erreur mais dans le tableau est vide à tout les niveaux.
Aider moi !
bestmomo
Salut,
Il faudrait quand même plus de détails sur le problème. Page blanche ? Tableau vide ? Ca donne quoi au niveau des requêtes échangées avec le serveur (onglet réseau des outils de développement du navigateur) ? Y-a-t-il des erreurs recensées dans les logs ?
webwatson
J’ai pas d’erreur dans la console.
Page vide au chargement et au niveau des post, tableau vide également.
bestmomo
Ca doit être l’Ajax qui passe pas. Dans le déroulement on charge d’abord le tableau vide avec une requête monblog.ext/admin/posts, puis les librairies, puis en dernier une requête Ajax du genre monblog.ext/admin/posts?draw=1&columns[0][data]=title&columns[1][data]=user.name&columns[2][data]=categories&columns[2][searchable]=false&columns[2][orderable]=false&columns[3][data]=comments_count&columns[3][searchable]=false&columns[3][orderable]=false&columns[4][data]=created_at&columns[5][data]=action&columns[5][searchable]=false&columns[5][orderable]=false&order[0][column]=0&order[0][dir]=asc&start=0&length=10&search[value]=&_=1616447757569 qui sert à récupérer du JSON pour remplir le tableau.
oksam
merci Best pour la réativité! j’ai trouvé ce qui causait ce problème!
oksam
j’ai juste la méthode get ==> http://127.0.0.1:8000/admin/posts
oksam
J’ai essayé sur firefox et Edge mais ne s’affiche!
bestmomo
Normalement tu a la succession de deux requêtes (sans parler des celles pour charger toutes les librairies) :
Est-ce que tu as bien cette succession ?
oksam
Bonsoir Best j’ai un soucis : l’affichage des articles sous forme de tableau dans l’administration avec les renseignements essentiels ne sont pas visible. lorsque j’inspecte la console est vide et le network affiche : methode : GET et status code : 2000 ok avec le bon chemin de url.
tu aurais une idée du problème!
bestmomo
Salut,
Datatable est un peu chatouilleux avec certains modules des navigateurs, je me rappelle avoir chercher ainsi un souci jusqu’à je me rende compte qu’un module destiné à bloquer des scripts en était la cause.
DIM
Bonjour Best momo et comment on peut résoudre ce problème ?
bestmomo
Salut,
La solution est de regarder avec le débogueur du navigateur ou tout simplement de désactiver des modules.
DIM
Salut,
voici le message que je reçois : GEThttp://redemption.test/admin/posts?draw=1&columns[0][data]=title&columns[1][data]=user.name&columns[2][data]=categories&columns[2][searchable]=false&columns[2][orderable]=false&columns[3][data]=comments_count&columns[3][searchable]=false&columns[3][orderable]=false&columns[4][data]=created_at&columns[5][data]=action&columns[5][searchable]=false&columns[5][orderable]=false&order[0][column]=0&order[0][dir]=asc&start=0&length=10&search[value]=&_=1676641041395
[HTTP/1.1 500 Internal Server Error 1108ms]