laravel-datatables-html icon indicating copy to clipboard operation
laravel-datatables-html copied to clipboard

Ability to use static data (no server-side)

Open OzanKurt opened this issue 1 year ago • 6 comments

I recently wanted to use the package for a "array based datatable".

Sadly when I do;

{!! $dataTable->table() !!}

it doesn't generate the tables body.

I added some logic to the Builder class so that we can make it fill the tbody IF the serverSide option is disabled.

Here is an example DataTable I've prepared along with 2 methods makingRowExample and makingCellExample explaining how the Row and Cell classes apis work. I tried to make things similar to the Column class which we already.

There area a couple important places I've marked via comments inside the code.

<?php

namespace App\DataTables;

use App\DataTables\Core\Html\Column;
use App\Models\User;
use Yajra\DataTables\Html\Builder;
use Yajra\DataTables\Html\Cell;
use Yajra\DataTables\Html\Row;
use Yajra\DataTables\Services\DataTable;

class ExampleStaticDataTable extends DataTable
{
    // IMPORTANT: 
    // You can name this method whatever you want, it will simply allow you to populate the rows data
    public function buildRows()
    {
        $users = User::query()->get();

        $rows = [];

        /** @var User $user */
        foreach ($users as $user) {
            $rows[] = [
                'full_name' => $user->full_name,
                'email' => $user->email,
                'created_at' => $user->created_at?->format('Y-m-d H:i:s') ?? 'N/A',
            ];
        }

        return $rows;
    }

    // IMPORTANT: 
    // Here we call the `rows(array $rows = [])` method on the `Builder` instance
    // set the `serverSide` attribute to `false`
    public function html(): Builder
    {
        return $this
            ->builder()
            ->rows($this->buildRows())
            ->serverSide(false);
    }

    public function getColumns(): array
    {
        return [
            Column::make('full_name'),
            Column::make('email'),
            Column::make('created_at'),
        ];
    }

    // IMPORTANT: 
    // Example usages of the Row api
    public function makingRowExample()
    {
        // Option 1:
        //      If your row doesn't have any attributes,
        //      you can directly use array for its cells.
        $rowExample1 = [
            // Cells here...
        ];

        // Option 2:
        //      If your row has attributes,
        //      you must put the cells to the `cells` key.
        $rowExample2 = [
            'row-class' => 'gray-row',
            'cells' => [
                // Cells here...
            ],
        ];

        // Option 3:
        //      If your row has no attributes,
        //      leave the first parameter as an empty array.
        $rowExample3 = Row::make([
            'row-class' => 'gray-row',
        ], [
            // Cells here...
        ]);
        $rowExample4 = Row::make([
            'row-class' => 'gray-row',
        ])->cells([
            // Cells here...
        ]);
    }

    // IMPORTANT: 
    // Example usages of the Cell api
    public function makingCellExample()
    {
        // Option 1 - Directly inside Row array as `key => value` pairs
        $cellExample1_1 = [
            'column_1' => 'Column #1 Content',
            'column_2' => 'Column #2 Content',
        ];
        $cellExample1_2 = [
            'cells' => [
                'column_1' => 'Column #1 Content',
                'column_2' => 'Column #2 Content',
            ],
        ];

        // Option 2 - Using array
        $cellExample2 = [
            'column' => 'column_1',
            'content' => 'Column #1 Content',
        ];

        // Option 3 - Using Cell Object
        $cellExample3_1 = Cell::make('column_1', 'Column #1 Content');
        $cellExample3_2 = Cell::make('column_1')->content('Column #1 Content');
    }
}

OzanKurt avatar Aug 08 '24 04:08 OzanKurt

Hello @yajra ,

Could you please have a look at this and share me your feedback?

Here I also added the basic usage of the datatable for the controller and the blade parts.

class TestController extends Controller
{
    public function test()
    {
        $dataTable = new ExampleStaticDataTable();

        return view('test')->with([
            'dataTable' => $dataTable->html(),
        ]);
    }
}
{!! $dataTable->table() !!}
{!! $dataTable->scripts() !!}

OzanKurt avatar Aug 08 '24 05:08 OzanKurt

hey @yajra, could you please review this?

1190 avatar Aug 10 '24 23:08 1190

@OzanKurt this is a great feature, thanks for sending the PR. I will test this as soon as I can.

One thing I noticed is that maybe we can simplify the syntax further by setting serverSide: false by default when rows are used.

    public function html(): Builder
    {
        return $this
            ->builder()
            ->rows($this->buildRows()) -- calling this will set serverSide to false
            ->serverSide(false); -- so we can remove this line
    }

yajra avatar Aug 11 '24 03:08 yajra

Automatically calling serverSide(false) makes so much sense!

In addition to this I am currently working on the option to load the initial data from ajax while having serverSide(false).

I will send a new update in a couple days.

OzanKurt avatar Aug 11 '24 03:08 OzanKurt

Thanks for the updates, let me know if this is ready for review again.

yajra avatar Aug 17 '24 04:08 yajra