Primero, gran trabajo para este increíble paquete.
Tengo un pequeño problema:
Agregué una nueva columna personalizada en su archivo de demostración: ... / eloquent / add-edit-remove-column, quiero buscar / filtrar esa columna, pero aparece un error en el navegador cuando ingreso todo.
¿Existe una solución para buscar / filtrar en una columna personalizada y luego agregar un texto de entrada de búsqueda para cada columna de la tabla, incluso para custom_column?
Error en la consola de FireBug:
<span class="exception_message">SQLSTATE[42S22]: Column not found: 1054 Champ
'new_column' inconnu dans where clause (SQL: select count(*) as aggregate from (select '
;1' 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 del 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 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}
]
});
@marioene , no puede buscar en addColumn
si los datos no son de la base de datos. Una solución para esto es agregar la columna en su declaración de selección como se muestra a continuación. No es necesario usar addColumn
.
$users = User::select([
'id', 'name', 'email', 'password', 'created_at', 'updated_at',
DB::raw("'ABC' as new_column")
]);
Nota: Es posible que deba escribir un
filterColumn
para que funcione. Solo asegúrese de que el sql generado esté funcionando y también debería funcionar con el paquete.
El cierre debido a la inactividad y la solución alternativa sugerida anteriormente deberían solucionar el problema. ¡Gracias!
@yajra Seguí tu sugerencia de agregar primero una columna calculada usando 'seleccionar' (en Controlador)
$staffData = Staff::select('id', 'staff_id', \DB::raw('concat(first_name, " ", middle_name, " ", last_name) as full_name'), 'department_name', 'status');
Luego agregué un filtro personalizado (en 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);
Cuando cargo por primera vez la página, la tabla de datos se representa correctamente cuando busco utilizando el cuadro de texto de entrada de búsqueda global, se arroja un error
Ajax error. http://datatables.net/tn/7
¿Puede decirme dónde podría estar cometiendo un error?
@ AshishGupta001 intente inspeccionar la solicitud ajax usando las herramientas de desarrollo de Chrome o Firebug. Le dará una pista sobre la causa del problema. Lo más probable es que se trate de un problema de excepción de SQL.
@yajara Gracias por tu rápida respuesta.
Al implementar la búsqueda global de una columna 'calculada' (en mi caso, 'nombre_completo') tomé referencia a
1) Número 168: https://github.com/yajra/laravel-datatables/issues/168
2) Ejemplo: https://datatables.yajrabox.com/eloquent/post-column-search
Antes de agregar la 'filterColumn ()' personalizada para mi tabla de datos, recibía una excepción de SQL quejándose por la falta de la columna 'full_name' en la tabla. Luego agregué el siguiente código para agregar un filtro personalizado para la columna 'calculada' (en mi caso, 'nombre_completo') como se muestra a continuación
$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);
Ahora obtengo el siguiente error en el registro
mb_strtolower() expects parameter 1 to be string, object given
en archivo ......./vendor/laravel/framework/src/Illuminate/Support/Str.php#162
Aprecie si puede ayudar a solucionar este problema.
@ AshishGupta001 ¿Qué versión estás usando? Tu código me parece bien.
@yajra Gracias por confirmar. Las versiones son las siguientes
PHP - 5.5.38-3
Laravel - 5.0.34
Tablas de datos - yajra / laravel-datatables-oracle: ^ 6.3 (como en composer.json)
Parece que en 'getOrMethod' en la clase Helper, se lanza una excepción ya que está tratando de convertir para reducir un "clouser" pasado como parámetro de entrada.
public static function getOrMethod($method) {
if (! Str::contains(Str::lower($method), 'or')) {
return 'or' . ucfirst($method);
}
return $method;
}
'$ método' es un clouser pasado function($query, $keyword)
, como se muestra a continuación
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
"""
}
Aunque no pude resolver el problema al que me enfrenté, pude encontrar la forma de solucionar este caso de uso específico. Gracias por las sugerencias disponibles aquí.
Vista: tenga lo siguiente en la vista dentro de la etiqueta de secuencia de comandos
{ 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: obtenga el primer nombre, etc. en la consulta SQL junto con el resto de los valores de la columna.
@ AshishGupta001 me alegro de que lo hayas descubierto. Eso es lo que solía hacer también desde la versión Laravel 4.2. 👍
@ AshishGupta001 ¡ Buena solución!
@yajra ¿Podemos buscar una columna agregada usando addColumn cuyos datos provienen de la base de datos pero no estamos agregando esta columna en el JS?
¿O deberíamos agregarlo al JS y hacerlo invisible pero con capacidad de búsqueda?
Algunas formas en las que puedo pensar:
{data: 'added_column', name: 'actual_column_name'}
Gracias por tu rápida respuesta @yajra
Ya estaba probando la segunda solución, pero noté que esta columna agregada no se considera en la consulta.
Alguna idea ?
Asegúrese de no agregar searchable: false
en esa columna.
Así es como agregué la columna ->addColumn('company_name', function($deal) {
return $deal->company_name;
})
Y la consulta de búsqueda global como $dataTable->filterColumn('company_name', 'where', "like", ["%$keyword%"]);
¿Podemos pasar searchable: false
en el backend?
searchable: false
está en el lado del cliente js.
Por cierto, ¿qué versión estás usando?
Ah, vale. Así que todavía necesitamos usar la primera forma que mencionaste, con esta forma.
Estoy usando v6.17.0
Tengo el mismo problema que @ AshishGupta001, desafortunadamente, el truco del lado del cliente no lo corta ya que la columna no se puede ordenar.
He explorado la alternativa filterColumn pero no pude hacer que funcione también.
usando "yajra / laravel-datatables-oracle": "~ 9.0"
método del 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" },
]
});
Excepción: cuando se intenta buscar u ordenar:
pues resulta que el problema con esa excepción fue culpa mía; Tenía un signo doble '$$' dentro de mi método filterColumn.
Sin embargo, eso no solucionó mi problema de clasificación. Todavía necesito saber:
@ seewhy17 puede usar orderColumn para una clasificación compleja. Sin embargo, en su caso, ordenar por fullname
ya funcionaría de fábrica.
@ seewhy17 puede usar orderColumn para una clasificación compleja. Sin embargo, en su caso, ordenar por
fullname
ya funcionaría de fábrica.
Bueno, no fue así, supongo que el método filterColumn entra en conflicto con un evaluador del modelo que básicamente hace lo mismo ... Realmente no lo sé.
Para saber, logré que funcione agregando un name: lastname
al js, por lo que filtra por apellido y el método filterColumn es redundante
Comentario más útil
@marioene , no puede buscar en
addColumn
si los datos no son de la base de datos. Una solución para esto es agregar la columna en su declaración de selección como se muestra a continuación. No es necesario usaraddColumn
.