Laravel-datatables: La búsqueda desde la columna combinada no funcionó

Creado en 30 may. 2017  ·  18Comentarios  ·  Fuente: yajra/laravel-datatables

Resumen del problema o solicitud de función


Usé filtercolumn () para hacerme buscar en múltiples columnas como el nombre (combinado de first_name y last_name)
había leído su demostración pero la consulta es diferente, así que todavía estoy confundido :(

Fragmento de código del 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;
            }
        });

y este es el código en mi 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);
    }

Detalles del sistema

  • Sistema operativo: Ubuntu 16.04
  • Versión PHP: 7.0
  • Versión de Laravel: 5.1
  • Versión de Laravel-Datatables: 6.0
question

Comentario más útil

finalmente resuelto, modifico la consulta en el controlador y la tabla de datos, así:

$("#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;
            }
        });

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

Gracias :)

Todos 18 comentarios

@faisalhilmi vea la solución ofrecida en https://github.com/yajra/laravel-datatables/issues/1173. ¡Gracias!

Veo las referencias y luego intento modificarlas así:

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

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

pero la búsqueda solo puede realizarse con nombre o apellido, no con ambos.
¿Es posible?

Hmm, creo que hay un error aquí en relación con la función de

¿Puedes intentar:

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

sí, quiero buscar el nombre completo :)
lo intento así

$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}%"]);
})

pero aún no funciona, incluso intento cambiar $ query en filtercolumn a $ users :(

¿Hay algún problema en la consulta de $ users?

¿Hay algún error en su respuesta ajax?

no hay error, solo "No se encontraron registros coincidentes" cuando busco "umum de cliente"
"cliente" es first_name en la tabla de usuarios
"umum" es el apellido en la tabla de usuarios

¿Puede intentar inspeccionar la solicitud ajax y pegar el sql generado? Sospecho que hay algo mal en su sql. Intente ejecutarlo manualmente.

Vaya, acabo de darse cuenta de que está utilizando v6.xy la búsqueda de varios términos no es aplicable en él. ¡Lo siento!

"yajra / laravel-datatables-oracle": "~ 6.0", ¿ese es el problema?

No, no es el problema, solo estaba haciendo referencia a una función incorrecta. Creo que el error aquí está en su SQL generado.

Usa concat en el nombre y apellido, pero usa - para separarlo, no el espacio. ¿Quizás eso está causando el problema?

no, todavía no puedo encontrar el nombre completo :(

Necesita depurar la consulta generada. Utilice las herramientas de desarrollo de Chrome o Firebug e inspeccione el SQL generado.

¿Debo agregar concat en esto?

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

Oh, necesitas eliminar ->get(); y dejar que el paquete haga la paginación en el nivel sql.

No puedo porque es hermano de otro proceso :(

Si usa ->get() , ahora está usando colección en lugar de elocuente. Y creo que filterColumn no es aplicable en Collection . Necesita encontrar una manera de eliminar get en su consulta. Ese es el problema por el que falla la búsqueda.

finalmente resuelto, modifico la consulta en el controlador y la tabla de datos, así:

$("#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;
            }
        });

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

Gracias :)

¿Fue útil esta página
0 / 5 - 0 calificaciones

Temas relacionados

alejandri picture alejandri  ·  3Comentarios

t0n1zz picture t0n1zz  ·  3Comentarios

techguydev picture techguydev  ·  3Comentarios

jackrsantana picture jackrsantana  ·  3Comentarios

FilipeBorges1993 picture FilipeBorges1993  ·  3Comentarios