Laravel-datatables: como pesquisar em uma coluna gerada por addColumn?

Criado em 3 ago. 2015  ·  22Comentários  ·  Fonte: yajra/laravel-datatables

Em primeiro lugar, ótimo trabalho para este pacote incrível.

Eu tenho um pequeno problema:

Eu adicionei uma nova coluna personalizada em seu arquivo de demonstração: ... / eloquent / add-edit-remove-column, desejo pesquisar / filtrar para essa coluna, mas recebo um erro no navegador ao inserir tudo.

Existe uma solução de pesquisa / filtro em uma coluna personalizada e depois disso para adicionar um texto de entrada de pesquisa para cada coluna na tabela, inclusive para custom_column?

Erro no 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>

Código do controlador:

    public function getAddEditRemoveColumnData()
    {
        $users = User::select(['id', 'name', 'email', 'password', 'created_at', 'updated_at']);

        return Datatables::of($users)
                                 ->addColumn('new_column' , 'ABC')
                                  ->make(true)
    }

Código do 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}
        ]
    });

Comentários muito úteis

@marioene , você não pode pesquisar em addColumn se os dados não forem do banco de dados. Uma solução alternativa para isso é adicionar a coluna em sua instrução de seleção como abaixo. Não há necessidade de usar addColumn .

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

Observação: talvez seja necessário escrever um filterColumn para que funcione. Apenas certifique-se de que o sql gerado está funcionando e deve funcionar com o pacote também.

Todos 22 comentários

@marioene , você não pode pesquisar em addColumn se os dados não forem do banco de dados. Uma solução alternativa para isso é adicionar a coluna em sua instrução de seleção como abaixo. Não há necessidade de usar addColumn .

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

Observação: talvez seja necessário escrever um filterColumn para que funcione. Apenas certifique-se de que o sql gerado está funcionando e deve funcionar com o pacote também.

Fechar devido à inatividade e solução alternativa sugerida acima deve corrigir o problema. Obrigado!

@yajra Eu segui sua sugestão de primeiro adicionar uma coluna calculada usando 'selecionar' (no Controlador)

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

Então eu adicionei um filtro personalizado (no controlador)

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

Quando eu carrego a página pela primeira vez, a tabela de dados é renderizada corretamente quando eu faço uma pesquisa usando a caixa de texto de entrada de pesquisa global, um erro está sendo lançado

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

Você pode me dizer onde posso estar cometendo um erro.

@ AshishGupta001 tente inspecionar a solicitação ajax usando ferramentas de desenvolvimento de cromo ou firebug. Ele lhe dará uma dica sobre o que está causando o problema. Muito provavelmente, um problema de exceção do sql.

@yajara Obrigado por sua resposta rápida.
Ao implementar a pesquisa global para uma coluna 'calculada' (no meu caso 'full_name'), fiz referência a
1) Problema 168: https://github.com/yajra/laravel-datatables/issues/168
2) Exemplo: https://datatables.yajrabox.com/eloquent/post-column-search

Antes de adicionar o 'filterColumn ()' personalizado para minha tabela de dados, estava recebendo exceção de SQL reclamando da coluna ausente 'full_name' na tabela. Em seguida, adicionei o código abaixo para adicionar um filtro personalizado para a coluna 'calculada' (no meu caso 'full_name') como abaixo

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

Agora recebo o seguinte erro no log

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

Agradeço se você puder ajudar a depurar esse problema.

@ AshishGupta001 qual versão você está usando? Seu código parece bom para mim.

@yajra Obrigado por confirmar. As versões são as seguintes

PHP - 5.5.38-3
Laravel - 5.0.34
Datatables - yajra / laravel-datatables-Oracle: ^ 6,3 (como em composer.json)

Parece que em 'getOrMethod' na classe Helper, uma exceção está sendo lançada enquanto ele está tentando converter para diminuir um "clouser" passado como um parâmetro de entrada.

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

'$ method' é um clouser conforme passado function($query, $keyword) , conforme abaixo

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

Embora eu não tenha conseguido descobrir o problema que enfrentei, fui capaz de descobrir a maneira de contornar esse caso de uso específico. Obrigado pelas dicas disponíveis aqui.

Visualização: Tenha o seguinte na Visualização dentro da tag 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 }

Controlador: busca o first_name etc na consulta SQL junto com o restante dos valores da coluna.

@ AshishGupta001 que bom que você descobriu isso. Eu também fazia isso desde a versão 4.2 do Laravel. 👍

@ AshishGupta001 Boa solução!

@yajra Podemos pesquisar uma coluna adicionada usando addColumn cujos dados vêm do banco de dados, mas não estamos adicionando essa coluna no JS?

Ou devemos adicioná-lo ao JS e torná-lo invisível, mas pesquisável?

Algumas maneiras em que posso pensar:

  1. Adicione-o a js e torne-o invisível e pesquisável como você disse.
  2. Use filterColumn para lidar manualmente com a pesquisa da coluna adicionada.
  3. Declare desta forma:
{data: 'added_column', name: 'actual_column_name'}

Obrigado pela sua resposta rápida @yajra

Já estava tentando a segunda solução, mas notei que essa coluna adicionada não é considerada na consulta.

Alguma ideia ?

Certifique-se de não adicionar searchable: false nessa coluna.

Foi assim que adicionei a coluna ->addColumn('company_name', function($deal) { return $deal->company_name; })

E a consulta de pesquisa global como $dataTable->filterColumn('company_name', 'where', "like", ["%$keyword%"]);

Podemos passar searchable: false no back-end?

searchable: false está no js do lado do cliente.

BTW, qual versão você está usando?

Ah ok. Portanto, ainda precisamos usar a primeira forma que você mencionou, com esta forma.
Estou usando v6.17.0

Estou tendo o mesmo problema que @ AshishGupta001, infelizmente, o truque do lado do cliente não
Eu explorei a alternativa filterColumn, mas não consegui fazê-la funcionar também.
usando "yajra / laravel-datatables-oracle": "~ 9.0"

método do controlador:

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

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

Exceção: ao tentar pesquisar ou classificar:

yajraIssue

como se constatou que o problema com essa exceção foi minha culpa; Eu tinha um sinal duplo '$$' no meu método filterColumn.
yajra_issue_fix_1

Mas isso não resolveu meu problema de classificação. Eu ainda preciso saber:

  1. como tornar a coluna classificável
  2. como pesquisar e classificar colunas relacionadas outra olhada na documentação limpou isso para o meu caso de uso

@ seewhy17 você pode usar orderColumn para classificação complexa. No entanto, no seu caso, pedir por fullname já funcionaria fora da caixa, afaik.

@ seewhy17 você pode usar orderColumn para classificação complexa. No entanto, no seu caso, pedir por fullname já funcionaria fora da caixa, afaik.

Bem, isso não aconteceu, eu acho que o método filterColumn está em conflito com um assessor no modelo que basicamente faz a mesma coisa ... eu realmente não sei.
Para saber, eu meio que consegui trabalhar adicionando name: lastname ao js, ​​então ele filtra por sobrenome e o método filterColumn é redundante

Esta página foi útil?
0 / 5 - 0 avaliações