|
| 1 | +# Sortable behavior package for Laravel |
| 2 | + |
| 3 | + |
| 4 | + |
| 5 | +[](https://styleci.io/repos/442271942) |
| 6 | +[](https://scrutinizer-ci.com/g/akaunting/laravel-sortable) |
| 7 | +[](LICENSE.md) |
| 8 | + |
| 9 | +This package allows you to add sortable behavior to `models` and `views`. It ships with a trait where you can set the sortable fields and a blade directive to generate table headers automatically. |
| 10 | + |
| 11 | +## Getting Started |
| 12 | + |
| 13 | +### 1. Install |
| 14 | + |
| 15 | +Run the following command: |
| 16 | + |
| 17 | +```bash |
| 18 | +composer require akaunting/laravel-sortable |
| 19 | +``` |
| 20 | + |
| 21 | +### 2. Publish |
| 22 | + |
| 23 | +Publish configuration |
| 24 | + |
| 25 | +```bash |
| 26 | +php artisan vendor:publish --tag=sortable |
| 27 | +``` |
| 28 | + |
| 29 | +### 3. Configure |
| 30 | + |
| 31 | +You can change the column sorting settings of your app from `config/sortable.php` file |
| 32 | + |
| 33 | +## Usage |
| 34 | + |
| 35 | +All you have to do is use the `Sortable` trait inside your model and define the `$sortable` fields. |
| 36 | + |
| 37 | +```php |
| 38 | +use Akaunting\Sortable\Traits\Sortable; |
| 39 | +use Illuminate\Database\Eloquent\Model; |
| 40 | + |
| 41 | +class Post extends Model |
| 42 | +{ |
| 43 | + use Sortable; |
| 44 | + ... |
| 45 | + |
| 46 | + public $sortable = [ |
| 47 | + 'id', |
| 48 | + 'title', |
| 49 | + 'author', |
| 50 | + 'created_at', |
| 51 | + ]; |
| 52 | + ... |
| 53 | +} |
| 54 | +``` |
| 55 | + |
| 56 | +If you don't define the `$sortable` array, the `Scheme::hasColumn()` function is used which runs an extra database query. |
| 57 | + |
| 58 | +### Scope |
| 59 | + |
| 60 | +The trait adds a `sortable` scope to the model so you can use it just before `paginate`: |
| 61 | + |
| 62 | +```php |
| 63 | +public function index() |
| 64 | +{ |
| 65 | + $posts = Post::query()->sortable()->paginate(10); |
| 66 | + |
| 67 | + return view('posts.index')->with(['posts' => $posts]); |
| 68 | +} |
| 69 | +``` |
| 70 | + |
| 71 | +You can set also default sorting field which will be applied when URL is empty. |
| 72 | + |
| 73 | +```php |
| 74 | +$posts = $post->sortable(['author'])->paginate(10); // $post->orderBy('posts.author', 'asc') |
| 75 | + |
| 76 | +$posts = $post->sortable(['title'])->paginate(10); // $post->orderBy('posts.title', 'asc') |
| 77 | + |
| 78 | +$posts = $post->sortable(['title' => 'desc'])->paginate(10); // $post->orderBy('posts.title', 'desc') |
| 79 | +``` |
| 80 | + |
| 81 | +### Blade Directive |
| 82 | + |
| 83 | +There is a also `blade` directive for you to create sortable links in your views: |
| 84 | + |
| 85 | +```blade |
| 86 | +@sortablelink('title', trans('general.title'), ['parameter' => 'smile'], ['rel' => 'nofollow']) |
| 87 | +``` |
| 88 | + |
| 89 | +The *first* parameter is the column in database. The *second* one is displayed inside the anchor tag. The *third* one is an `array()`, and it sets the default (GET) query string. The *fourth* one is also an `array()` for additional anchor-tag attributes. You can use a custom URL as 'href' attribute in the fourth parameter, which will append the query string. |
| 90 | + |
| 91 | +Only the first parameter is required. |
| 92 | + |
| 93 | +Examples: |
| 94 | + |
| 95 | +```blade |
| 96 | +@sortablelink('title') |
| 97 | +@sortablelink('title', trans('general.title')) |
| 98 | +@sortablelink('title', trans('general.title'), ['filter' => 'active, visible']) |
| 99 | +@sortablelink('title', trans('general.title'), ['filter' => 'active, visible'], ['class' => 'btn btn-success', 'rel' => 'nofollow', 'href' => route('posts.index')]) |
| 100 | +``` |
| 101 | + |
| 102 | +#### Icon Set |
| 103 | + |
| 104 | +You can use any icon set you want. Just change the `icons.wrapper` from the config file accordingly. By default, it uses Font Awesome. |
| 105 | + |
| 106 | +### Sorting Relationships |
| 107 | + |
| 108 | +The package supports `HasOne` and `BelongsTo` relational sorting: |
| 109 | + |
| 110 | +```php |
| 111 | +class Post extends Model |
| 112 | +{ |
| 113 | + use Sortable; |
| 114 | + ... |
| 115 | + |
| 116 | + protected $fillable = [ |
| 117 | + 'title', |
| 118 | + 'author_id', |
| 119 | + 'body', |
| 120 | + ]; |
| 121 | + |
| 122 | + public $sortable = [ |
| 123 | + 'id', |
| 124 | + 'title', |
| 125 | + 'author', |
| 126 | + 'created_at', |
| 127 | + 'updated_at', |
| 128 | + ]; |
| 129 | + |
| 130 | + /** |
| 131 | + * Get the author associated with the post. |
| 132 | + */ |
| 133 | + public function author() |
| 134 | + { |
| 135 | + return $this->hasOne(\App\Models\Author::class); |
| 136 | + } |
| 137 | + ... |
| 138 | +} |
| 139 | +``` |
| 140 | + |
| 141 | +And you can use the relation in views: |
| 142 | + |
| 143 | +```blade |
| 144 | +// resources/views/posts/index.blade.php |
| 145 | +
|
| 146 | +@sortablelink('title', trans('general.title')) |
| 147 | +@sortablelink('author.name', trans('general.author')) |
| 148 | +``` |
| 149 | + |
| 150 | +> **Note**: In case there is a self-referencing model (like comments, categories etc.); parent table will be aliased with `parent_` string. |
| 151 | +
|
| 152 | +### Advanced Relation |
| 153 | + |
| 154 | +You can also extend the relation sorting feature by creating a function with `Sortable` suffix. There you're free to write your own queries and apply `orderBy()` manually: |
| 155 | + |
| 156 | +```php |
| 157 | +class User extends Model |
| 158 | +{ |
| 159 | + use Sortable; |
| 160 | + ... |
| 161 | + |
| 162 | + public $sortable = [ |
| 163 | + 'name', |
| 164 | + 'address', |
| 165 | + ]; |
| 166 | + |
| 167 | + public function addressSortable($query, $direction) |
| 168 | + { |
| 169 | + return $query->join('user_details', 'users.id', '=', 'user_details.user_id') |
| 170 | + ->orderBy('address', $direction) |
| 171 | + ->select('users.*'); |
| 172 | + } |
| 173 | + ... |
| 174 | +``` |
| 175 | + |
| 176 | +The usage in `controller` and `view` remains the same. |
| 177 | + |
| 178 | +### Aliasing |
| 179 | + |
| 180 | +You can declare the `$sortableAs` array in your model and use it to alias (bypass column exists check), and ignore prefixing with table: |
| 181 | + |
| 182 | +```php |
| 183 | +public $sortableAs = [ |
| 184 | + 'nick_name', |
| 185 | +]; |
| 186 | +``` |
| 187 | + |
| 188 | +In controller |
| 189 | + |
| 190 | +```php |
| 191 | +$users = $user->select(['name as nick_name'])->sortable(['nick_name'])->paginate(10); |
| 192 | +``` |
| 193 | + |
| 194 | +In view |
| 195 | + |
| 196 | +```blade |
| 197 | +@sortablelink('nick_name', 'nick') |
| 198 | +``` |
| 199 | + |
| 200 | +It's very useful when you want to sort results using [`withCount()`](https://laravel.com/docs/eloquent-relationships#counting-related-models). |
| 201 | + |
| 202 | +## Changelog |
| 203 | + |
| 204 | +Please see [Releases](../../releases) for more information what has changed recently. |
| 205 | + |
| 206 | +## Contributing |
| 207 | + |
| 208 | +Pull requests are more than welcome. You must follow the PSR coding standards. |
| 209 | + |
| 210 | +## Security |
| 211 | + |
| 212 | +Please review [our security policy](https://github.com/akaunting/laravel-sortable/security/policy) on how to report security vulnerabilities. |
| 213 | + |
| 214 | +## Credits |
| 215 | + |
| 216 | +- [Denis Duliçi](https://github.com/denisdulici) |
| 217 | +- [Martin Kiesel](https://github.com/Kyslik) |
| 218 | +- [All Contributors](../../contributors) |
| 219 | + |
| 220 | +## License |
| 221 | + |
| 222 | +The MIT License (MIT). Please see [LICENSE](LICENSE.md) for more information. |
0 commit comments