Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tap into the sort query #216

Closed
wants to merge 1 commit into from
Closed

tap into the sort query #216

wants to merge 1 commit into from

Conversation

devsrv
Copy link
Contributor

@devsrv devsrv commented Apr 19, 2021

this will allow users to customize the sort query like below

in user's livewire table component

public function tapSorting(Builder $query, $field, $direction) {
    if($field === 'company_name') {
        $sortQuery = Company::select('name')
                    ->whereColumn('companies.user_id', 'users.id'); // a custom query for orderBy(..)

        return $query->orderBy($sortQuery, $direction);
    }
}

this will allow users to customize the sort query like below

> in livewire table component
```php
public function tapSorting(Builder $query, $field, $direction) {
    if($field === 'company_name') {
        $sortQuery = Company::select('name')
                    ->whereColumn('companies.user_id', 'users.id'); // a custom query for orderBy(..)

        return $query->orderBy($sortQuery, $direction);
    }
}
```
@rappasoft
Copy link
Owner

I like the idea, however there might be a better way to do it.

If we are going to go this route we can probably add a sorting() callback to the Column itself, much like the old version.

Let me think about it a little bit.

@devsrv
Copy link
Contributor Author

devsrv commented Apr 19, 2021

callback will be great (y)

@bdelamatre
Copy link
Contributor

Am I the only one that thinks tap implies registering a callback (or multiple)? E.g. if we have a tapSorting() I would expect it to register a callback that accepts (and returns) the builder during sorting. We then would be able to define multiple taps either on a property or by injecting them at some point in the class lifecycle (construct?, mount?, somewhere else?)

If we get this right here we could probably apply the same pattern to search/filter/etc.

@rappasoft
Copy link
Owner

rappasoft commented Apr 20, 2021

Maybe something like: (untested)

public function sortable(callable $callback = null): self
{
    $this->sortable = true;

    if ($callback) {
        $this->sortCallback = $callback;
    }

    return $this;
}
public function applySorting(Builder $query): Builder
{
    foreach ($this->sorts as $field => $direction) {
        if ($this->getColumn($field)->hasSortCallback()) {
            $query = app()->call($this->getColumn($field)->getSortCallback(), ['builder' => $query, 'direction' => $direction]);
        } else {
            $query->orderBy($field, $direction);
        }
    }

    return $query;
}

Then the above example:

Column::make(__('Name'))
    ->sortable(function(Builder $builder, string $direction) {
        return $builder->orderBy(Company::select('name')->whereColumn('companies.user_id', 'users.id'), $direction);
    }),

@devsrv
Copy link
Contributor Author

devsrv commented Apr 20, 2021

Column::make(__('Name'))
    ->sortable(function(Builder $builder, string $direction) {
        return $builder->orderBy(Company::select('name')->whereColumn('companies.user_id', 'users.id'), $direction);
    }),

its neat 👌

@rappasoft
Copy link
Owner

rappasoft commented Apr 20, 2021

So I have it working on this branch with your example: develop...feature/sorting-callbacks

Curious if you guys see any super obvious issues with this approach.

@rappasoft
Copy link
Owner

WIll merge this new feature into the next release!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants