F
Filament13mo ago
urbycoz

How can I sort by a custom Column

Here's the table data, which uses Account, Customer and Employee models: Account::query() ->with([customer, employee]) Here are the relationships in the Account model public function customer(): BelongsTo { return $this->belongsTo(Customer::class, 'contactid'); } public function employee(): BelongsTo { return $this->belongsTo(Employee::class, 'contactid'); } ...and the aggregated attribute: public function getCombinedNameAttribute() { if ($this->contactType == 'Customer'){ return $this->customer->name } elseIf ($this->contactType == 'Employee'){ return $this->employee->fullname } } The text column works fine, but I just can't make it sortable. The code below doesn't seem to work: TextColumn::make('combined_name') ->sortable()
7 Replies
Dennis Koch
Dennis Koch13mo ago
You can't as it is no database column.
ArnoNym
ArnoNym12mo ago
Ciao I know i am late but i wanted to recycle this question instead of making a new one. Is it still not possible to define a ->defaultSort on a calculated column? Or is it possible to get the rows of the table in php to implement a custom sorting/ defaultSort? I have a column in my table like this: ->columns([ Tables\Columns\TextColumn::make('distance') ->label('distance') ->state(function (Model $record): string { $distance = CustomStringHelper::calculateDistance($this->gps_lat, $this->gps_long, $record->gps_lat, $record->gps_long); return (int)$distance . 'km'; }) ->sortable(), ]) and at the table ->defaultSort('distance') Is there a way to achieve this? Bump, is it possible to sort the rows manually (php) or how do you sort columns which are not in the db?
awcodes
awcodes12mo ago
You can’t. But you can sort them if you have virtual columns for them on the db. Everything on a table works through the eloquent builder.
ArnoNym
ArnoNym12mo ago
I am not sure if a virtual column can be used in our case. We calculate the distance from the user (geolocation.getCurrentPosition) to a model (known gps lat and long). the location of the user is determined in a js function which calls a php function on the component class. I am able to calculate the distance in the "state" function of the textColumn like this: Tables\Columns\TextColumn::make('distance') ->label('distance') ->state(function (Model $record): string { $distance = CustomStringHelper::calculateDistance($this->gps_lat, $this->gps_long, $record->gps_lat, $record->gps_long); return (int)$distance . 'km'; }) ->sortable(), But neither the sortable nor the ->defaultSort is working ... Anyone has an idea how to do that sortable?
awcodes
awcodes12mo ago
it still has to be done at the eloquent level. maybe try the laravel discord or search for how to do it with eloquent.
ArnoNym
ArnoNym12mo ago
Thanks @awcodes for your honest answers. I am not sure how to do that in eloquent . do you have some hints? 🙂 Thanks in advance
awcodes
awcodes12mo ago
It's a bit advanced by i'm doing something like this to retrieve the closest stores to a zip code. But you might want to look into geospatial column types. Might be a lot easier. Our servers aren't on mysql 8 so had to get clever. Good luck.
public function geoCoords(Builder $builder, array $input): Builder
{
if (isset($input['lat']) && isset($input['lng'])) {
$haversine = "(3961 * acos(cos(radians({$input['lat']}))
* cos(radians(locations.latitude))
* cos(radians(locations.longitude)
- radians({$input['lng']}))
+ sin(radians({$input['lat']}))
* sin(radians(locations.latitude))))";

return $builder
->select('*') //pick the columns you want here.
->selectRaw("{$haversine} AS distance")
->whereRaw("{$haversine} < ?", [$input['radius']])
->orderBy('distance')
->take($input['limit']);
}

return $builder;
}
public function geoCoords(Builder $builder, array $input): Builder
{
if (isset($input['lat']) && isset($input['lng'])) {
$haversine = "(3961 * acos(cos(radians({$input['lat']}))
* cos(radians(locations.latitude))
* cos(radians(locations.longitude)
- radians({$input['lng']}))
+ sin(radians({$input['lat']}))
* sin(radians(locations.latitude))))";

return $builder
->select('*') //pick the columns you want here.
->selectRaw("{$haversine} AS distance")
->whereRaw("{$haversine} < ?", [$input['radius']])
->orderBy('distance')
->take($input['limit']);
}

return $builder;
}
Want results from more Discord servers?
Add your server