summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--resources/views/table.blade.php36
-rw-r--r--src/Columns/Column.php55
-rw-r--r--src/TableComponent.php65
3 files changed, 129 insertions, 27 deletions
diff --git a/resources/views/table.blade.php b/resources/views/table.blade.php
index 1938b48..5f6df75 100644
--- a/resources/views/table.blade.php
+++ b/resources/views/table.blade.php
@@ -1,4 +1,40 @@
<div>
+ <div class="table-controls pb-2 d-flex justify-content-between align-items-center">
+ @if($searchable)
+ <div>
+ <input class="form-control border-secondary" type="search"
+ wire:model.live.debounce.{{ $searchDebounce}}="search"
+ placeholder="{{ __('Search') }}..." />
+ </div>
+ @endif
+ <div class="d-flex gap-3">
+ @if($showColumnSelect)
+ <div class="dropdown">
+ <button type="button" class="btn btn-outline-secondary border-secondary"
+ data-bs-toggle="dropdown" aria-expanded="false"
+ data-bs-auto-close="outside">
+ {{ __('Columns') }}
+ </button>
+ <div class="dropdown-menu p-4">
+ @foreach($allColumns->filter(fn($c) => $c->getShowInSelect()) as $column)
+ <label class="d-block">
+ <input type="checkbox" wire:model.live="activeColumns"
+ value="{{ $column->name }}" />
+ {{ $column->title }}
+ </label>
+ @endforeach
+ </div>
+ </div>
+ @endif
+ @if($showPageSizeSelect)
+ <select wire:model.live="pageSize" class="form-select border-secondary">
+ @foreach($pageSizes as $size)
+ <option value="{{ $size }}">{{ $size }}</option>
+ @endforeach
+ </select>
+ @endif
+ </div>
+ </div>
<table class="table">
<thead>
<tr>
diff --git a/src/Columns/Column.php b/src/Columns/Column.php
index 7b9f248..f3fe811 100644
--- a/src/Columns/Column.php
+++ b/src/Columns/Column.php
@@ -2,40 +2,48 @@
namespace Lightscale\LaralightTables\Columns;
+use Lightscale\LaralightTables\TableComponent;
+
use Illuminate\Database\Eloquent\Model;
use Illuminate\View\ComponentAttributeBag;
+use Illuminate\Support\HtmlString;
use Closure;
class Column {
private TableComponent $table;
+ private bool $showInSelect;
- private Closure $displayFn;
+ private ?Closure $slotFn = null;
private ?Closure $sortFn = null;
- private ?Closure $searchFn = null;
- private ?Closure $attributesFn = null;
+ private ?Closure $tdAttributesFn = null;
public function __construct(
public string $name,
- public string $title
+ public ?string $title = null
) {
- $this->displayFn = Closure::fromCallable([$this, 'defaultDisplay']);
+ $this->showInSelect = $this->title !== null;
}
- public static function make(string $name, $title) : static
+ public static function make(string $name, ?string $title = null) : static
{
return new static($name, $title);
}
- private function defaultDisplay(Model $row, Column $column)
+ public function setTable(TableComponent $table) : void
+ {
+ $this->table = $table;
+ }
+
+ private function defaultSlot(Model $row)
{
- return $row->{$column->name};
+ return $row->{$this->name};
}
- public function display(callable $fn) : static
+ public function slot(callable $fn) : static
{
- $this->displayFn = Closure::fromCallable($fn);
+ $this->slotFn = Closure::fromCallable($fn);
return $this;
}
@@ -45,24 +53,33 @@ class Column {
return $this;
}
- public function searchable(callable $fn) : static
+ public function tdAttributes(callable $fn) : static
{
- $this->searchFn = Closure::fromCallable($fn);
+ $this->tdAttributesFn = Closure::fromCallable($fn);
return $this;
}
- public function attributes(callable $fn) : static
+ public function showInSelect($show = true)
{
- $this->attributesFn = Closure::fromCallable($fn);
- return $this;
+ $this->showInSelect = $show;
+ }
+
+ public function getShowInSelect()
+ {
+ return $this->showInSelect;
+ }
+
+ protected function getContent(Model $row)
+ {
+ return $this->slotFn?->call($this, $row, $this) ?? $this->defaultSlot($row);
}
public function view(Model $row)
{
- $attributes = $this->attributesFn?->call($this, $row) ?? [];
- $attributes = new ComponentAttributeBag($attributes);
- $content = $this->displayFn->call($this, $row, $this);
- return view('laralight-tables::column', compact('attributes', 'content'));
+ $attributes = $this->tdAttributesFn?->call($this, $row) ?? [];
+ $attributes = (new ComponentAttributeBag($attributes))->toHtml();
+ $content = $this->getContent($row);
+ return new HtmlString("<td {$attributes}>{$content}</td>");
}
}
diff --git a/src/TableComponent.php b/src/TableComponent.php
index e530415..04d457e 100644
--- a/src/TableComponent.php
+++ b/src/TableComponent.php
@@ -6,7 +6,7 @@ use Livewire\Component;
use Livewire\WithPagination;
use Illuminate\Database\Eloquent\Builder;
-use Illuminate\Database\Eloquent\Model;
+use Illuminate\Support\Str;
use Exception;
@@ -14,10 +14,34 @@ abstract class TableComponent extends Component
{
use WithPagination;
+ // Config
protected $paginationTheme = 'bootstrap';
protected bool $searchable = true;
+ protected int $searchMinLength = 2;
+ protected int $searchDebounce = 250;
+ protected bool $showPageSizeSelect = true;
+ protected bool $showColumnSelect = true;
- protected Model $model = null;
+ protected array $pageSizes = [10, 25, 50];
+
+ protected $model = null;
+
+ // Properties
+ public string $search = '';
+ public int $pageSize = 0;
+ public array $activeColumns = [];
+
+ public function __construct()
+ {
+ $this->pageSize = $this->pageSizes[0] ?? 0;
+ }
+
+ public function mount()
+ {
+ foreach($this->getColumns() as $column) {
+ $this->activeColumns[] = $column->name;
+ }
+ }
protected function query() : Builder
{
@@ -37,19 +61,44 @@ abstract class TableComponent extends Component
return [];
}
- protected buildQuery() : Builder
+ protected function buildQuery() : Builder
{
$query = $this->query();
+
+ if($this->searchable && (Str::length($this->search) >= $this->searchMinLength)) {
+ $this->search($query, $this->search);
+ }
+
+ return $query;
+ }
+
+ protected function getColumns()
+ {
+ static $columns = null;
+
+ if($columns === null) {
+ $columns = collect($this->columns())->each(
+ fn($c) => $c->setTable($this)
+ );
+ }
+
+ return $columns;
}
public function render()
{
- $this->buildQuery()->paginate();
- $data = $query->paginate($this->pageSize);
- $columns = $this->columns();
+ $data = $this->buildQuery()->paginate($this->pageSize);
+ $allColumns = $this->getColumns();
+ $columns = $allColumns->filter(fn($c) => in_array($c->name,$this->activeColumns));
- return view('laralight-tables::table', compact(
- 'data', 'columns'
+ return view('laralight-tables::table', [
+ 'searchable' => $this->searchable,
+ 'searchDebounce' => $this->searchDebounce,
+ 'showPageSizeSelect' => $this->showPageSizeSelect,
+ 'showColumnSelect' => $this->showColumnSelect,
+ 'pageSizes' => $this->pageSizes,
+ ] + compact(
+ 'data', 'allColumns', 'columns'
));
}
}