# DataGrid

# Introduction

A DataGrid is a powerful tool for displaying database records in a tabular format, making it easier to present and manage large amounts of data in an organized manner. In Bagisto, the DataGrid feature enables you to display data efficiently, with built-in functionalities like sorting, filtering, and mass actions. These additional features enhance the basic functionality of DataGrid, allowing you to interact with and manage data seamlessly. Whether you use the pre-built DataGrid or write your own custom implementation, Bagisto’s DataGrid provides a robust solution for data presentation and manipulation.

# Global Properties of DataGrid

The DataGrid in Bagisto has several global properties that enhance its functionality and customization. Below are the key properties and their purposes:

Property Functionality
primaryColumn The value assigned to this property must be unique, typically the primary key like id, so that data will be uniquely identified and operations performed will be based on your index value.
queryBuilder This is used to perform database operations in your application.
columns This contain array values of column in the DataGrid.
sortOrder The sortOrder key is used to arrange the results in ascending or descending order.
actions This contain all the data related to the action of DataGrid.
massActions This contain all the data related to the mass action of DataGrid.
paginator The paginate property used to contain paginator instance.
itemsPerPage The itemsPerPage key is used to display the number of items per page.

# How DataGrid Works

The DataGrid abstract class is created in the Webkul\DataGrid package. In the abstract class, a list of properties and methods are declared. To create your own DataGrid, you need to extend the Webkul\DataGrid\DataGrid abstract class.

In Webkul\DataGrid\DataGrid\DataGrid.php abstract class, two abstract methods are declared prepareQueryBuilder() and prepareColumns(). You can prepare your grid by defining these two methods.

  • prepareQueryBuilder(): In this method, records are retrieved through queries applicable to the database and stored in a collection. When records are retrieved, the setQueryBuilder() method is called.

    public function prepareQueryBuilder()
    {
        $queryBuilder = DB::table('posts')
            ->select('id', 'title', 'status', 'created_at', 'updated_at');
    
        return $queryBuilder;
    }
    
  • prepareColumns(): In this method, columns are created which are displayed in the grid. The parameter accepts an array in key-value pairs. Some of the essential keys are described below:

    Key Functionality
    index This key is defined in the grid, and the value assigned to this is a column.
    label This key accepts the label of the column.
    type This key accepts the type of data in the column.
    searchable This accepts boolean values true or false to make the column searchable.
    sortable This accepts boolean values true or false to make the column sortable.
    filterable This accepts boolean values true or false to make the column filterable.
    closure Perform actions based on a condition satisfied or apply some customization to the value.
    public function prepareColumns()
    {
        $this->addColumn([
            'index'      => 'id',
            'label'      => trans('blog::app.admin.datagrid.id'),
            'type'       => 'integer',
            'searchable' => false,
            'sortable'   => true,
            'filterable' => true
        ]);
    }
    
  • prepareActions(): This method is defined when there is a need to perform any action such as edit or delete on the grid. In this method, the addAction() method is called to define a particular action.

  • addAction(): This method is used for adding actions (like edit, delete, etc.) to each row generated by the DataGrid.

    Key Functionality
    icon This key accept class of your icon.
    title This key accept title of action column.
    method This key accept HTTP methods to perform specific action(GET/DELETE).
    url This key accepts the route of the specific action.
    public function prepareActions()
    {
        $this->addAction([
            'icon'   => 'icon-edit'
            'title'  => trans('blog::app.admin.datagrid.edit'),
            'method' => 'GET',
            'url'    => function ($row) {
                return route('admin.blog.edit', $row->id);
            },
        ]);
    }
    

# Making DataGrids

  1. Create a folder called DataGrids inside the src folder of your package. Within the DataGrids folder, create a file name PostDataGrid.php.

    └── packages
        └── Webkul
            └── Blog
                └── src
                    ├── ...
                    └── DataGrids
                        └── PostDataGrid.php
    
  2. Add the following code to your DataGrid file, i.e. PostDataGrid.php:

    namespace Webkul\Blog\DataGrids;
    
    use Webkul\DataGrid\DataGrid;
    use Illuminate\Support\Facades\DB;
    
    class PostDataGrid extends DataGrid
    {
        // ...
    }
    

# Displaying DataGrid

  1. Now, go to Admin/PostController.php and locate the index method. Use the toJson() method as follows:

    use Webkul\Blog\DataGrids\PostDataGrid;
    
    class PostController extends Controller
    {
        /**
         * Display a listing of the resource.
         *
         * @return \Illuminate\View\View
         */
        public function index()
        {
            if (request()->ajax()) {
                return app(PostDataGrid::class)->toJson();
            }
    
            return view('blog::admin.index');
        }
    
        // ...
    }
    

# Render DataGrid

  1. In the view file views/admin/index.blade.php, use the datagrid blade component and specify the URL from which it will load the JSON data:

    <x-admin::datagrid src="{{ route('admin.blog.index') }}"></x-admin::datagrid>
    

    With these steps, your DataGrid is now ready to be used.

WARNING

Make sure to copy the sample code provided below to your own PostDataGrid.php file, as we have already included all the necessary methods and functions there. This code can be used later as an example for your implementation.

# Sample DataGrid

Here's an improved version of the provided DataGrid sample:

<?php

namespace Webkul\Blog\DataGrids;

use Illuminate\Support\Facades\DB;
use Webkul\DataGrid\DataGrid;

class PostDataGrid extends DataGrid
{
    /**
     * Primary column.
     *
     * @var string
     */
    protected $primaryColumn = 'order_id';

    /**
     * Prepare query builder.
     *
     * @return \Illuminate\Database\Query\Builder
     */
    public function prepareQueryBuilder()
    {
        $queryBuilder = DB::table('posts')
            ->select('id', 'title', 'status', 'created_at', 'updated_at');

        return $queryBuilder;
    }

    /**
     * Prepare columns.
     *
     * @return void
     */
    public function prepareColumns()
    {
        $this->addColumn([
            'index'      => 'id',
            'label'      => trans('blog::app.admin.datagrid.id'),
            'type'       => 'integer',
            'searchable' => false,
            'sortable'   => true,
            'filterable' => true,
        ]);

        $this->addColumn([
            'index'      => 'title',
            'label'      => trans('blog::app.admin.datagrid.title'),
            'type'       => 'string',
            'searchable' => true,
            'sortable'   => true,
            'filterable' => false,
            'closure'    => function ($value) {
                return substr($value->title, 0, 20);
            },
        ]);

        $this->addColumn([
            'index'      => 'status',
            'label'      => trans('blog::app.admin.datagrid.status'),
            'type'       => 'boolean',
            'sortable'   => true,
            'searchable' => false,
            'filterable' => true,
            'closure'    => function ($value) {
                if ($value->status) {
                    return '<p class="label-active">' . trans('blog::app.admin.datagrid.active') . '</p>';
                }

                return '<p class="label-info">' . trans('blog::app.admin.datagrid.inactive') . '</p>';
            },
        ]);

        $this->addColumn([
            'index'      => 'created_at',
            'label'      => trans('blog::app.admin.datagrid.created_at'),
            'type'       => 'datetime',
            'searchable' => true,
            'sortable'   => true,
            'filterable' => true,
        ]);

        $this->addColumn([
            'index'      => 'updated_at',
            'label'      => trans('blog::app.admin.datagrid.updated_at'),
            'type'       => 'datetime',
            'searchable' => true,
            'sortable'   => true,
            'filterable' => true,
        ]);
    }

    /**
     * Prepare actions.
     *
     * @return void
     */
    public function prepareActions()
    {
        $this->addAction([
            'icon'   => 'icon-edit',
            'title'  => trans('blog::app.admin.datagrid.edit'),
            'method' => 'GET',
            'url'    => function ($row) {
                return route('aadmin.blog.edit', $row->id);
            },
        ]);

        $this->addAction([
            'icon'   => 'icon-delete',
            'title'  => trans('blog::app.admin.datagrid.delete'),
            'method' => 'DELETE',
            'url'    => function ($row) {
                return route('admin.blog.delete', $row->id);
            },
        ]);
    }

    /**
     * Prepare mass actions.
     *
     * @return void
     */
    public function prepareMassActions()
    {
        $this->addMassAction([
            'title'   => trans('blog::app.admin.datagrid.mass-update'),
            'url'     => oute('admin.blog.mass_update'),
            'method'  => 'POST',
            'options' => [
                [
                    'label'  => trans('blog::app.admin.datagrid.active'),
                    'value' => 1,
                ], [
                    'label'  => trans('blog::app.admin.datagrid.inactive'),
                    'value' => 0,
                ],
            ],
        ]);

        $this->addMassAction([
            'title'  => trans('blog::app.admin.datagrid.mass-delete'),
            'url'    => route('admin.blog.mass_delete'),
            'method' => 'POST'
        ]);
    }
}

# DataGrid Customization

In Bagisto, we have the flexibility to tailor DataGrids to your specific needs, allowing you to achieve the desired layout and functionality. Follow these straightforward steps to customize your DataGrid:

  1. Start by extending the DataGrid template:
<x-admin::datagrid 
    src="{{ route('admin.catalog.products.index') }}" 
    :isMultiRow="true"
>
        <template #header="{
            isLoading,
            available,
            applied,
            selectAll,
            sort,
            performAction
        }">

        <template #body="{
            isLoading,
            available,
            applied,
            selectAll,
            sort,
            performAction
        }">
</x-admin::datagrid>
Key Functionality
isLoading This key provides information about whether the DataGrid is currently loading.
available This key contains the available records in the DataGrid.
applied An object representing the currently applied filters, pagination, sorting, and mass actions.
selectAll A function that selects or deselects all records in the datagrid.
sort This is a function used to sort the datagrid based on a specified column.
performAction This is a function triggered when an action is performed on a record in the datagrid, such as editing, deleting, or processing.

You can use these props to customize the appearance and behavior of the datagrid header, including handling loading states, applying filters, sorting data, selecting records, and performing actions on the entire dataset.

  1. Once you've completed this step, all the data within the DataGrid becomes accessible inside the template. At this point, you have the freedom to modify the DataGrid's functionality and its user interface to suit your preferences.

TIP

By customizing the DataGrid directly in the Blade file, you won't affect your default DataGrid. This means you can display the same DataGrid with various appearances and customize it by writing simple Vue.js code and using Tailwind CSS (since we use it in Bagisto).