Laravel-datatables: A pesquisa da coluna combinada não funcionou

Criado em 30 mai. 2017  ·  18Comentários  ·  Fonte: yajra/laravel-datatables

Resumo do problema ou solicitação de recurso


Usei filtercolumn () para fazer com que eu pudesse pesquisar várias colunas como nome (combinado de first_name e last_name)
Eu tinha lido sua demonstração, mas a consulta é diferente, então ainda estou confuso :(

Fragmento de código do problema

$(function () {
        $("#datatable").DataTable({
            processing: true,
            serverSide: true,
            "order": [[ 1, "asc" ]],
            ajax: "{!! route('admin.customers.getdata','Umum') !!}",
            columns: [
                { data: null, bSortable: false, className: "text-center" },
                { data: "id" },
                { data: "name", name: "name" },
                { data: "type" },
                { data: "email" },
                { data: "location" },
                { data: "active", bSortable: false, className: "text-center" },
                { data: "free_ongkir", bSortable: false, className: "text-center" },
                { data: "action", bSortable: false, className: "text-center" }
            ],
            fnRowCallback: function(nRow, aData, iDisplayIndex){
                $("td:first", nRow).html(iDisplayIndex +1);
                return nRow;
            }
        });

e este é o código no meu controlador

public function getdata($type)
    {
        $users = User::where(['type'=>$type])->whereHas('roles', function ($query) {
            $query->where('slug', '=', 'user');
        })->get();
        foreach ($users as $key => $value) {
            if($value->id == Sentinel::getUser()->id) $value->disabled = "disabled";
            else$value->disabled = "";
        }
        return Datatables::of($users)
        ->editColumn('name', '
            <a href="{{ route(\'admin.customers.show\', $id) }}">{!! $first_name." ".$last_name !!}</a>
        ')
        ->filterColumn('name', function($query, $keyword) {
                    $sql = "CONCAT(users.first_name,'-',users.last_name)  like ?";
                    $query->whereRaw($sql, ["%{$keyword}%"]);
                })
        ->editColumn('type', function($users) {
            if($users->hasAccess('superadmin')) return 'Super Admin';
            else return "Komoditi $users->type";
        })
        ->editColumn('active', function($users) {
            if(!$users->is_approved) {
                return '<span class="has-error form-group"><label><i class="fa fa-times-circle-o"></i> Belum di approve</label></span>';
            } else if(Activation::completed($users)) {
                return '<span class="has-success form-group"><label><i class="fa fa-check"></i> Aktif</label></span>';
            } else {
                return '<span class="has-error form-group"><label><i class="fa fa-times-circle-o"></i> Belum Aktivasi</label></span>';
            }
        })
        ->editColumn('free_ongkir', function($users) {
          if ($users->free_ongkir == 1) {
            return '<span class="has-success form-group"><label><i class="fa fa-check"></i></label></span>';
          }else {
            return '<span class="has-error form-group"><label><i class="fa fa-times-circle-o"></i></label></span>';
          }
        })
        ->editColumn('location', function($users){
            if(empty($users->city->name)) return 'None';
            else return $users->city->name;
        })
        ->addColumn('action', '@if(Sentinel::getUser()->hasAccess(["customers.edit"]))<button class="btn btn-primary" type="button" onClick="location.href=\'{{ route(\'admin.customers.edit\', $id) }}\'"><i class="fa fa-edit"></i></button>
            <strong i="13">@endif</strong>
            {!! Form::open([
                \'method\'=>\'DELETE\',
                \'route\' => [\'admin.customers.destroy\', $id],
                \'style\' => \'display:inline\'
            ]) !!}
            @if(Sentinel::getUser()->hasAccess(["customers.destroy"]))
                {!! Form::button(\'<i class="fa fa-trash"></i>\', [\'class\' => \'btn btn-danger btn-md\',\'type\'=>\'submit\',\'onclick\'=>\'return confirm("Are you sure want to delete?")\', $disabled]) !!}
             <strong i="14">@endif</strong>
            {!! Form::close() !!}

        ')
        ->make(true);
    }

Detalhes do sistema

  • Sistema operacional: Ubuntu 16.04
  • Versão PHP: 7.0
  • Versão do Laravel: 5.1
  • Laravel-Datatables Versão: 6.0
question

Comentários muito úteis

finalmente resolvido, eu modifico a consulta no controlador e a tabela de dados, assim:

$("#datatable").DataTable({
            processing: true,
            serverSide: true,
            "order": [[ 1, "asc" ]],
            ajax: "{!! route('admin.customers.getdata','Umum') !!}",
            columns: [
                { data: null, bSortable: false, className: "text-center" },
                { data: "id" },
                { data: "name", name: "full_name" },
                { data: "type" },
                { data: "email" },
                { data: "location" },
                { data: "active", bSortable: false, className: "text-center" },
                { data: "free_ongkir", bSortable: false, className: "text-center" },
                { data: "action", bSortable: false, className: "text-center" }
            ],
            fnRowCallback: function(nRow, aData, iDisplayIndex){
                $("td:first", nRow).html(iDisplayIndex +1);
                return nRow;
            }
        });

O controlador:

{
        $users = User::select('id','email','first_name','last_name','city_id', 'is_approved','type', DB::raw("CONCAT(first_name,' ',last_name) as full_name"))->where(['type'=>$type])->whereHas('roles', function ($query) {
            $query->where('slug', '=', 'user');
        })->get();
        foreach ($users as $key => $value) {
            if($value->id == Sentinel::getUser()->id) $value->disabled = "disabled";
            else$value->disabled = "";
        }
        return Datatables::of($users)
        ->editColumn('name', '
            <a href="{{ route(\'admin.customers.show\', $id) }}">{!! $first_name." ".$last_name !!}</a>
        ')
        ->editColumn('type', function($users) {
            if($users->hasAccess('superadmin')) return 'Super Admin';
            else return "Komoditi $users->type";
        })
        ->editColumn('active', function($users) {
            if(!$users->is_approved) {
                return '<span class="has-error form-group"><label><i class="fa fa-times-circle-o"></i> Belum di approve</label></span>';
            } else if(Activation::completed($users)) {
                return '<span class="has-success form-group"><label><i class="fa fa-check"></i> Aktif</label></span>';
            } else {
                return '<span class="has-error form-group"><label><i class="fa fa-times-circle-o"></i> Belum Aktivasi</label></span>';
            }
        })
        ->editColumn('free_ongkir', function($users) {
          if ($users->free_ongkir == 1) {
            return '<span class="has-success form-group"><label><i class="fa fa-check"></i></label></span>';
          }else {
            return '<span class="has-error form-group"><label><i class="fa fa-times-circle-o"></i></label></span>';
          }
        })
        ->editColumn('location', function($users){
            if(empty($users->city->name)) return 'None';
            else return $users->city->name;
        })
        ->addColumn('action', '@if(Sentinel::getUser()->hasAccess(["customers.edit"]))<button class="btn btn-primary" type="button" onClick="location.href=\'{{ route(\'admin.customers.edit\', $id) }}\'"><i class="fa fa-edit"></i></button>
            <strong i="9">@endif</strong>
            {!! Form::open([
                \'method\'=>\'DELETE\',
                \'route\' => [\'admin.customers.destroy\', $id],
                \'style\' => \'display:inline\'
            ]) !!}
            @if(Sentinel::getUser()->hasAccess(["customers.destroy"]))
                {!! Form::button(\'<i class="fa fa-trash"></i>\', [\'class\' => \'btn btn-danger btn-md\',\'type\'=>\'submit\',\'onclick\'=>\'return confirm("Are you sure want to delete?")\', $disabled]) !!}
             <strong i="10">@endif</strong>
            {!! Form::close() !!}

        ')
        ->make(true);
    }

Obrigada :)

Todos 18 comentários

@faisalhilmi veja a solução oferecida em https://github.com/yajra/laravel-datatables/issues/1173. Obrigado!

vejo as referências e tento modificar assim:

{ data: "name", name: "name" },
{ data: "first_name", name: "first_name", visible: false },
{ data: "last_name", name: "last_name", visible: false },

no controlador:

        ->editColumn('name', '
            <a href="{{ route(\'admin.customers.show\', $id) }}">{!! $first_name." ".$last_name !!}</a>
        ')
        ->filterColumn('name', function($query, $keyword) {
                $query->orWhere('first_name', 'like', '%'. $keyword . '%');
                $query->orWhere('last_name', 'like', '%'. $keyword . '%');
            })

mas a pesquisa pode apenas com first_name ou sobrenome, não ambos.
É possível?

Hmm, acho que há um bug aqui em relação ao recurso de pesquisa de vários termos . Você está pesquisando o espaço do nome completo separado à direita? Acho que as palavras-chave passadas para filterColumn agora estão separadas em duas partes (nome e sobrenome).

Você pode tentar:

->filterColumn('name', function($query, $keyword) {
    $sql = "CONCAT(users.first_name,'-',users.last_name)  like ?";
    $keyword = request('search.value');
    $query->whereRaw($sql, ["%{$keyword}%"]);
})

sim, quero pesquisar o nome completo :)
eu tento assim

$users = User::where(['type'=>$type])->whereHas('roles', function ($query) {
            $query->where('slug', '=', 'user');
        })->get();
        foreach ($users as $key => $value) {
            if($value->id == Sentinel::getUser()->id) $value->disabled = "disabled";
            else$value->disabled = "";
        }
        return Datatables::of($users)
        ->editColumn('name', '
            <a href="{{ route(\'admin.customers.show\', $id) }}">{!! $first_name." ".$last_name !!}</a>
        ')
        ->filterColumn('name', function($query, $keyword) {
    $sql = "CONCAT(users.first_name,'-',users.last_name)  like ?";
    $keyword = request('search.value');
    $query->whereRaw($sql, ["%{$keyword}%"]);
})

mas ainda não funciona, mesmo eu tento alterar $ query em filtercolumn para $ users :(

há algo errado na consulta de $ users?

Existe algum retorno de erro em sua resposta ajax?

nenhum erro, apenas "Nenhum registro correspondente encontrado" quando eu pesquiso "cliente umum"
"cliente" é first_name na tabela de usuários
"umum" é o último_nome na tabela de usuários

Você pode tentar inspecionar a solicitação ajax e colar o sql gerado? Eu suspeito que há algo errado no seu sql. Tente executá-lo manualmente.

Ops, acabamos de perceber que você está usando a v6.x e a pesquisa de vários termos não se aplica a ela. Desculpa!

"yajra / laravel-datatables-oracle": "~ 6.0", qual é o problema?

Não, não é o problema, eu estava apenas me referindo a um recurso errado. Acho que o erro aqui está no SQL gerado.

Você usa concat no nome e sobrenome, mas usa - para separá-lo, não espaço. Talvez seja isso que está causando o problema?

não, ainda não consigo encontrar o nome completo :(

Você precisa depurar a consulta gerada. Use ferramentas de desenvolvimento de cromo ou firebug e inspecione o SQL gerado.

devo adicionar concat nisso?

$users = User::where(['type'=>$type])->whereHas('roles', function ($query) {
            $query->where('slug', '=', 'user');
        })->get();

Oh, você precisa remover ->get(); e deixar o pacote fazer a paginação no nível sql.

eu não posso porque é irmão de outro processo :(

Se você usar ->get() , agora você está usando coleção em vez de eloquente. E acho que filterColumn não se aplica a Collection . Você precisa encontrar uma maneira de remover o get em sua consulta. Essa é a razão pela qual a pesquisa está falhando.

finalmente resolvido, eu modifico a consulta no controlador e a tabela de dados, assim:

$("#datatable").DataTable({
            processing: true,
            serverSide: true,
            "order": [[ 1, "asc" ]],
            ajax: "{!! route('admin.customers.getdata','Umum') !!}",
            columns: [
                { data: null, bSortable: false, className: "text-center" },
                { data: "id" },
                { data: "name", name: "full_name" },
                { data: "type" },
                { data: "email" },
                { data: "location" },
                { data: "active", bSortable: false, className: "text-center" },
                { data: "free_ongkir", bSortable: false, className: "text-center" },
                { data: "action", bSortable: false, className: "text-center" }
            ],
            fnRowCallback: function(nRow, aData, iDisplayIndex){
                $("td:first", nRow).html(iDisplayIndex +1);
                return nRow;
            }
        });

O controlador:

{
        $users = User::select('id','email','first_name','last_name','city_id', 'is_approved','type', DB::raw("CONCAT(first_name,' ',last_name) as full_name"))->where(['type'=>$type])->whereHas('roles', function ($query) {
            $query->where('slug', '=', 'user');
        })->get();
        foreach ($users as $key => $value) {
            if($value->id == Sentinel::getUser()->id) $value->disabled = "disabled";
            else$value->disabled = "";
        }
        return Datatables::of($users)
        ->editColumn('name', '
            <a href="{{ route(\'admin.customers.show\', $id) }}">{!! $first_name." ".$last_name !!}</a>
        ')
        ->editColumn('type', function($users) {
            if($users->hasAccess('superadmin')) return 'Super Admin';
            else return "Komoditi $users->type";
        })
        ->editColumn('active', function($users) {
            if(!$users->is_approved) {
                return '<span class="has-error form-group"><label><i class="fa fa-times-circle-o"></i> Belum di approve</label></span>';
            } else if(Activation::completed($users)) {
                return '<span class="has-success form-group"><label><i class="fa fa-check"></i> Aktif</label></span>';
            } else {
                return '<span class="has-error form-group"><label><i class="fa fa-times-circle-o"></i> Belum Aktivasi</label></span>';
            }
        })
        ->editColumn('free_ongkir', function($users) {
          if ($users->free_ongkir == 1) {
            return '<span class="has-success form-group"><label><i class="fa fa-check"></i></label></span>';
          }else {
            return '<span class="has-error form-group"><label><i class="fa fa-times-circle-o"></i></label></span>';
          }
        })
        ->editColumn('location', function($users){
            if(empty($users->city->name)) return 'None';
            else return $users->city->name;
        })
        ->addColumn('action', '@if(Sentinel::getUser()->hasAccess(["customers.edit"]))<button class="btn btn-primary" type="button" onClick="location.href=\'{{ route(\'admin.customers.edit\', $id) }}\'"><i class="fa fa-edit"></i></button>
            <strong i="9">@endif</strong>
            {!! Form::open([
                \'method\'=>\'DELETE\',
                \'route\' => [\'admin.customers.destroy\', $id],
                \'style\' => \'display:inline\'
            ]) !!}
            @if(Sentinel::getUser()->hasAccess(["customers.destroy"]))
                {!! Form::button(\'<i class="fa fa-trash"></i>\', [\'class\' => \'btn btn-danger btn-md\',\'type\'=>\'submit\',\'onclick\'=>\'return confirm("Are you sure want to delete?")\', $disabled]) !!}
             <strong i="10">@endif</strong>
            {!! Form::close() !!}

        ')
        ->make(true);
    }

Obrigada :)

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

Questões relacionadas

vipin733 picture vipin733  ·  3Comentários

techguydev picture techguydev  ·  3Comentários

shadoWalker89 picture shadoWalker89  ·  3Comentários

Mopster picture Mopster  ·  3Comentários

ghost picture ghost  ·  3Comentários