• Project Info
  • License
  • MIT
  • Version Released
  • May 26, 2021
  • Docs Built
  • May 30, 2021
  • Latest Version
  • main
  • Collaborators
  • luanf dansysanalyst
  • Tags
  • laravel livewire

PowerGrid Logo


Livewire PowerGrid

What is Livewire PowerGrid?

Livewire PowerGrid is a component for generating dynamic tables with your Laravel Models and Collections.


Get started


Requirements

Installation

This documentation will describe the creation of a table called ProductTable used to list products of the Product Model.

1. Via composer

To install via composer, run:

  composer require power-components/livewire-powergrid

2. Publish Config files

Publish the Livewire PowerGrid configuration file with the following command:

    php artisan vendor:publish --tag=livewire-powergrid-config

3. Publish files [OPTIONAL]

This step is OPTIONAL. Skip it if you don't need to customize Livewire PowerGrid.

Language files can be published with:

Views:

    php artisan vendor:publish --tag=livewire-powergrid-views

Language files can be published with:

    php artisan vendor:publish --tag=livewire-powergrid-lang

4. Configure the theme and Alpine JS

By default, PowerGrid uses Tailwind, Bootstrap 5 use.

4.1 your blade layout add jquery before bootstrap.js:

        <script src="https://code.jquery.com/jquery-3.6.0.slim.min.js"></script>

        <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.1/dist/js/bootstrap.bundle.min.js" integrity="sha384-gtEjrD/SeCtmISkJkNUaaKMoLD0//ElJ19smozuHV6z3Iehds+3Ulb9Bn9Plx0x4" crossorigin="anonymous"></script>
        
        <!-- after -->
        @powerGridScripts

This configuration can be changed in the file config/livewire-powergrid.php.

4.2 change config/livewire-powergrid.php:

    //...
    'theme' => 'bootstrap'

For Tailwind:

    //...
    'theme' => 'tailwind'

Alpine JS is not mandatory but it is required by features like "Click to edit" and "Toggable".

To activate it, open the file config/livewire-powergrid.php and modify the 'js_framework' setting replacing null with 'alpinejs'.

    //...
    'js_framework' => 'alpinejs',

The CDN for Alpine JS is configured by default, in the same file:

    //...
    'js_framework_cdn' => [
        'alpinejs' => 'https://cdn.jsdelivr.net/gh/alpinejs/alpine@v2.8.2/dist/alpine.min.js'
    ]

5. Include PowerGrid component

Include the Livewire and the PowerGrid styles and scripts:

...
    <!-- Styles -->
    @livewireStyles
    @powerGridStyles

   </head>
...
    <!-- Scripts -->
    @livewireScripts
    @powerGridScripts

</body>

You can read more about this at the official Livewire documentation


6. Creating a Table Component

To create a Table Component run powergrid:create informing your table name and your model.

Example:

php artisan powergrid:create ProductTable --model="App\Models\Product"  

you can also do it like this

php artisan powergrid:create Admin.ProductTable --model="App\Models\Product"
php artisan powergrid:create Admin\\ProductTable --model="App\Models\Product"

Output

(It's advisable to use "" around your --model option)

6.1 Create with Fillable

If your Model has the fillable property specified, use --fillable option to create columns based on its value.

php artisan powergrid:create ProductTable --model="App\Models\Product" --fillable

If everything was successful, you will find your new table component inside the app/Http/Livewire folder.

6.2 Create options

The command powergrid:create accepts the following options:

Option Description Example
--model Full model path --model="App\Models\Product"
--fillable Creates columns based on the Model's Fillable array --fillable
--template Uses a provided stub file as template for creating tables --template=stubs/table_with_buttons.sub
--with-collection Creates a table to work with collections --with-collection

7. Using your Table Component

The ProductTable component can be included in any view.

There are two ways to do that. Both work in the same way:

    <livewire:product-table/>

If your component lives is a sub-folder, for example Admin/ProductsTable.php:

    <livewire:admin-product-table/>

You can also use a blade directive:

  @livewire('product-table')

Configuring and Customizing

You can configure and customize your table component to adjust it to your needs.

You can view more functionalities consulting each of the following methods:

setUp() Method

The Setup method is used to configure your component.

Method Arguments Description Example
showCheckBox - Displays checkboxes on the table ->showCheckBox()
showPerPage Integer $perPage Items per page (Default 10) ->showPerPage()
showSearchInput - Shows the search input ->showSearchInput()
showRecordCount String $mode (min|short|full) Displays the records count ->showRecordCount('short')
showExportOption String download filename, Array options Displays export button and set custom name to exported file ->showExportOption('download', ['excel', 'csv])

Example of usage:

  public function setUp()
  {
      $this->showCheckBox()
      ->showRecordCount('short')
      ->showPerPage()
      ->showSearchInput()
      ->showExportOption('download', ['excel', 'csv']);
  }

NOTE

NOTE: In this version some things will change:

dataSource can now receive an instance of an eloquent models or a collection treated with PowerGrid::eloquent within the method.

a method has been added to work with column mutation.

_By default, powergrid will generate based on the eloquent model_

dataSource() Method

The dataSource() method is responsible for feeding data to your table.

It expects a model collection in the variable $model. Relationships can also be included.

model

public function dataSource() {
    
     return Product::query()->with('group'); // without get()
    
}

collection

public function dataSource() {

     return Product::query()->with('group')->get();
     
}

Here method is receiving all products with the relationship to groups.

For instance, the product "Mouse" belongs to "Computer" group, the product "A4 Paper" belongs to "Office Supplies" group.

addColumns() Method

Method Arguments Description Example
addColumn String $title, \Closure $closure Database field for this column ->addColumn('id')

Example of usage:

public function addColumns(): ?PowerGrid
{
    return PowerGrid::eloquent()
        ->addColumn('id')
        ->addColumn('name')
        ->addColumn('size')
    
        /** Group Relationship **/
        ->addColumn('group_id', function (Product $product) {
            return  $product->group_id;
        })
        ->addColumn('group_name', function (Product $product) {
            return  $product->group->name;
        })
        /** Active Boolean **/
        ->addColumn('is_active')
        ->addColumn('is_active_label', function (Product $product) {
            return ($product->is_active ? "active" : "inactive");
        })
        /** Price Format **/
        ->addColumn('price')
        ->addColumn('price_formatted', function(Product $product) {
            return  '$ ' . number_format($product->price, 2, ',', '.');
        })
        /** Created Date Format **/
        ->addColumn('created_at')
        ->addColumn('created_at_formatted', function(Product $product) {
          return Carbon::parse($product->created_at)->format('d/m/Y H:i');
        });
}

The data of each column can be manipulated with a closure function.

  ->addColumn('price') 
   //will output 1500.00

The example below brings the price formated.

  ->addColumn('price_formatted', function(Product $product) {
      return  '$ ' . number_format($product->price, 2, ',', '.');
    })
    //will output $ 1.500,00

The custom currency format should be converted back in the updated method as demonstrated below.

The column group_id is added for the relationship filter and the column group_name will bring the group data via the relationship.

    ->addColumn('group_id', function (Product $product) {
        return  $product->group_id;
    })
    ->addColumn('group_name', function (Product $product) {
        return  $product->group->name;
    })

Column Settings

These are the methods available on each column added with the Column class.

Method Arguments Result Example
add Add a new column Column::add()
field String $field Field name ->field('name')
title String $title Column title for the given field ->title('Product Name')
searchable Includes the column in the global search ->searchable()
sortable Includes column in the sortable list ->sortable()
hidden hides the column in the table ->hidden()
headerAttribute [String $class default: ''], [String $style default: ''] Add the class and style elements to the column header ->headerAttribute('text-center', 'color:red')
bodyAttribute [String $class default: ''], [String $style default: ''] Add the column lines the class and style elements ->bodyAttribute('text-center', 'color:red')
visibleInExport When true it will be invisible in the table and will show the column in the exported file ->visibleInExport(true)

Column Filters

These are the filters available for each column.

Method Arguments Result Example
makeInputText String $data_field Renders a textfield filter for the column ->makeInputText()
makeBooleanFilter String $data_field, String $trueLabel, String $falseLabel Filter for boolean columns ->makeBooleanFilter('is_active', 'active', 'inactive')
makeInputDatePicker [String $class default: 'col-3'] Include a specific field on the page to filter between the specific date in the column ->makeInputDatePicker()
makeInputSelect [Array $data_source, String $display_field, String $relation_id, Array $settings] Include a specific field on the page to filter a hasOne relation in the column ->makeInputSelect(Group::all(), 'name', 'group_id', ['live_search' => true ,'class' => ''])
makeInputMultiSelect $data_source, String $display_field, String $relation_id Include a specific field on the page to filter a hasOne relation in the column ->makeInputSelect(Group::all(), 'name', 'group_id'])
makeInputRange [string $data_field, String $thousands, String $decimal] Generates a min and max input for range filter. ->makeInputRange('price', '.', ',')

Column Actions

These are the actions available for each column.

Method Arguments Result Example
editOnClick bool $isEditable Allows the column to be editable by clicking on it (*requires Alpine.js) ->field('name')->editOnClick()
toggleable bool $isTogglable, String $trueLabel, String $falseLabel Renders a toggle control (ON/OFF) (*requires Alpine.js) ->field('is_active')->toggleable()
clickToCopy bool $hasPermission, string $label Renders a button for copying the cell contents ->field('name')->clickToCopy()

Example of usage:

The example below will render a column for the attribute name, with the title "Product Name". This column will be searchable by the main search field, will allow editing the values on click, and have its own input box filter on top.

    $canEdit = true; // this role has permission to edit

    Column::add()
        ->title(__('Product Name'))
        ->field('name')
        ->searchable()
        ->editOnClick($canEdit)
        ->clickToCopy()
        ->makeInputText()
        ->sortable(),

The next example will bring a column with the date formatted and with a date filter for it.

  Column::add()
      ->title('Creation date')
      ->field('created_at_formatted')  //Displays formatted data dd/mm/YYY to the user
      ->makeInputDatePicker('created_at') //Uses unformatted data
      ->searchable()

The example below renders a min-max amount filter and configures it to handle the custom currency formatting ($ 85.133,84). The method makeInputRange references the price attribute, while the column outputs the price_formatted.

  Column::add()
      ->title(__('US Price'))
      ->field('price_formatted')
      ->makeInputRange('price', '.', ','),

Boolean column example:

   $canEditStatus = true; // permission for editing
   
   Column::add()
      ->title(__('Status'))
      ->field('is_active')
      ->toggleable($canEditStatus, 'active', 'inactive') // Toggleable. If false, instead will render "active/inactive"
      ->makeBooleanFilter('is_active', 'active', 'inactive'), // Filter with "active/inactive" labels

NOTE

Performing data updating with features like clickToEdit and Toggleable will require you to have the update() method uncommented and configured. Alpine JS must be activated.


Action Methods

These methods are available on the Button class.

Method Arguments Result Example
add String $action Action name Button::add()
caption String $caption Label for the button ->caption('Edit Product')
class String $class_attr CSS class attribute ->class('bg-indigo-500 text-white')
openModal String $component, Array $params ->openModal('product', ['product' => 'id'])
method String $method Method for action (GET/POST/PUT/DELETE)) ->method('delete')
route String $route, Array $param Route for action ->route('product.edit', ['product' => 'id'])

Example of usage:

 return [
    Button::add('destroy')
        ->caption(__('Delete'))
        ->class('btn btn-danger')
        ->route('product.destroy', ['product' => 'id'])
        ->method('delete'),
  //...
];


Example of usage with modal component:

You will need to install the component Livewire UI Component

  • the first argument is within the openModal method is the name of the modal component

  • the second argument is an array of parameters where the key is field name in the modal component and the second is the name of the model field of this component

 return [
    Button::add('view')
        ->caption(__('View'))
        ->class('btn btn-primary')
        ->openModal('product', ['cod' => 'id']),
  //...
];

Update Method

The update method needs to be activated and configured for the edit on click and toggle to work.

All data sent by the user should go under validation and treatment. For instance, the user sends price_formatted with the value of $ 4.947,70 to update the Product price. The database has the field price and expects 44947.70. The developer must handle this data and point where to save it. Powergrid will not perform this conversion automatically. The same would happen with dates. See the two basic examples below:

public function update(array $product): bool
{

        /**
        * Reverts "price_formatted" to the database format and saves in the 'price' field.
        *  $ 4.947,70 --> 44947.70
        **/

        if ($data['field'] == 'price_formatted') {
              $data['field'] = 'price'; //Update the field price
              $data['value'] = Str::of($data['value'])
                ->replace('.', '')
                ->replace(',', '.')
                ->replaceMatches('/[^Z0-9\.]/', '');
        }

        /**
        *  Parses the date from d/m.Y (25/05/2021) 
        **/
         if ($data['field'] == 'created_at_formatted' && $data['value'] != '') {
            $data['field'] = 'created_at'; // Updates created_at
            $data['value'] =  Carbon::createFromFormat('d/m/Y', $data['value']);
         }

      try {
          $updated = Product::query()->find($product['id'])->update([
              $product['field'] => $product['value']
          ]);
      } catch (QueryException $exception) {
          $updated = false;
      }
      return $updated;
}

The update() method supports custom messages for each field.

To modify the displayed message after saving data, edit or add items on the updateMessages() method.

    public function updateMessages(string $status, string $field = '_default_message'): string
    {
        $updateMessages = [
            'success'   => [
              '_default_message' => __('Data has been updated successfully!'),
               //...
              'name' => __('Product name updated successfully!'), // Custom message for name field
              ],

            "error" => [
              '_default_message' => __('Error updating the data.'),
               //'custom_field' => __('Error updating custom field.'),
            ]

        ];

        return ($updateMessages[$status][$field] ?? $updateMessages[$status]['_default_message']);
    }


Discussions (1)

dilmurodq 3 weeks ago 2

Return value of powerGridJsFramework() must be of the type string, null returned (View: D:\Laravel Projects\teampro projects\parser_dashboard\vendor\power-components\livewire-powergrid\resources\views\assets\scripts.blade.php)




Add Discussion as Guest

Log in