Skip to content

Commit 413654c

Browse files
author
Herbert Maschke
committed
introduce ability to pin specific records
1 parent 92e4a68 commit 413654c

File tree

5 files changed

+104
-20
lines changed

5 files changed

+104
-20
lines changed

README.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,30 @@ public function getExportStylesProperty()
314314
}
315315
```
316316

317+
### Pin Records
318+
319+
If you want to give your users the ability to pin specific records to be able to, for example, compare
320+
them with each other, you can use the CanPinRecords trait. Ensure to have at least one Checkbox Column
321+
so the user can select records:
322+
323+
```php
324+
use Mediconesystems\LivewireDatatables\Traits\CanPinRecords;
325+
326+
class RecordTable extends LivewireDatatable
327+
{
328+
use CanPinRecords;
329+
330+
public $model = Record::class;
331+
332+
public function columns()
333+
{
334+
return [
335+
Column::checkbox(),
336+
337+
// ...
338+
339+
```
340+
317341
### Custom column names
318342
It is still possible to take full control over your table, you can define a ```builder``` method using whatever query you like, using your own joins, groups whatever, and then name your columns using your normal SQL syntax:
319343

@@ -343,7 +367,6 @@ public function columns()
343367

344368
```
345369

346-
347370
### Callbacks
348371
Callbacks give you the freedom to perform any mutations you like on the data before displaying in the table.
349372
- The callbacks are performed on the paginated results of the database query, so shouldn't use a ton of memory
Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
11
<div class="flex justify-center">
2-
<input type="checkbox" wire:model="selected" value="{{ $value }}" class="form-checkbox mt-1 h-4 w-4 text-blue-600 transition duration-150 ease-in-out" />
2+
<input
3+
type="checkbox"
4+
wire:model="selected"
5+
value="{{ $value }}"
6+
@if (in_array($value, $this->pinnedRecords)) checked @endif
7+
class="w-4 h-4 mt-1 text-blue-600 form-checkbox transition duration-150 ease-in-out"
8+
/>
39
</div>

resources/views/livewire/datatables/datatable.blade.php

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -121,22 +121,7 @@ class="px-3 py-2 text-xs font-medium tracking-wider text-green-500 uppercase bg-
121121
@endif
122122
@endforeach
123123
</div>
124-
125-
<div class="table-row bg-blue-100 divide-x divide-blue-200">
126-
@foreach($this->columns as $index => $column)
127-
@if($column['hidden'])
128-
@if($hideable === 'inline')
129-
<div class="table-cell w-5 overflow-hidden align-top bg-blue-100"></div>
130-
@endif
131-
@elseif($column['type'] === 'checkbox')
132-
@include('datatables::filters.checkbox')
133-
@endunless
134-
@else
135-
@include('datatables::header-no-hide', ['column' => $column, 'sort' => $sort])
136-
@endif
137-
@endforeach
138-
</div>
139-
124+
@endunless
140125
<div class="table-row bg-blue-100 divide-x divide-blue-200">
141126
@foreach($this->columns as $index => $column)
142127
@if($column['hidden'])
@@ -166,7 +151,6 @@ class="px-3 py-2 text-xs font-medium tracking-wider text-green-500 uppercase bg-
166151
@endif
167152
@endforeach
168153
</div>
169-
@endif
170154
@forelse($this->results as $row)
171155
<div class="table-row p-1 {{ $this->rowClasses($row, $loop) }}">
172156
@foreach($this->columns as $column)

src/Http/Livewire/LivewireDatatable.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@ public function applyToTable($options)
151151
'activeNumberFilters',
152152
'hide',
153153
'selected',
154+
'pinnedRecords',
154155
] as $property) {
155156
if (isset($options[$property])) {
156157
$this->$property = $options[$property];
@@ -178,6 +179,9 @@ public function resetTable()
178179
$this->hide = null;
179180
$this->resetHiddenColumns();
180181
$this->selected = [];
182+
if (isset($this->pinnedRecords)) {
183+
$this->pinnedRecords = [];
184+
}
181185
}
182186

183187
/**
@@ -245,6 +249,10 @@ public function mount(
245249
$this->initialisePerPage();
246250
$this->initialiseColumnGroups();
247251
$this->model = $this->model ?: get_class($this->builder()->getModel());
252+
253+
if (isset($this->pinnedRecords)) {
254+
$this->initialisePinnedRecords();
255+
}
248256
}
249257

250258
// save settings
@@ -1502,6 +1510,9 @@ public function addTimeRangeFilter()
15021510
public function addSort()
15031511
{
15041512
if (isset($this->sort) && isset($this->freshColumns[$this->sort]) && $this->freshColumns[$this->sort]['name']) {
1513+
if (isset($this->pinnedRecords) && $this->pinnedRecords) {
1514+
$this->query->orderBy(DB::raw('FIELD(id,' . implode(',', $this->pinnedRecords) . ')'), 'DESC');
1515+
}
15051516
$this->query->orderBy(DB::raw($this->getSortString()), $this->direction ? 'asc' : 'desc');
15061517
}
15071518

@@ -1793,6 +1804,5 @@ public function massActionOptionHandler()
17931804
}
17941805

17951806
$this->massActionOption = null;
1796-
$this->selected = [];
17971807
}
17981808
}

src/Traits/CanPinRecords.php

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
namespace Mediconesystems\LivewireDatatables\Traits;
4+
5+
use Mediconesystems\LivewireDatatables\Action;
6+
7+
/**
8+
* Use this trait to enable the functionality to pin specific records to the
9+
* top of the table.
10+
*
11+
* Ensure to;
12+
*
13+
* 1) have at least one Checkbox Column in your table
14+
* 2) have session storage activated (it is by default)
15+
* 3) to enable the mass bulk action dropdown as described in:
16+
*
17+
* @link https://github.com/MedicOneSystems/livewire-datatables#mass-bulk-action
18+
*/
19+
trait CanPinRecords
20+
{
21+
public array $pinnedRecords = [];
22+
23+
public string $sessionKeyPrefix = '_pinned_records';
24+
25+
public function buildActions()
26+
{
27+
return array_merge(parent::buildActions() ?? [], [
28+
Action::value('pin')
29+
->label(__('Pin selected Records'))
30+
->callback(function ($mode, $items) {
31+
$this->pinnedRecords = array_merge($this->pinnedRecords, $items);
32+
$this->selected = $this->pinnedRecords;
33+
34+
session()->put($this->sessionKey(), $this->pinnedRecords);
35+
}),
36+
37+
Action::value('unpin')
38+
->label(__('Unpin selected Records'))
39+
->callback(function ($mode, $items) {
40+
$this->pinnedRecords = array_diff($this->pinnedRecords, $items);
41+
$this->selected = $this->pinnedRecords;
42+
43+
session()->put($this->sessionKey(), $this->pinnedRecords);
44+
}),
45+
]);
46+
}
47+
48+
protected function initialisePinnedRecords()
49+
{
50+
if (session()->has($this->sessionKey())) {
51+
$this->pinnedRecords = session()->get($this->sessionKey());
52+
}
53+
54+
$this->selected = $this->pinnedRecords;
55+
}
56+
57+
private function sessionKey(): string
58+
{
59+
return $this->sessionStorageKey() . $this->sessionKeyPrefix;
60+
}
61+
}

0 commit comments

Comments
 (0)