Я использую Laravel 4.2 с таблицами данных jQuery на стороне сервера.
Пакет: https://github.com/Chumper/Datatable
Как добавить произвольную сортировку?
например, для столбцов валюты, времени и т. д.
Я использую Laravel 4.2 с таблицами данных jQuery на стороне сервера.
Пакет: https://github.com/Chumper/Datatable
Как добавить произвольную сортировку?
например, для столбцов валюты, времени и т. д.
ПРИМЕЧАНИЕ: при этом не использовался пакет Chumper / Datatable, но он использует таблицы данных jQuery, поэтому может быть полезным.
Вот как я это сделал. Это был сценарий, в котором у меня был стол с командами по американскому футболу. Каждая команда была членом Конференции, которая была частью Дивизиона. Команды можно было отсортировать по названию, конференции или подразделению. Ниже приведен код на стороне сервера, используемый для реализации этого. Кроме того, они могут быть отфильтрованы по конференциям или подразделениям.
/*
* 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 );
}
Если повезет, вы можете скорректировать этот пример в соответствии с вашей ситуацией. Надеюсь это поможет!
вот как я это делаю
n.b. это не оптимизировано. более или менее полный фрагмент кода без проверки ошибок
функция контроллера laravel (это L5.2, но его легко понизить до 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);
p.s. этот код предполагает, что поле 'data' столбцов с данными имеет точно такое же имя, как имя поля в вашей базе данных. Вам также нужно будет использовать render_function для рендеринга столбца datatable по вашему желанию.
столбцы с данными:
columns: [
{ data: 'price', orderable: true, searchable: true, render: render_price },
{ data: 'anotherField' },
[...]
],
Пример render_function:
function render_price(price, type, row) {
return price + ' USD';
}
таким образом у вас будут столбцы, отображающие данные, как вы хотите (например, цена = 10,50 $)
и они будут отсортированы
Если вы пытаетесь отсортировать коллекцию или результат запроса в любом порядке, вы можете сделать что-то вроде этого:
$orders = Order::all()->SortBy('currency','desc');
or
$customers = Customers::where('age',$age)->orderBy('currency','desc')->get();
Кстати, почему вы все еще используете Laravel 4, когда уже есть Laravel 8?
Не уверены, что под custom sorting
вы имеете в виду сортировку строк, нажимая на заголовки? Если вы это имеете в виду, вы можете определить их на стороне клиента, задав параметры данных.
oSettings = $("#{{$table->getId()}}").dataTable().fnSettings();
oSettings.aaSorting = [[6, 'desc']];
Но если вы хотите сохранить сортировку определенного столбца по умолчанию при загрузке таблицы данных, тогда
Datatable::table()
->addColumn($theader) // these are the column headings to be shown
->setOptions('order', array([$ordercolumn ,"desc"]))
->setUrl(route('route.name', $form_id))
->render()
Надеюсь, это поможет.
Вы не проверили документацию? Потому что там объясняется:
public function getDatatable() { return Datatable::collection(User::all(array('id','name'))) ->showColumns('id', 'name') ->searchColumns('name') ->orderColumns('id','name') ->make(); }