Laravel-datatables: Wie suche ich in einer von addColumn generierten Spalte?

Erstellt am 3. Aug. 2015  ·  22Kommentare  ·  Quelle: yajra/laravel-datatables

Erstens, großartige Arbeit für dieses erstaunliche Paket.

ich habe ein kleines Problem:

Ich habe Ihrer Demodatei eine neue benutzerdefinierte Spalte hinzugefügt: .../eloquent/add-edit-remove-column, ich möchte nach dieser Spalte suchen/filtern, aber ich erhalte einen Fehler im Browser, wenn ich alles eingebe.

Gibt es eine Lösung, um in einer benutzerdefinierten Spalte zu suchen / zu filtern und danach für jede Spalte in der Tabelle einen Sucheingabetext hinzuzufügen, einschließlich für custom_column?

Fehler in der FireBug-Konsole:

  <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 vom Controller:

    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 aus 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}
        ]
    });

Hilfreichster Kommentar

@marioene , Sie können nicht nach addColumn suchen, wenn die Daten nicht aus der Datenbank stammen. Eine Problemumgehung hierfür besteht darin, die Spalte wie unten zu Ihrer select-Anweisung hinzuzufügen. Keine Notwendigkeit, addColumn .

$users = User::select([
'id', 'name', 'email', 'password', 'created_at', 'updated_at',
DB::raw("'ABC' as new_column")
]);

Hinweis: Möglicherweise müssen Sie ein benutzerdefiniertes filterColumn schreiben, damit es funktioniert. Stellen Sie nur sicher, dass die generierte SQL funktioniert und auch mit dem Paket funktionieren sollte.

Alle 22 Kommentare

@marioene , Sie können nicht nach addColumn suchen, wenn die Daten nicht aus der Datenbank stammen. Eine Problemumgehung hierfür besteht darin, die Spalte wie unten zu Ihrer select-Anweisung hinzuzufügen. Keine Notwendigkeit, addColumn .

$users = User::select([
'id', 'name', 'email', 'password', 'created_at', 'updated_at',
DB::raw("'ABC' as new_column")
]);

Hinweis: Möglicherweise müssen Sie ein benutzerdefiniertes filterColumn schreiben, damit es funktioniert. Stellen Sie nur sicher, dass die generierte SQL funktioniert und auch mit dem Paket funktionieren sollte.

Das Schließen aufgrund von Inaktivität und die oben vorgeschlagene Problemumgehung sollten das Problem beheben. Vielen Dank!

@yajra Ich bin Ihrem Vorschlag gefolgt, zuerst eine berechnete Spalte mit 'select' (im Controller) hinzuzufügen.

$staffData = Staff::select('id', 'staff_id', \DB::raw('concat(first_name, " ", middle_name, " ", last_name) as full_name'), 'department_name', 'status');

Dann habe ich einen benutzerdefinierten Filter hinzugefügt (in 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);

Wenn ich die Seite zum ersten Mal lade, wird die Datentabelle richtig gerendert, wenn ich mit dem globalen Sucheingabetextfeld suche, wird ein Fehler ausgegeben

Ajax error. http://datatables.net/tn/7

Können Sie mir bitte sagen, wo ich einen Fehler machen könnte.

@ AshishGupta001 Versuchen Sie, die Ajax-Anfrage mit Chrome- Firebug zu überprüfen . Es gibt Ihnen einen Hinweis auf die Ursache des Problems. Höchstwahrscheinlich ein SQL-Ausnahmeproblem.

@yajara Danke für deine schnelle Antwort.
Bei der Implementierung der globalen Suche nach einer 'berechneten' Spalte (in meinem Fall 'full_name') habe ich Bezug genommen auf
1) Ausgabe 168: https://github.com/yajra/laravel-datatables/issues/168
2) Beispiel: https://datatables.yajrabox.com/eloquent/post-column-search

Bevor ich die benutzerdefinierte 'filterColumn()' für meine Datentabelle hinzugefügt habe, habe ich eine SQL-Ausnahme erhalten, die sich über die fehlende Spalte 'full_name' in der Tabelle beschwert. Dann habe ich den folgenden Code hinzugefügt, um einen benutzerdefinierten Filter für die Spalte "berechnet" (in meinem Fall "full_name") wie unten beschrieben hinzuzufügen

$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);

Jetzt bekomme ich folgende Fehlermeldung im Log

mb_strtolower() expects parameter 1 to be string, object given in Datei ......./vendor/laravel/framework/src/Illuminate/Support/Str.php#162

Schätzen Sie, wenn Sie helfen können, dieses Problem zu beheben.

@ AshishGupta001 welche Version verwendest du? Dein Code sieht für mich gut aus.

@yajra Danke für die Bestätigung. Versionen sind wie unten

PHP - 5.5.38-3
Laravel - 5.0.34
Datentabellen - yajra/laravel-datatables-oracle: ^6.3 (wie in composer.json)

Es scheint, dass in 'getOrMethod' in der Helper-Klasse eine Ausnahme ausgelöst wird, während versucht wird, einen als Eingabeparameter übergebenen "clouser" in einen niedrigeren Wert zu konvertieren.

public static function getOrMethod($method) {
   if (! Str::contains(Str::lower($method), 'or')) {
      return 'or' . ucfirst($method);
   }
      return $method;
}

'$method' ist ein Clouser als übergeben function($query, $keyword) , wie unten

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
    """
}

Obwohl ich das Problem, mit dem ich konfrontiert war, nicht herausfinden konnte, konnte ich diesen speziellen Anwendungsfall umgehen. Danke für die hier verfügbaren Hinweise.

Ansicht: Haben Sie Folgendes in der Ansicht innerhalb des Skript-Tags

{ 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 }

Controller: Rufen Sie first_name usw. in der SQL-Abfrage zusammen mit den restlichen Spaltenwerten ab.

@ AshishGupta001 bin froh, dass du das herausgefunden hast. Das habe ich auch seit der Version 4.2 von Laravel gemacht. 👍

@ AshishGupta001 Gute Lösung!

@yajra Können wir eine hinzugefügte Spalte mit der addColumn durchsuchen, deren Daten aus der Datenbank stammen, aber wir fügen diese Spalte nicht im JS hinzu?

Oder sollten wir es dem JS hinzufügen und es unsichtbar, aber durchsuchbar machen?

Einige Möglichkeiten, die ich mir vorstellen kann:

  1. Fügen Sie es zu js hinzu und machen Sie es unsichtbar und durchsuchbar, wie Sie gesagt haben.
  2. Verwenden Sie filterColumn, um die Suche nach hinzugefügten Spalten manuell durchzuführen.
  3. Deklariere es so:
{data: 'added_column', name: 'actual_column_name'}

Danke für deine schnelle Antwort @yajra

Ich habe bereits die zweite Lösung ausprobiert, aber ich habe festgestellt, dass diese hinzugefügte Spalte in der Abfrage nicht berücksichtigt wird.

Irgendwelche Gedanken?

Stellen Sie sicher, dass Sie dieser Spalte nicht searchable: false hinzugefügt haben.

So habe ich die Spalte ->addColumn('company_name', function($deal) { return $deal->company_name; }) hinzugefügt

Und die globale Suchanfrage als $dataTable->filterColumn('company_name', 'where', "like", ["%$keyword%"]);

Können wir die searchable: false im Backend übergeben?

searchable: false befindet sich auf der clientseitigen js.

Übrigens, welche Version verwendest du?

Ah okay. Wir müssen also immer noch den ersten Weg verwenden, den Sie erwähnt haben, mit diesem Weg.
Ich verwende v6.17.0

Ich habe das gleiche Problem wie @ AshishGupta001 leider
Ich habe die filterColumn-Alternative untersucht, konnte sie aber auch nicht zum Laufen bringen.
mit "yajra/laravel-datatables-oracle": "~9.0"

Controller-Methode:

    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');
    }

Klinge 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" },
          ]
        });

Ausnahme: beim Suchen oder Sortieren:

yajraIssue

Wie sich herausstellte, war das Problem mit dieser Ausnahme meine Schuld; Ich hatte ein doppeltes '$$'-Zeichen in meiner filterColumn-Methode.
yajra_issue_fix_1

Das hat mein Sortierproblem aber nicht behoben. Ich muss noch wissen:

  1. wie man die Spalte sortierbar macht
  2. wie man verwandte Spalten durchsucht und sortiert Ein weiterer Blick auf die Dokumente hat dies für meinen Anwendungsfall gelöscht

@seewhy17 Sie können orderColumn für eine komplexe Sortierung verwenden. In Ihrem Fall würde die Bestellung von fullname jedoch bereits sofort funktionieren.

@seewhy17 Sie können orderColumn für eine komplexe Sortierung verwenden. In Ihrem Fall würde die Bestellung von fullname jedoch bereits sofort funktionieren.

Nun, das war nicht der Fall, ich denke, die Methode filterColumn kollidiert mit einem Assessor auf dem Modell, der im Grunde dasselbe tut ... Ich weiß es wirklich nicht.
Wissen Sie, ich habe es irgendwie zum Arbeiten gebracht, indem ich dem js ein name: lastname hinzugefügt habe, so dass es nach Nachname filtert und die Methode filterColumn redundant ist

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen