tablas de datos jquery, clasificación personalizada en el lado del servidor
laravel datatables (4)
Estoy usando Laravel 4.2, con tablas de datos jQuery del lado del servidor.
Paquete: https://github.com/Chumper/Datatable
¿Cómo puedo agregar una clasificación personalizada?
como para columnas de moneda, tiempo, etc.
¿No has revisado la documentación? Porque se explica allí:
public function getDatatable() { return Datatable::collection(User::all(array(''id'',''name''))) ->showColumns(''id'', ''name'') ->searchColumns(''name'') ->orderColumns(''id'',''name'') ->make(); }
NOTA: esto no hizo uso del paquete Chumper / Datatable, pero sí utiliza tablas de datos jQuery, por lo que puede ser de alguna utilidad.
Así es como lo hice. Este fue un escenario en el que tuve una mesa con equipos de fútbol americano. Cada equipo era miembro de una Conferencia, que era parte de una División. Los equipos pueden clasificarse por nombre de equipo, conferencia o división. A continuación se muestra el código del lado del servidor utilizado para implementar esto. Además, podrían filtrarse por conferencia o división.
/*
* Route::get( ''api/v1/teams-table'', ''APIController@teamsTable'' );
*/
public function dataTable() {
// get the input parameters
$i = Input::all();
// parse the parameters and set default values
$draw = isset( $i[ ''draw'' ] ) ? $i[ ''draw'' ] : 1;
$start = isset( $i[ ''start'' ] ) ? $i[ ''start'' ] : 0;
$length = isset( $i[ ''length'' ] ) ? $i[ ''length'' ] : 10;
$search = isset( $i[ ''search'' ][ ''value'' ] ) && '''' != $i[ ''search'' ][ ''value'' ] ? $i[ ''search'' ][ ''value'' ] : false;
$ordrby = isset( $i[ ''order'' ] ) ? $i[ ''columns'' ][ $i[ ''order'' ][ 0 ][ ''column'' ] ][ ''name'' ] : '''';
$ordrdr = isset( $i[ ''order'' ] ) ? $i[ ''order'' ][ 0 ][ ''dir'' ] : ''asc'';
$total = Team::count();
$filter = $total;
// get the data
if ( '''' == $search ) {
switch( $ordrby ) {
case ''name'':
$teams = Team::with( ''conferences'', ''logo'', ''conferences.division'' )
->skip( $start )
->take( $length )
->orderBy( ''name'', $ordrdr )
->get();
break;
case ''conference'':
$teams = Team::with( ''conferences'', ''logo'', ''conferences.division'' )
->join( ''conference_team'', ''conference_team.team_id'', ''='', ''teams.id'' )->join( ''conferences'', ''conferences.id'', ''='', ''conference_team.conference_id'' )
->orderBy( ''conferences.abbr'', $ordrdr )
->skip( $start )
->take( $length )
->get();
break;
case ''division'':
$teams = Team::with( ''conferences'', ''logo'', ''conferences.division'' )
->skip( $start )
->take( $length )
->conference()
->division()
->orderBy( ''abbr'', $ordrdr )
->get();
break;
default:
$teams = Team::with([ ''conferences'', ''logo'', ''conferences.division'' ])
->skip( $start )
->take( $length )
->get();
}
} else {
$teams = Team::with( ''conferences'', ''logo'', ''conferences.division'' )
->skip( $start )
->take( $length )
->where( ''name'', ''LIKE'', ''%'' . $search . ''%'' )
->orWhereHas( ''conferences'', function( $q ) use ( $search ) {
$q->where( ''abbr'', ''LIKE'', ''%'' . $search . ''%'' )
->orWhereHas( ''division'', function( $qu ) use ( $search ) {
$qu->where( ''abbr'', ''LIKE'', ''%'' . $search . ''%'' );
});
})
->get();
$filter = Team::with( ''conferences'', ''logo'', ''conferences.division'' )
->where( ''name'', ''LIKE'', ''%'' . $search . ''%'' )
->orWhereHas( ''conferences'', function( $q ) use ( $search ) {
$q->where( ''abbr'', ''LIKE'', ''%'' . $search . ''%'' )
->orWhereHas( ''division'', function( $qu ) use ( $search ) {
$qu->where( ''abbr'', ''LIKE'', ''%'' . $search . ''%'' );
});
})
->count();
}
// loop through the retrieved data and format it to be returned as JSON
$data = [];
foreach ( $teams as $t ) {
$show = URL::route( ''admin.team.show'', $t->slug );
$edit = URL::route( ''admin.team.depth_chart'', $t->slug );
$data[] = [
''checkbox'' => ''<label><input type="checkbox" class="ace" value="'' . $t->id . ''" /><span class="lbl"></span></label>'',
''logo'' => ''<img src="'' . $t->logo->filename . ''" alt="'' . $t->name . '' logo" height="40">'',
''name'' => [
''display'' => link_to_route( ''admin.team.show'', $t->name, [ $t->slug ] ),
''filter'' => $t->name,
''sort'' => $t->name,
],
''conference'' => [
''display'' => link_to_route( ''admin.conference.show'', $t->conferences[ 0 ]->abbr, [ $t->conferences[ 0 ]->slug ] ),
''filter'' => $t->conferences[ 0 ]->name . '' '' . $t->conferences[ 0 ]->abbr,
''sort'' => $t->conferences[ 0 ]->abbr,
],
''division'' => [
''display'' => link_to_route( ''admin.division.show'', $t->conferences[ 0 ]->division->abbr, [ $t->conferences[ 0 ]->division->slug ] ),
''filter'' => $t->conferences[ 0 ]->division->name . '' '' . $t->conferences[ 0 ]->division->abbr,
''sort'' => $t->conferences[ 0 ]->division->abbr,
],
''site'' => ''<a target="_blank" href="'' . $t->url . ''">website <i class="fa fa-external-link"></i></a>'',
''actions'' => sprintf( $this->actions, $show, $edit, $show, $edit ),
];
}
$tdata = [
''draw'' => $draw,
''recordsTotal'' => $total, //consider caching or setting fixed value for this
''recordsFiltered'' => $filter,
''data'' => $data,
];
return Response::json( $tdata );
}
Con un poco de suerte, puedes ajustar este ejemplo para que se ajuste a tu situación. ¡Espero que esto ayude!
¿No estás seguro si por custom sorting
quieres decir ordenar las filas haciendo clic en los encabezados? Si eso es lo que quiere decir, entonces puede definirlos en el lado del cliente definiendo la configuración de tabla de datos.
oSettings = $("#{{$table->getId()}}").dataTable().fnSettings();
oSettings.aaSorting = [[6, ''desc'']];
Pero si desea mantener una clasificación predeterminada de una columna en particular cuando se carga la tabla de datos, entonces
Datatable::table()
->addColumn($theader) // these are the column headings to be shown
->setOptions(''order'', array([$ordercolumn ,"desc"]))
->setUrl(route(''route.name'', $form_id))
->render()
Espero que esto ayude.
así es como lo hago
nb no está optimizado. más o menos un fragmento de código completo sin comprobación de errores
función de controlador laravel (es L5.2 pero puede degradarse fácilmente a 4.2):
$response = array();
$query = MyModel::query();
$response[''recordsTotal''] = MyModel::count();
$response[''draw''] = Input::get(''draw'', 0);
$query->where(''searchField'', ''LIKE'', ''%'' . Input::get(''search'', array(''value'' => ''''))[''value''] . ''%'');
$response[''recordsFiltered''] = $query->count();
$query->take(Input::get(''length'', 1));
$query->offset(Input::get(''start'', 0));
$columns = Input::get(''columns'');
$orders = Input::get(''order'', []);
$data = $data->toArray();
foreach($orders as $order){
$idx = $order[''column''];
$column = $columns[$idx];
$orderFactor = 1;
if($order[''dir''] == ''desc'')
$orderFactor = -1;
$dname = $column[''data''];
if(count($data)>0){
if(isset($data[0][$dname])){
usort($data, function($record1, $record2) use($dname, $orderFactor){
// here you implement your custom sorting
// like if($dname === ''price'') return compare_price($record1[$dname], $record2[$dname]) * $orderFactor;
// but I hope you''re not storing prices as strings in your database. you won''t need this custom sorting
//
return strcmp($record1[$dname], $record2[$dname]) * $orderFactor;
});
}
}
}
$response[''data''] = $data;
return Response::json($response);
ps este código asume que el campo ''datos'' de las columnas datatable se nombra exactamente como el nombre del campo en su base de datos. También necesitarás usar una función render para renderizar la columna datatable como desees.
columnas datatable:
columns: [
{ data: ''price'', orderable: true, searchable: true, render: render_price },
{ data: ''anotherField'' },
[...]
],
Ejemplo de render_function:
function render_price(price, type, row) {
return price + '' USD'';
}
de esta forma, tendrá sus columnas de visualización de tabla de datos de la forma que desee (por ejemplo, precio = 10.50 $)
y serán ordenables