Tout d'abord, excellent travail pour ce package incroyable.
J'ai un petit problème:
J'ai ajouté une nouvelle colonne personnalisée dans votre fichier de démonstration : .../eloquent/add-edit-remove-column, je veux rechercher/filtrer cette colonne, mais j'obtiens une erreur dans le navigateur lorsque je saisis tout.
Existe-t-il une solution pour rechercher/filtrer dans une colonne personnalisée et ensuite ajouter un texte d'entrée de recherche pour chaque colonne du tableau, y compris pour custom_column ?
Erreur dans la console Firebug:
<span class="exception_message">SQLSTATE[42S22]: Column not found: 1054 Champ
'new_column' inconnu dans where clause (SQL: select count(*) as aggregate from (select '
;1' as row_count from `users` where (LOWER(`id`) LIKE %b% or LOWER(`name`) LIKE %b% or LOWER(`email
`) LIKE %b% or LOWER(`created_at`) LIKE %b% or LOWER(`updated_at`) LIKE %b% or LOWER(`new_column`) LIKE
%b%)) count_row_table)</span>
Code du contrôleur:
public function getAddEditRemoveColumnData()
{
$users = User::select(['id', 'name', 'email', 'password', 'created_at', 'updated_at']);
return Datatables::of($users)
->addColumn('new_column' , 'ABC')
->make(true)
}
Code à partir de Javascript :
$('#users-table').DataTable({
processing: true,
serverSide: true,
ajax: '{{ url("eloquent/add-edit-remove-column-data") }}',
columns: [
{data: 'id', name: 'id'},
{data: 'name', name: 'name'},
{data: 'email', name: 'email'},
{data: 'created_at', name: 'created_at'},
{data: 'updated_at', name: 'updated_at'},
{data: 'new_column', custom: 'new_column', orderable: true, searchable: true}
]
});
@marioene , vous ne pouvez pas rechercher sur addColumn
si les données ne proviennent pas de la base de données. Une solution de contournement consiste à ajouter la colonne sur votre instruction select comme ci-dessous. Pas besoin d'utiliser addColumn
.
$users = User::select([
'id', 'name', 'email', 'password', 'created_at', 'updated_at',
DB::raw("'ABC' as new_column")
]);
Remarque : Vous devrez peut-être écrire un
filterColumn
pour que cela fonctionne. Assurez-vous simplement que le SQL généré fonctionne et qu'il devrait également fonctionner avec le package.
La fermeture en raison de l'inactivité et la solution de contournement suggérée ci-dessus devraient résoudre le problème. Merci!
@yajra J'ai suivi votre suggestion d'ajouter d'abord une colonne calculée en utilisant 'select' (dans Controller)
$staffData = Staff::select('id', 'staff_id', \DB::raw('concat(first_name, " ", middle_name, " ", last_name) as full_name'), 'department_name', 'status');
Ensuite, j'ai ajouté un filtre personnalisé (dans Controller)
$dt = Datatables::of($staffData);
return $dt->filterColumn('full_name', function($query, $keyword) {
$query->whereRaw("CONCAT(first_name, ' ', middle_name, ' ', last_name) like ?", ["%{$keyword}%"]);
})->make(true);
Lorsque je charge la page pour la première fois, la table de données est rendue correctement lorsque je fais une recherche à l'aide de la zone de texte d'entrée de recherche globale, une erreur est renvoyée
Ajax error. http://datatables.net/tn/7
Pouvez-vous s'il vous plaît me dire où je pourrais faire une erreur.
@AshishGupta001 essayez d'inspecter la requête ajax à l'aide des outils de développement Chrome ou Firebug. Cela vous donnera un indice sur la cause du problème. Très probablement, un problème d'exception SQL.
@yajara Merci pour votre réponse rapide.
Lors de la mise en œuvre de la recherche globale d'une colonne 'calculée' (dans mon cas 'full_name'), j'ai fait référence à
1) Numéro 168 : https://github.com/yajra/laravel-datatables/issues/168
2) Exemple : https://datatables.yajrabox.com/eloquent/post-column-search
Avant d'ajouter le 'filterColumn()' personnalisé pour ma table de données, je recevais une exception SQL se plaignant de la colonne manquante 'full_name' dans la table. Ensuite, j'ai ajouté le code ci-dessous pour ajouter un filtre personnalisé pour la colonne "calculée" (dans mon cas "nom_complet") comme ci-dessous
$dt->filterColumn('full_name', function($query, $keyword) {
$query->whereRaw("CONCAT(staff.first_name, ' ', staff.middle_name, ' ', staff.last_name) like ?", ["%{$keyword}%"]);
});
return $dt->make(true);
Maintenant, j'obtiens l'erreur suivante dans le journal
mb_strtolower() expects parameter 1 to be string, object given
dans le fichier ......./vendor/laravel/framework/src/Illuminate/Support/Str.php#162
Merci si vous pouvez aider à déboguer ce problème.
@AshishGupta001 quelle version utilisez-vous ? Ton code m'a l'air bien.
@yajra Merci d'avoir confirmé. Les versions sont comme ci-dessous
PHP - 5.5.38-3
Laravel - 5.0.34
Datatables - yajra/laravel-datatables-oracle : ^6.3 (comme dans composer.json)
Il semble que dans 'getOrMethod' dans la classe Helper, une exception soit levée car elle essaie de convertir pour abaisser un "clouser" passé en tant que paramètre d'entrée.
public static function getOrMethod($method) {
if (! Str::contains(Str::lower($method), 'or')) {
return 'or' . ucfirst($method);
}
return $method;
}
'$method' est un clouser tel que passé function($query, $keyword)
, comme ci-dessous
Closure {#864
reflection: """
Closure [ <user> public method App\Http\Controllers\{closure} ] {\n
@@ /var/www/html/XYZ/app/Http/Controllers/StaffHistoryController.php 310 - 313\n
\n
- Parameters [2] {\n
Parameter #0 [ <required> $query ]\n
Parameter #1 [ <required> $keyword ]\n
}\n
}\n
"""
}
Bien que je ne puisse pas comprendre le problème auquel j'ai été confronté, j'ai pu trouver le moyen de contourner ce cas d'utilisation spécifique. Merci pour les conseils disponibles ici.
Vue : avoir les éléments suivants dans la vue dans la balise de script
{ data: 'full_name', name: 'full_name', searchable: false },
{ data: 'first_name', name: 'first_name', searchable: true, visible: false },
{ data: 'middle_name', name: 'middle_name', searchable: true, visible: false },
{ data: 'last_name', name: 'last_name', searchable: true, visible: false }
Contrôleur : récupérez first_name, etc. dans la requête SQL avec le reste des valeurs de la colonne.
@ AshishGupta001 content que vous ayez compris cela. C'est ce que je faisais aussi depuis la version Laravel 4.2. ??
@AshishGupta001 Bonne solution !
@yajra Pouvons-nous rechercher une colonne ajoutée à l'aide de l'addColumn dont les données proviennent de la base de données mais nous n'ajoutons pas cette colonne dans le JS ?
Ou devrions-nous l'ajouter au JS et le rendre invisible mais consultable ?
Certaines façons auxquelles je peux penser:
{data: 'added_column', name: 'actual_column_name'}
Merci pour ta réponse rapide @yajra
J'essayais déjà la deuxième solution mais j'ai remarqué que cette colonne ajoutée n'est pas prise en compte dans la requête.
Des pensées ?
Assurez-vous de ne pas avoir ajouté searchable: false
dans cette colonne.
C'est ainsi que j'ai ajouté la colonne ->addColumn('company_name', function($deal) {
return $deal->company_name;
})
Et la requête de recherche globale sous la forme $dataTable->filterColumn('company_name', 'where', "like", ["%$keyword%"]);
Pouvons-nous passer le searchable: false
dans le backend ?
searchable: false
est du côté client js.
D'ailleurs, quelle version utilisez-vous ?
Ah ok. Nous devons donc toujours utiliser la première façon que vous avez mentionnée, avec cette façon.
J'utilise v6.17.0
J'ai le même problème que @AshishGupta001, malheureusement, l'astuce côté client ne le coupe pas car la colonne n'est pas triable.
J'ai exploré l'alternative filterColumn mais je n'ai pas pu la faire fonctionner aussi.
en utilisant "yajra/laravel-datatables-oracle": "~9.0"
méthode du contrôleur :
public function getAccounts(Request $request)
{
if ($request->ajax()) {
$accounts = Account::with('current_marketer')->select([
'*',
DB::raw("CONCAT(accounts.lastname,' ',accounts.firstname) as fullname"),
]);
return Datatables::of(Account::query()->with('current_marketer'))
->addColumn('marketer', function(Account $account){
return $account->current_marketer->name;
})
->addColumn('fullname', function($account){
return '<a href="'.route('account.clients.show', $account->account_number).'" class="hover:underline" target="_blank">'. $account->fullname.'</a>';
})
->filterColumn('fullname', function($query, $keyword) {
$sql = "CONCAT(accounts.lastname,' ',accounts.firstname) like ?";
$$query->whereRaw($sql, ["%{$keyword}%"]);
})
->rawColumns(['fullname'])
->editColumn('created_on', function(Account $account) {
return Carbon::parse($account->created_on)->format('jS F, Y');
})
->toJson();
}
return view('datatables.accounts.index');
}
Lame js :
$('#accounts-table').DataTable({
"processing": true,
"serverSide": true,
"ajax": '{{ route('accounts.get') }}',
"columns": [
{ data: "id" },
{ data: "account_number" },
{ data: 'fullname'},
{ data: "marketer" },
{ data: "created_on" },
]
});
Exception : lors d'une tentative de recherche ou de tri :
il s'avère que le problème avec cette exception était de ma faute ; J'avais un double signe '$$' dans ma méthode filterColumn.
Cela n'a pas résolu mon problème de tri cependant. J'ai encore besoin de savoir :
@ seewhy17, vous pouvez utiliser orderColumn pour un tri complexe. Cependant, dans votre cas, la commande par fullname
fonctionnerait déjà comme prévu.
@ seewhy17, vous pouvez utiliser orderColumn pour un tri complexe. Cependant, dans votre cas, la commande par
fullname
fonctionnerait déjà comme prévu.
Eh bien, ce n'est pas le cas, je suppose que la méthode filterColumn est en conflit avec un évaluateur sur le modèle qui fait essentiellement la même chose... Je ne sais vraiment pas.
Pour savoir que je l'ai fait fonctionner en ajoutant un name: lastname
au js, donc il filtre par nom de famille et la méthode filterColumn est redondante
Commentaire le plus utile
@marioene , vous ne pouvez pas rechercher sur
addColumn
si les données ne proviennent pas de la base de données. Une solution de contournement consiste à ajouter la colonne sur votre instruction select comme ci-dessous. Pas besoin d'utiliseraddColumn
.