# 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 | Specifies the primary identifier column for the data grid, typically set to 'id' for unique identification of data entries. |
queryBuilder | Manages the database query operations for fetching data based on configured criteria. |
columns | Array defining the columns to be displayed in the data grid. |
sortColumn | Optional. Specifies the default column used for sorting data in the grid. |
sortOrder | Specifies the default order ('asc' or 'desc') for sorting data in the grid. |
actions | Array containing configurations for actions that can be performed on individual data grid entries. |
massActions | Array defining actions that can be applied to multiple entries simultaneously in the data grid. |
paginator | Stores an instance of LengthAwarePaginator for managing pagination of grid data. |
itemsPerPage | Specifies the default number of items to display per page in the data grid. |
perPageOptions | Array of options allowing users to select different numbers of items per page. |
exportable | Boolean indicating whether the data grid can exported. |
exportFile | Stores metadata related to exported data if exportable is enabled. |
# 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, thesetQueryBuilder()
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
Specifies the column's index, used to identify the column within the grid. label
Specifies the label of the column, typically used as the column header in the grid. type
Specifies the type of data contained in the column. searchable
Accepts boolean values ( true
orfalse
) to indicate if the column can be searched.filterable
Accepts boolean values ( true
orfalse
) to indicate if the column can be filtered.filterableType
Specifies the type of filter that can be applied to the column, if filterable. filterableOptions
Array of options that can be used to filter the column's data. allowMultipleValues
Accepts boolean values ( true
orfalse
) to indicate if the column allows multiple values.sortable
Accepts boolean values ( true
orfalse
) to indicate if the column can be sorted.visibility
Accepts boolean values ( true
orfalse
) to indicate if the column is visible.closure
Used to apply custom actions or conditions to the column's value. columnName
Specifies the fully qualified table column name associated with the grid column. public function prepareColumns() { $this->addColumn([ 'index' => 'status', 'label' => trans('shop::app.customers.account.orders.status.title'), 'type' => 'string', 'searchable' => true, 'filterable' => true, 'filterable_type' => 'dropdown', 'filterable_options' => [ [ 'label' => trans('shop::app.customers.account.orders.status.options.processing'), 'value' => Order::STATUS_PROCESSING, ], [ 'label' => trans('shop::app.customers.account.orders.status.options.completed'), 'value' => Order::STATUS_COMPLETED, ], [ 'label' => trans('shop::app.customers.account.orders.status.options.canceled'), 'value' => Order::STATUS_CANCELED, ], [ 'label' => trans('shop::app.customers.account.orders.status.options.closed'), 'value' => Order::STATUS_CLOSED, ], [ 'label' => trans('shop::app.customers.account.orders.status.options.pending'), 'value' => Order::STATUS_PENDING, ], [ 'label' => trans('shop::app.customers.account.orders.status.options.pending-payment'), 'value' => Order::STATUS_PENDING_PAYMENT, ], [ 'label' => trans('shop::app.customers.account.orders.status.options.fraud'), 'value' => Order::STATUS_FRAUD, ], ], 'sortable' => true, 'closure' => function ($row) { switch ($row->status) { case Order::STATUS_PROCESSING: return '<p class="label-processing">'.trans('shop::app.customers.account.orders.status.options.processing').'</p>'; case Order::STATUS_COMPLETED: return '<p class="label-active">'.trans('shop::app.customers.account.orders.status.options.completed').'</p>'; case Order::STATUS_CANCELED: return '<p class="label-canceled">'.trans('shop::app.customers.account.orders.status.options.canceled').'</p>'; case Order::STATUS_CLOSED: return '<p class="label-closed">'.trans('shop::app.customers.account.orders.status.options.closed').'</p>'; case Order::STATUS_PENDING: return '<p class="label-pending">'.trans('shop::app.customers.account.orders.status.options.pending').'</p>'; case Order::STATUS_PENDING_PAYMENT: return '<p class="label-pending">'.trans('shop::app.customers.account.orders.status.options.pending-payment').'</p>'; case Order::STATUS_FRAUD: return '<p class="label-canceled">'.trans('shop::app.customers.account.orders.status.options.fraud').'</p>'; } }, ]); }
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, theaddAction()
method is called to define a particular action.addAction()
: This method is used for adding actions (likeedit
,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); }, ]); }
# Setting Up DataGrid
# Create the DataGrids Folder
First, navigate to the src
folder of your package. Within this folder, create a new directory called DataGrids
. Inside this new directory, create a file named PostDataGrid.php
.
The folder structure should look like this:
└── packages
└── Webkul
└── Blog
└── src
├── ...
└── DataGrids
└── PostDataGrid.php
# Define the PostDataGrid Class
Open the PostDataGrid.php
file and add the following code to define the PostDataGrid
class. This class will extend the base DataGrid class provided by Bagisto and set up the necessary configurations for your data grid.
namespace Webkul\Blog\DataGrids;
use Webkul\DataGrid\DataGrid;
use Illuminate\Support\Facades\DB;
class PostDataGrid extends DataGrid
{
// ...
}
# Displaying DataGrid
Open the Admin/PostController.php
file in your package and locate the index method. In this method, you will use the toJson()
method from your DataGrid class to return the data grid as JSON when the request is an AJAX call.
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 datagrid(PostDataGrid::class)->process();
}
return view('blog::admin.index');
}
// ...
}
# Render DataGrid
Open the view file views/admin/index.blade.php
. In this view, you will use the datagrid
Blade component and specify the URL from which it will load the JSON
data.
Update the index.blade.php file as shown below:
<x-admin::datagrid src="{{ route('admin.blog.index') }}"></x-admin::datagrid>
Make sure the route admin.blog.index
is defined in your web.php
file, so that it points to the index method of the PostController:
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' => 'string',
'searchable' => false,
'filterable' => true,
'sortable' => 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',
'filterable' => true,
'filterable_type' => 'datetime_range',
'sortable' => true,
]);
$this->addColumn([
'index' => 'updated_at',
'label' => trans('blog::app.admin.datagrid.updated_at'),
'type' => 'datetime',
'filterable' => true,
'filterable_type' => 'datetime_range',
'sortable' => 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' => route('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, you can customize the DataGrid to fit your specific needs. This involves extending the DataGrid template and utilizing slots to tailor the layout and functionality. Here’s how to do it:
Use the DataGrid
component in your Blade view and specify the source URL and other properties like isMultiRow
if needed. Additionally, use the #header
and #body
slots to customize the content.
Here’s an example of how you can extend the DataGrid template:
- 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.
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).
# Available Column Types
Bagisto’s DataGrid supports various column types that allow you to store, display, and manage diverse kinds of data. This also includes a searchability feature, allowing users to filter data by specific criteria. Below is a breakdown of key column types: decimal, integer, string, boolean, date, datetime, and aggregate types.
# Integer Column Type
The integer column type is designed for whole numbers without any fractional or decimal parts. This column type is ideal for counting or identification data. Used for IDs, quantities, and numeric fields that don’t require decimal places.
$this->addColumn([
'index' => 'id',
'label' => trans('blog::app.admin.datagrid.index.id'),
'type' => 'integer',
'searchable' => true,
'filterable' => true,
'sortable' => true,
]);
# Decimal Column Type
The decimal column type stores numbers with high precision, allowing fractional parts. It’s ideal for financial or measurement data where exact precision is necessary. Used for columns like product prices, weights, or tax rates that require decimal values.
$this->addColumn([
'index' => 'price',
'label' => trans('blog::app.admin.datagrid.index.price'),
'type' => 'decimal',
'searchable' => true,
'filterable' => true,
'sortable' => true,
]);
# String Column Type
The string column type stores text or alphanumeric data. It’s widely used for columns that contain names, descriptions, or any textual information. Typically used for product names, customer names, categories, and descriptions.
$this->addColumn([
'index' => 'name',
'label' => trans('blog::app.admin.datagrid.index.name'),
'type' => 'string',
'searchable' => true,
'filterable' => true,
'sortable' => true,
]);
# filterable options in string column type
When using the string column type in Bagisto’s DataGrid, the following filterable options are supported to help refine searches based on text data.
$this->addColumn([
'index' => 'type',
'label' => trans('blog::app.admin.datagrid.index.type'),
'type' => 'string',
'filterable' => true,
'searchable' => true,
'filterable_type' => 'dropdown',
'filterable_options' => [
[
'label' => trans('blog::app.admin.datagrid.index.type.text'),
'value' => 'text',
],
[
'label' => trans('blog::app.admin.datagrid.index.type.textarea'),
'value' => 'textarea',
],
[
'label' => trans('blog::app.admin.datagrid.index.type.price'),
'value' => 'price',
],
[
'label' => trans('blog::app.admin.datagrid.index.type.boolean'),
'value' => 'boolean',
],
[
'label' => trans('blog::app.admin.datagrid.index.type.select'),
'value' => 'select',
],
[
'label' => trans('blog::app.admin.datagrid.index.type.multiselect'),
'value' => 'multiselect',
],
[
'label' => trans('blog::app.admin.datagrid.index.type.date-time'),
'value' => 'datetime',
],
[
'label' => trans('blog::app.admin.datagrid.index.type.date'),
'value' => 'date',
],
[
'label' => trans('blog::app.admin.datagrid.index.type.image'),
'value' => 'image',
],
[
'label' => trans('blog::app.admin.datagrid.index.type.file'),
'value' => 'file',
],
[
'label' => trans('blog::app.admin.datagrid.index.type.checkbox'),
'value' => 'checkbox',
],
],
'sortable' => true,
]);
# Boolean Column Type
The boolean column type stores binary values such as true or false. It’s useful for indicating the state of a specific condition. Used for status flags like “active/inactive,” “available/unavailable,” or "enabled/disabled."
$this->addColumn([
'index' => 'status',
'label' => trans('blog::app.admin.datagrid.index.status'),
'type' => 'boolean',
'searchable' => true,
'filterable' => true,
'sortable' => true,
]);
# Date Column Type
The date column type stores dates, but without time information. It is useful when only the calendar date is important, such as in daily reports or event dates. Often used for birth dates, order dates, or specific event dates.
$this->addColumn([
'index' => 'created_at',
'label' => trans('blog::app.admin.datagrid.index.date'),
'type' => 'date',
'searchable' => true,
'filterable' => true,
'sortable' => true,
]);
# filterable type in Date column type
When using the date column type in Bagisto’s DataGrid, the following filterable type are supported to help refine searches based on text data. The filterable type is typically set to 'date_range', allowing users to search for records based on specific date ranges.
$this->addColumn([
'index' => 'created_at',
'label' => trans('blog::app.admin.datagrid.index.date'),
'type' => 'date',
'searchable' => true,
'filterable' => true,
'filterable_type' => 'date_range',
'sortable' => true
]);
# DateTime Column Type
The datetime column type stores both date and time information. This is important when precise timestamps are needed. Used for tracking exact times for events like order creation, login timestamps, or last updated times.
$this->addColumn([
'index' => 'updated_at',
'label' => trans('blog::app.admin.datagrid.index.date'),
'type' => 'datetime',
'searchable' => true,
'filterable' => true,
'sortable' => true,
]);
# filterable type in Date Time column type
When using the date time column type in Bagisto’s DataGrid, the following filterable type are supported to help refine searches based on text data. The filterable type is typically set to 'datetime_range', allowing users to search for records based on specific date time ranges.
$this->addColumn([
'index' => 'updated_at',
'label' => trans('blog::app.admin.datagrid.index.date'),
'type' => 'datetime',
'filterable' => true,
'searchable' => true,
'filterable_type' => 'datetime_range',
'sortable' => true,
]);
# Aggregate Type Column
The aggregate column type is used for displaying summarized or calculated data, such as totals, averages, or counts derived from other data in the DataGrid. Used to display metrics like total sales, average order value, or product count in categories.
$this->addColumn([
'index' => 'total',
'label' => trans('blog::app.admin.datagrid.index.total'),
'type' => 'aggregate',
'searchable' => true,
'filterable' => true,
'sortable' => true,
]);