Laravel-datatables: comment rechercher dans une colonne générée par addColumn ?

Créé le 3 août 2015  ·  22Commentaires  ·  Source: yajra/laravel-datatables

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
 &#039;new_column&#039; inconnu dans where clause (SQL: select count(*) as aggregate from (select &#039
;1&#039; 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}
        ]
    });

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'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.

Tous les 22 commentaires

@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:

  1. Ajoutez-le à js et rendez-le invisible et consultable comme vous l'avez dit.
  2. Utilisez filterColumn pour gérer manuellement la recherche de la colonne ajoutée.
  3. Déclarez-le de cette façon :
{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 :

yajraIssue

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.
yajra_issue_fix_1

Cela n'a pas résolu mon problème de tri cependant. J'ai encore besoin de savoir :

  1. comment rendre la colonne triable
  2. comment rechercher et trier les colonnes associées un autre regard sur la documentation a effacé cela pour mon cas d'utilisation

@ 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

Cette page vous a été utile?
0 / 5 - 0 notes