PHPackages                             internetguru/laravel-model-browser - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Admin Panels](/categories/admin)
4. /
5. internetguru/laravel-model-browser

ActiveLibrary[Admin Panels](/categories/admin)

internetguru/laravel-model-browser
==================================

A Laravel package to browse models and show them in a table, autocmplete, etc.

v4.1.0(2mo ago)02.8k↓50%1MITPHPPHP ^8.4CI passing

Since Oct 21Pushed 2mo ago2 watchersCompare

[ Source](https://github.com/internetguru/laravel-model-browser)[ Packagist](https://packagist.org/packages/internetguru/laravel-model-browser)[ RSS](/packages/internetguru-laravel-model-browser/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (16)Versions (93)Used By (1)

Laravel Model Browser
=====================

[](#laravel-model-browser)

A Laravel package to browse models and show them in cards, tables, etc.

BranchStatusCode CoverageMain[![tests](https://github.com/internetguru/laravel-model-browser/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/internetguru/laravel-model-browser/actions/workflows/test.yml/badge.svg?branch=main)[![coverage](https://raw.githubusercontent.com/internetguru/laravel-model-browser/refs/heads/badges/main-coverage.svg)](https://raw.githubusercontent.com/internetguru/laravel-model-browser/refs/heads/badges/main-coverage.svg)Staging[![tests](https://github.com/internetguru/laravel-model-browser/actions/workflows/test.yml/badge.svg?branch=staging)](https://github.com/internetguru/laravel-model-browser/actions/workflows/test.yml/badge.svg?branch=staging)[![coverage](https://raw.githubusercontent.com/internetguru/laravel-model-browser/refs/heads/badges/staging-coverage.svg)](https://raw.githubusercontent.com/internetguru/laravel-model-browser/refs/heads/badges/staging-coverage.svg)Dev[![tests](https://github.com/internetguru/laravel-model-browser/actions/workflows/test.yml/badge.svg?branch=dev)](https://github.com/internetguru/laravel-model-browser/actions/workflows/test.yml/badge.svg?branch=dev)[![coverage](https://raw.githubusercontent.com/internetguru/laravel-model-browser/refs/heads/badges/dev-coverage.svg)](https://raw.githubusercontent.com/internetguru/laravel-model-browser/refs/heads/badges/dev-coverage.svg)Installation
------------

[](#installation)

1. Install the package via Composer:

    ```
    # First time installation
    composer require internetguru/laravel-model-browser
    # For updating the package
    composer update internetguru/laravel-model-browser
    ```
2. Optionally publish the views and translations:

    ```
    php artisan vendor:publish --tag=views --provider="Internetguru\ModelBrowser\ModelBrowserServiceProvider"
    php artisan vendor:publish --tag=translations --provider="Internetguru\ModelBrowser\ModelBrowserServiceProvider"

    # If you want to publish everything, you can use the `--provider` option:
    php artisan vendor:publish --provider="Internetguru\ModelBrowser\ModelBrowserServiceProvider"
    ```

Run Tests Locally
-----------------

[](#run-tests-locally)

To run the tests manually, you can use the following command:

```
./test.sh
```

Basic Usage
-----------

[](#basic-usage)

Show the model browser in your views:

```

```

If no `viewAttributes` are provided, the model's fillable attributes are used by default.

Component Parameters
--------------------

[](#component-parameters)

Both `BaseModelBrowser` and `TableModelBrowser` accept the following parameters:

### `model` (required)

[](#model-required)

The Eloquent model class. Optionally specify a method (scope) to call on the model:

```
model="App\Models\User"
model="App\Models\User@summary"
```

### `viewAttributes`

[](#viewattributes)

Attributes displayed as columns/cards, mapped to their labels:

```
:viewAttributes="[
    'created_at' => __('summary.created_at'),
    'name' => __('summary.name'),
    'email' => __('summary.email'),
]"
```

### `formats`

[](#formats)

Formatting functions for attribute values. Each function receives `($value, $item)` and returns the formatted output (HTML is allowed). Values are passed as global function name strings:

```
:formats="[
    'created_at' => 'formatDateTime',
    'price' => 'formatCurrency',
    'symbol' => 'formatOrderSymbol',
    'payment_type' => 'formatTransactionPaymentType',
]"
```

Define the formatting functions as global helpers, e.g. in a `helpers.php` file:

```
function formatDateTime($order, $value)
{
    return \Carbon\Carbon::parse($value)->format('d.m.Y H:i');
}

function formatCurrency($order, $value)
{
    return number_format($value / 100, 2) . ' CZK';
}
```

### `alignments`

[](#alignments)

Column alignment settings (`start`, `end`, or `center`). Numeric values default to `end`, others to `start`:

```
:alignments="[
    'created_at' => 'start',
    'amount' => 'end',
    'is_active' => 'center',
]"
```

### `defaultSortColumn` / `defaultSortDirection`

[](#defaultsortcolumn--defaultsortdirection)

Default sort when user hasn't selected one:

```
defaultSortColumn="created_at"
defaultSortDirection="desc"
```

### `enableSort`

[](#enablesort)

Enable/disable interactive column sorting (default: `true`):

```
:enableSort="false"
```

### `filters` / `filterSessionKey`

[](#filters--filtersessionkey)

See the [Filters](#filters) section below. When using `filters`, `filterSessionKey` is required.

### `refreshInterval`

[](#refreshinterval)

Auto-refresh interval in seconds. When set, the component polls the server and re-renders with fresh data (including total count). Default: `0` (disabled):

```
:refreshInterval="10"
```

### TableModelBrowser-only Parameters

[](#tablemodelbrowser-only-parameters)

#### `lightDarkStep`

[](#lightdarkstep)

Controls alternating row shading in the table (default: `1`):

```
:lightDarkStep="2"
```

#### `columnWidths`

[](#columnwidths)

Custom CSS grid column widths per attribute. Defaults to `minmax(4em, 1fr)`:

```
:columnWidths="[
    'name' => 'minmax(8em, 2fr)',
    'email' => 'minmax(10em, 2fr)',
    'is_active' => '6em',
]"
```

Filters
-------

[](#filters)

The filter system provides a search bar with Gmail-style query syntax and an expandable filter panel. Filters are persisted in the session and can be initialized from URL query parameters.

### Configuration

[](#configuration)

Pass an associative array to the `filters` parameter. Each key is a filter attribute name, and each value is a config array:

```
:filters="[
    'from' => [
        'type' => 'date_from',
        'label' => 'From Date',
        'column' => 'created_at',
        'timezone' => 'Europe/Prague',
    ],
    'to' => [
        'type' => 'date_to',
        'label' => 'To Date',
        'column' => 'created_at',
        'timezone' => 'Europe/Prague',
    ],
    'symbol' => [
        'type' => 'string',
        'label' => 'Symbol',
        'column' => 'symbol',
        'rules' => 'nullable|string|max:20',
    ],
    'voucher' => [
        'type' => 'string',
        'label' => 'Voucher',
        'column' => 'ulid',
        'relation' => 'charges.voucher',
        'rules' => 'nullable|string|max:32',
        'url' => 'voucher',
    ],
    'priceFrom' => [
        'type' => 'number_from',
        'label' => 'Price From',
    ],
    'priceTo' => [
        'type' => 'number_to',
        'label' => 'Price To',
    ],
    'name' => [
        'type' => 'string',
        'label' => 'Customer',
        'column' => 'name',
        'relation' => 'customer',
    ],
]"
filterSessionKey="order-browser-filters"
```

Note that `priceFrom` and `priceTo` have no `column` key — they are not auto-applied and must be handled manually in the model scope (see [HasModelBrowserFilters Trait](#hasmodelbrowserfilters-trait)).

### Filter Config Keys

[](#filter-config-keys)

KeyDescription`type`Filter type: `string`, `number`, `date`, `date_from`, `date_to`, `number_from`, `number_to`, `options` (default: `string`). **Note:** `date_to` interprets date-only values (without an explicit time) as end-of-day (23:59:59), so e.g. `to:2026-02-16` includes all records on Feb 16. When a specific time is provided, it is used as-is.`label`Display label in the filter panel`column`Database column name for auto-apply. **When set**, the filter is automatically applied to the query. **When omitted**, the filter is NOT auto-applied — use `HasModelBrowserFilters` trait for manual access.`relation`Eloquent relation name — wraps the filter in `whereHas()`. Supports dot-notation for nested relations.`options`Array of options for the `options` type (e.g. `['value' => 'Label']`)`rules`Custom Laravel validation rules (overrides default type-based rules)`url`URL query parameter name to initialize the filter from (takes priority over session)`timezone`Timezone for date filters — the parsed date value is shifted via `Carbon::shiftTimezone($tz)` (e.g. `'Europe/Prague'`)### Search Query Syntax

[](#search-query-syntax)

The search bar supports Gmail-style syntax:

- **Free text**: `john` — searches across all `string`-type filter columns (with `column` set)
- **Specific filter**: `name:john` — applies to the `name` filter
- **Quoted values**: `name:"John Doe"` — for values containing spaces
- **Combined**: `name:john from:2025-01-01` — all terms must match (AND)

### Auto-applied vs Manual Filters

[](#auto-applied-vs-manual-filters)

Filters with a `column` key are **auto-applied** to the Eloquent query. Filters without `column` are stored in session but require manual application — useful for custom logic in model scopes:

```
// Auto-applied filter (no manual code needed):
'name' => ['type' => 'string', 'label' => 'Name', 'column' => 'name']

// Manual filter (applied in your model scope via HasModelBrowserFilters):
'priceFrom' => ['type' => 'number_from', 'label' => 'Price From']
```

Typical reasons to omit `column` and handle filtering manually:

- The filter operates on a computed/aggregate value (e.g. sum of related records)
- The filter needs custom OR logic across multiple relations
- The filter requires raw SQL expressions

### HasModelBrowserFilters Trait

[](#hasmodelbrowserfilters-trait)

Use this trait in your Eloquent model to access filter values from session for manual filtering. The `$modelBrowserFilterSessionKey` must match the `filterSessionKey` passed to the component.

```
use Internetguru\ModelBrowser\Traits\HasModelBrowserFilters;

class Order extends Model
{
    use HasModelBrowserFilters;

    protected string $modelBrowserFilterSessionKey = 'order_filter';

    public static function summary()
    {
        $query = static::with(['customer', 'payment', 'charges']);
        $filters = (new static)->getModelBrowserFilters();

        // Manual filter: price is a computed sum of related charges
        if ($priceFrom = $filters->get('priceFrom')) {
            $query->whereRaw(
                '(SELECT SUM(amount) FROM charges WHERE charges.order_id = orders.id) >= ?',
                [$priceFrom * 100]
            );
        }
        if ($priceTo = $filters->get('priceTo')) {
            $query->whereRaw(
                '(SELECT SUM(amount) FROM charges WHERE charges.order_id = orders.id)
