1. Go to this page and download the library: Download unnathianalytics/laragrid library. Choose the download type require.
2. Extract the ZIP file and open the index.php.
3. Add this code to the index.php.
<?php
require_once('vendor/autoload.php');
/* Start to develop here. Best regards https://php-download.com/ */
unnathianalytics / laragrid example snippets
use App\Models\Resort;
use LaraGrid\Actions\Action;
use LaraGrid\Aggregate;
use LaraGrid\Columns\{SerialColumn, TextColumn, IntegerColumn, DateColumn, ComputedColumn};
use LaraGrid\Filters\SelectFilter;
use LaraGrid\Grid;
use LaraGrid\Livewire\WithLaraGrid;
use LaraGrid\Support\CellHtml;
use Livewire\Component;
class ResortsIndex extends Component
{
use WithLaraGrid; // ← see note below
->filters([
SelectFilter::make('type')->label('Type')
->options(fn () => Resort::distinct()->orderBy('type')->pluck('type', 'type')),
SelectFilter::make('visibility')->label('Visibility')
->options(['show' => 'Show', 'hide' => 'Hide']),
])
->columns([
SerialColumn::make(),
TextColumn::make('name')->label('Resort')->sortable()->searchable()->grow(),
TextColumn::make('type')->sortable()->width(120),
IntegerColumn::make('hits')->sortable()->width(90),
ComputedColumn::make('status')->html()->width(90)
->state(fn (array $row) => $row['visibility'] === 'show'
? CellHtml::badge('green', 'Show')
: CellHtml::badge('zinc', 'Hide')),
DateColumn::make('created_at')->label('Added')->sortable()->width(110),
])
->footer([Aggregate::sum('hits')->format('number')])
->exportable(['csv', 'xlsx', 'pdf']) // toolbar Export control — see Exports
->actions([
Action::make('edit')->icon('✎')->url(fn ($row) => route('resorts.edit', $row['id'])),
Action::make('delete')->icon('✕')->confirm('Delete this resort?')
->call(fn (array $row) => Resort::whereKey($row['id'])->delete()),
])
->stickyHeader()->striped()->maxHeight('70vh')];
}
public function render()
{
return view('livewire.resorts-index');
}
}
use LaraGrid\Columns\{SerialColumn, SearchSelectColumn, IntegerColumn, DecimalColumn, FormulaColumn, TextColumn};
use LaraGrid\Editing\RowContext;
class BookingEntry extends Component
{
use WithLaraGrid;
/** @var list<array<string, mixed>> */
public array $lines = [];
public function mount(): void
{
$this->lines = $this->gridMountRows('lines'); // seeds defaultRows via the factory
}
protected function grids(): array
{
return ['lines' => Grid::make('lines')
->editable()
->rowsFrom('lines') // binds public array $lines
->authorize(fn () => $this->authorize('booking.create'))
->defaultRows(3)
->newRowUsing(fn () => ['nights' => 1]) // template for seeded AND inserted rows
->minRows(1)
->autoAppend() // Enter past the last cell grows the grid
->persistDraft('local', 'booking:new') // opt-in IndexedDB crash/reload recovery
->focusOnMount()
->focusOutTo('[data-save]') // Tab past the last cell lands on Save
->columns([
SerialColumn::make(),
SearchSelectColumn::make('resort_id')->label('Resort')
->optionsUsing(fn (string $term) => Resort::query()
->when($term !== '', fn ($q) => $q->where('name', 'like', "%{$term}%"))
->limit(50)->get(['id', 'name'])
->map(fn ($r) => ['value' => (string) $r->id, 'label' => $r->name])
->all())
->onSelect(function (RowContext $row, mixed $value): void {
// Enrichment: the pick pre-fills the rate; write-backs reconcile
// into the client row automatically.
$row->set('rate', Resort::whereKey($value)->value('comparison_tariff'));
})
->
SearchSelectColumn::make('item_id')
->endOfListOption() // default label: <-- End of List -->
// ->endOfListOption('— Done adding lines —') // custom label
// ->endOfListOption(allowOnEmpty: true) // offer it even on an empty grid
Grid::make('lines')
->editable()->rowsFrom('lines')->autoAppend()
->focusOutTo('[data-save]') // operator tabs off the end → Save
->onCompleteFocus('[data-save]') // operator picks "End of List" → lgrid:complete + Save
// 1. Per-pick enrichment (SearchSelectColumn): the pick pre-fills dependent cells.
SearchSelectColumn::make('item_id')
->onSelect(function (RowContext $row, mixed $value): void {
$item = Item::find($value);
$row->set('rate', $item?->rate);
$row->set('uom', $item?->uom);
})
// 2. Grid-wide row consistency: runs after EVERY applied cell change (typing, paste,
// fill-down). Example — derive nights from a date range:
->afterCellChange(function (RowContext $row, string $column): void {
if (! in_array($column, ['fromDate', 'toDate'], true)) {
return;
}
if ($row->get('fromDate') && $row->get('toDate')) {
$nights = Carbon::parse($row->get('fromDate'))
->diffInDays(Carbon::parse($row->get('toDate')), false);
$row->set('nights', $nights >= 1 ? (int) $nights : null);
}
})
// 3. After a row removal — recompute host-side chrome (an "Allocated" total, a balance badge):
->afterRowRemove(fn () => $this->recomputeTotals())
TextColumn::make('type')->hiddenByDefault()
use LaraGrid\Columns\FocusMode;
// Variable (Default): Always receives sequential keyboard focus
TextColumn::make('party_name')
->focusMode(FocusMode::Always);
// Semi-Variable: Skipped on keyboard navigation (Tab/Enter), focusable and editable on mouse click
DecimalColumn::make('qty')
->focusMode(FocusMode::Manual, default: 1);
// Fixed: Skipped on keyboard navigation, read-only / non-editable, dynamic Closure default
DateColumn::make('vch_date')
->focusMode(FocusMode::Never, default: fn () => now()->format('Y-m-d'));
->actions([ // per-row buttons in a trailing column
Action::make('edit')->icon('✎')->url(fn ($row) => route('items.edit', $row['id'])),
Action::make('archive')->confirm('Archive?')->visible(fn ($row) => ! $row['archived'])
->call(fn (array $row) => Item::whereKey($row['id'])->archive()),
])
->bulkActions([ // run over checked rows; a selector gutter + toolbar bulk bar appear
Action::make('delete')->confirm('Delete selected?')
->call(fn (array $keys) => Item::whereKey($keys)->delete()),
])
->toolbarActions([ // grid-scoped buttons in the toolbar
Action::make('new')->label('New Item')->url(fn () => route('items.create')),
])
Grid::make('resorts')
->query(fn () => Resort::query())
->authorize('resort.viewAny')
->exportable() // csv + xlsx + pdf (the config default set)
// ->exportable(['csv', 'xlsx']) // or exactly these formats
// ->exportable(['csv'], fileName: 'resorts', limit: 10000)
use App\Models\Voucher;
use LaraGrid\Columns\{DateColumn, DecimalColumn, SerialColumn, TextColumn};
use LaraGrid\Grid;
use LaraGrid\Livewire\WithLaraGrid;
use Livewire\Component;
class DayBook extends Component
{
use WithLaraGrid;
/** Rows built for the normal in-memory screen. */
public array $rows = [];
public string $from = '';
public string $to = '';
protected function grids(): array
{
return ['dayBook' => $this->dayBookGrid()];
}
protected function dayBookGrid(): Grid
{
return Grid::make('dayBook')
->authorize(fn () => $this->authorize('viewAny', Voucher::class))
->exportRows(fn (array $state): iterable => $this->dayBookExportRows($state))
->exportable(['csv', 'xlsx', 'pdf'], fileName: 'day-book')
->columns([
SerialColumn::make(),
DateColumn::make('date')->sortable(),
TextColumn::make('type')->sortable(),
TextColumn::make('voucher')->sortable(),
TextColumn::make('ledger'),
DecimalColumn::make('debit')->scale(2),
DecimalColumn::make('credit')->scale(2),
]);
}
/**
* $state is exactly {sort, dir, search, filters}; unknown client keys and invalid
* sort/filter targets have already been removed. Apply the intents your report supports.
*/
protected function dayBookExportRows(array $state): iterable
{
// Component report filters such as $this->from/$this->to are already trusted server
// state on this rehydrated Livewire component. Re-query and transform independently.
foreach ($this->reportBuilder($this->from, $this->to)->lazyEntries() as $voucher) {
foreach ($this->movePartyEntryFirst($voucher) as $row) {
yield $row; // generators keep the export pipeline bounded-memory
}
}
}
public function render()
{
return view('livewire.day-book');
}
}
// A service provider:
app(\LaraGrid\Export\ExporterRegistry::class)->register('pdf', new BrandedDompdfExporter);
app(\LaraGrid\Export\ExporterRegistry::class)->register('ods', new OdsExporter);
// A grid:
->exportable(['csv', 'ods']) // unknown names still fail loudly at build time
Grid::make('items')
->query(fn () => Item::query())
->authorize('item.viewAny')
->persistQuery() // opt-in; ->persistQuery('session', 'key') overrides the key
->persistWidths() // composes — different lifetime, different state
->persistQuery(key: "items:{$companyId}")
$this->forgetGridQuery('items'); // no-op on a grid without ->persistQuery()
Grid::make('items')->theme('blue') // per grid (unknown names fail loud at build time)
// config/laragrid.php — app-wide default; any grid's ->theme() overrides it
'theme' => 'emerald',
// A custom column type is just a class:
class RatingColumn extends \LaraGrid\Columns\Column
{
public function painterId(): string { return 'rating'; }
public function editorId(): ?string { return 'rating'; }
public function parseSpec(): array { return ['kind' => 'int']; }
}
// App-specific formatters and parse kinds register in a service provider:
app(\LaraGrid\Formatting\FormatRegistry::class)->register('inr', new InrFormatter);
app(\LaraGrid\Casting\CastRegistry::class)->register('paise', new PaiseCast);