Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Simple Tables Laravel Package

tiagospem/simple-tables

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps to First Use

  1. Install the Package

    composer require tiagospem/simple-tables
    php artisan st:install
    
  2. Generate a Table Component

    php artisan st:create table UsersTable
    

    This creates a Livewire component at app/Livewire/UsersTable.php.

  3. Define Columns In UsersTable.php, use the columns() method to define table columns:

    public function columns(): array
    {
        return [
            Column::make('Name', 'name'),
            Column::make('Email', 'email')
                ->sortable()
                ->searchable(),
        ];
    }
    
  4. Set the Data Source Override query() to return an Eloquent query builder:

    public function query(): Builder
    {
        return User::query();
    }
    
  5. Render the Table Add the component to a Blade view:

    @livewire('users-table')
    

First Use Case: Basic CRUD Table

  • Use columns() to display model attributes.
  • Leverage built-in pagination, sorting, and search.
  • Add actions via actions():
    public function actions(): array
    {
        return [
            Column::action('Edit', 'edit')
                ->icon('edit')
                ->url(fn ($row) => route('users.edit', $row)),
        ];
    }
    

Implementation Patterns

Core Workflows

  1. Data Binding

    • Use query() to bind an Eloquent query. The package handles pagination, sorting, and filtering automatically.
    • Example with relationships:
      public function query(): Builder
      {
          return User::with('roles')->query();
      }
      
  2. Column Customization

    • Sorting: Add ->sortable() to enable column sorting.
    • Searching: Add ->searchable() to enable global or column-specific search.
    • Formatting: Use ->format(fn ($value) => ...) to customize cell rendering.
      Column::make('Status', 'status')
          ->format(fn ($status) => $status === 'active' ? 'Active' : 'Inactive')
      
  3. Filters

    • Define filters in filters():
      public function filters(): array
      {
          return [
              Column::filter('Role')
                  ->select([
                      'admin' => 'Admin',
                      'user' => 'User',
                  ]),
          ];
      }
      
    • Use ->dependsOn() for dependent filters:
      Column::filter('Sub Role')
          ->select(fn ($query) => $query->where('role_id', $this->role))
          ->dependsOn('role')
      
  4. Row Actions

    • Add row-level actions via actions():
      public function actions(): array
      {
          return [
              Column::action('Delete', 'delete')
                  ->icon('trash')
                  ->confirmation('Are you sure?')
                  ->method('destroy'),
          ];
      }
      
    • Use ->url() for external links or ->method() for Livewire methods.
  5. Bulk Actions

    • Enable bulk actions with bulkActions():
      public function bulkActions(): array
      {
          return [
              Column::bulkAction('Delete Selected', 'deleteSelected')
                  ->icon('trash')
                  ->confirmation('Are you sure?'),
          ];
      }
      
    • Implement the method in the component:
      public function deleteSelected()
      {
          $this->selectedRows()->each->delete();
      }
      
  6. Row Details

    • Expand rows with details():
      public function details(): array
      {
          return [
              Column::detail('User Details')
                  ->content(fn ($row) => view('livewire.users.details', ['user' => $row])),
          ];
      }
      

Integration Tips

  • Laravel Scout: Integrate with Scout for search-as-you-type:
    public function query(): Builder
    {
        return User::search($this->search)->query();
    }
    
  • Livewire Hooks: Extend functionality using Livewire hooks:
    protected $listeners = ['refreshTable' => '$refresh'];
    
    public function updatedSearch()
    {
        $this->resetPage();
    }
    
  • Theming: Override Tailwind classes in resources/css/app.css or use the theme() method:
    public function theme(): string
    {
        return 'dark'; // or custom theme
    }
    

Gotchas and Tips

Pitfalls and Debugging

  1. Query Caching

    • Avoid caching the query result in query(); let the package handle pagination and filtering dynamically.
    • ❌ Bad:
      private $users;
      public function query(): Builder { return $this->users ??= User::all(); }
      
    • âś… Good:
      public function query(): Builder { return User::query(); }
      
  2. Relationship Loading

    • Eager-load relationships in query() to avoid N+1 queries:
      public function query(): Builder
      {
          return User::with('posts')->query();
      }
      
    • Access nested data in columns:
      Column::make('Post Count', fn ($row) => $row->posts->count())
      
  3. Filter Persistence

    • Filters persist across requests. Reset them explicitly if needed:
      public function resetFilters()
      {
          $this->reset(['role', 'search']);
      }
      
  4. Livewire Property Binding

    • Ensure filter properties are public or use public $property syntax:
      public $role;
      
    • ❌ Bad (private property won’t bind):
      private $role;
      
  5. Action Confirmation

    • Use ->confirmation() for destructive actions to avoid accidental triggers:
      Column::action('Delete', 'delete')
          ->confirmation('This action cannot be undone.')
      

Configuration Quirks

  1. Default Sorting

    • Set default sorting in query():
      public function query(): Builder
      {
          return User::query()->orderBy('name');
      }
      
    • Override via ->defaultSort() in columns:
      Column::make('Name', 'name')->defaultSort()
      
  2. Pagination

    • Customize pagination settings:
      public function pagination(): int
      {
          return 25; // Default is 10
      }
      
    • Disable pagination:
      public function pagination(): bool
      {
          return false;
      }
      
  3. Search Behavior

    • Global search vs. column search:
      • Global: Automatically added if any column has ->searchable().
      • Column-specific: Use ->searchable()->global(false).

Extension Points

  1. Custom Columns

    • Extend TiagoSpem\SimpleTables\Column for reusable column types:
      class StatusColumn extends Column
      {
          public function format($value)
          {
              return $value === 'active' ? 'Active' : 'Inactive';
          }
      }
      
    • Usage:
      StatusColumn::make('Status', 'status')
      
  2. Custom Filters

    • Create reusable filters by extending TiagoSpem\SimpleTables\Filter:
      class RoleFilter extends Filter
      {
          public function apply(Builder $query)
          {
              return $query->where('role_id', $this->value);
          }
      }
      
    • Usage:
      RoleFilter::make('Role')
          ->select(['admin' => 'Admin', 'user' => 'User'])
      
  3. Custom Themes

    • Override Tailwind classes or create a custom theme:
      public function theme(): string
      {
          return 'custom-theme';
      }
      
    • Define theme in resources/css/custom-theme.css.
  4. Event Listeners

    • Listen for table events (e.g., row selection, filter changes):
      protected $listeners = [
          'tableRowSelected' => 'handleRowSelected',
      ];
      
      public function handleRowSelected($row)
      {
          // Custom logic
      }
      
  5. API Integration

    • Fetch data via API by overriding getData():
      public function getData(): array
      {
          return Http::get('api/users')->json();
      }
      
    • Customize response handling for non-Eloquent data.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
emuniq/filament-browser-notifications
syriable/filament-translator
hungnm28/livewire-form
wenprise/eloquent
crudly/encrypted
fadion/bouncy
cuci/prototurk-sdk
gos/pubsub-router-bundle
cuci/prototurk-sdk-symfony
clementtalleu/easyadmin-markdown-bundle
codeflextech/permission-manager
karnoweb/livewire-datepicker
sayedenam/sayed-dashboard
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui