vojtasim / laravel-grid
Basic Laravel data-grid system to ease sorting and filtering large tables. Does not contain any frontend bullshit so the appearance is your job
This package's canonical repository appears to be gone and the package has been frozen as a result.
Requires
- php: >=5.4.0
- laravel/framework: 5.*
README
Basic Laravel data-grid system to ease sorting and filtering large tables. Does not contain any frontend bullshit so the apperiance is your job.
Install:
composer require vojtasim/laravel-grid
To providers in config/app.php add following line:
\VojtaSim\LaravelGrid\DataGridServiceProvider::class,
then add alias for the DataGrid facade:
'DataGrid' => \VojtaSim\LaravelGrid\Facades\DataGrid::class,
then you may publish view files by executing following command:
artisan vendor:publish --provider="\VojtaSim\LaravelGrid\DataGridServiceProvider"
Views:
Form
First we need to create form to accomodate all filter inputs. To do so, use @grid directive that takes 2 parameters.
- Name of the grid: used in controllers or outside the @grid - @endgrid scope to reference specific grid
- Route: route to which the filter and sort requests should be sent
@grid('products', 'products.index') - @endgrid
Sorting
Next we may add sorting column by using @gridColumn
directive. This directive also takes 2 parameters.
- Name of the column
- Text translation
<th>@gridColumn('name', 'products.name')</th>
If you want to filter by relative model column, you will have to join the table and alias desired column.
$query->select(['products.*', DB::raw('brands.name AS brand_name')]) ->leftJoin('brands', 'products.brand_id', '=', 'brands.id');
<th>@gridColumn('brand_name', 'products.brand')
Filters
Filter inputs are created by @gridTextFilter
or @gridSelectFilter
directive.
@gridTextFilter takes only 2 parameters and that is the name of the column you wish to filter and whether the filter should be precise or not (meaning whether the filter will use column like %value%
or column = value
@gridTextFilter('name', true/false)
@gridSelectFilter has variety of options how you can filter column, so let`s name it:
-
filtering by array of
key => value
pairs as option@gridSelectFilter('is_available', trans('products.availabilityStates'))
'availabilityStates' => ['0' => 'Unavailable', '1' => 'Available
],` -
filtering by Collection of models
@gridSelectFilter('supplier_id', $suppliers, ['id' => 'name'])
the 2nd parameter is the collection of models and the 3rd is array containing names of keys that should be used as key and value for each option of the select
-
filtering by ManyToMany relationship
@gridSelectFilter('categories:id', $categories, ['id' => 'name'])
here, the name of column is replaced by the name of the relation we wish to filter by. The string after
:
is name of the column by which the relation will be queried. For example you could filter by categories like so:@gridSelectFilter('categories:name', $categories, ['name' => 'name'])
-
filtering by count
@gridSelectFilter('relatedProducts:has', trans('products.relatedFilterStates'))
In this example the string after
:
ishas
and that means the->has()
function of QueryBuilder will be used to query the relationship.'relatedFilterStates' => ['=:0' => 'Unassigned', '>:0' => 'Assigned'],
the key of each option must consist of operator and value to correcty filter the relation.
-
filtering by multiple values
Each of options 1. - 3. can also filter by multiple values. To do so specify the 4th parameter as
true
.@gridSelectFilter('is_available', trans('products.availabilityStates'), null, true)
@gridSelectFilter('supplier_id', $suppliers, ['id' => 'name'], true)
@gridSelectFilter('categories:name', $categories, ['name' => 'name'], true)
Pagination
@gridPerPage() - directive to display "per page" select
<div class="panel-body"> {!! $products->appends(grid_parameters())->links() !!} <div class="pull-right"> <label>@lang('grid.itemsPerPage')</label> @gridPerPage([10, 20, 50, 100]) </div> </div>
Helpers
grid_parameters([ string $gridName]) - returns current sorting and filtering parameters for creating routes. Ideal for creating custom action when needed.
route('products.custom_action', array_merge(['parameter' => 'value'], grid_parameters()))
grid_checkbox([ string $gridName]) - function for creating checkbox names for bulk actions
<input type="checkbox" name="{{ grid_checkbox() }}" value="{{ $product->id }}">
grid_action([ string $gridName]) - function for creating bulk action button names
<button type="submit" name="{{ grid_action() }}" value="destroy" class="btn btn-efault"> <i class="fa fa-remove"></i> <span>@lang('products.destroy')</span> </button>
grid_column_class(string|array $column [, $gridName]) - function to obrtain CSS class for specified column(s)
returns grid-filtered
and/or grid-sorted
<colgroup> <col> <col class="{{ grid_column_class('name') }}"> <col class="{{ grid_column_class(['brand_id', 'brand_name']) }}"> <col class="{{ grid_column_class(['manufacturer_id', 'manufacturer_name']) }}"> <col class="{{ grid_column_class('is_active') }}"> <col> </colgroup>
grid_clear_link([ string $gridName]) - function that returns link for clearing all filters and sorts
Controllers
In controllers you will use maily 2 functions: applyConditions()
and getSelected()
. You may also use getFilters()
to retrieve array of filter values in column => value
pairs (note: columns that are not filtered won't be included in the array)
Example #1: applying conditions and executing bulk actions
use App\Http\Controllers\Controller, Illuminate\Http\Request, VojtaSim\LaravelGrid\Services\DataGrid; // ... public function index(Request $request, DataGrid $grid) { if ($items = $grid->getSelected('products')) { // $items = {"action": (string), "selected": (array)} if (method_exists($this, ($method = "{$items->action}Products"))) { return $this->{$method}($request, $items->selected); } } $query = Product::with(['brand', 'categories', 'relatedProducts']) ->select(['products.*', DB::raw('brands.name as brand_name')]) ->leftJoin('brands', 'products.brand_id', '=', 'brands.id'); $products = $grid->applyConditions('products', $query); $brands = Products\Brand::orderBy('name', 'asc')->get(); $categories = Products\Category::orderBy('name', 'asc')->get(); return view('products.index', compact('products', 'brands', 'categories', 'manufacturers')); }
Example #2 - obtaining filter values
use App\Http\Controllers\Controller, Illuminate\Http\Request, VojtaSim\LaravelGrid\Services\DataGrid; // ... public function index(Request $request, DataGrid $grid) { if ($items = $grid->getSelected('products')) { // $items = {"action": (string), "selected": (array)} if (method_exists($this, ($method = "{$items->action}Products"))) { return $this->{$method}($request, $items->selected); } } $query = Product::with(['manufacturer', 'productSeries',]) ->select(['products.*', DB::raw('manufacturers.name as manufacturer_name'), DB::raw('printer_series.name as series_name') ]) ->leftJoin('manufacturers', 'products.manufacturer_id', '=', 'manufacturers.id') ->leftJoin('printer_series', 'products.product_series_id', '=', 'product_series.id'); $products = $grid->applyConditions('products', $query); $manufacturers = Manufacturer::orderBy('name', 'asc')->get(); $series = Series::orderBy('name', 'asc')->get(); if ($selectedManufacturers = $grid->getFilters('products', 'manufacturer_id')) { $series->whereIn('products_series.manufacturer_id', $selectedManufacturers); } $series = $series->get(); return view('products.index', compact('products', 'manufacturers', 'series')); }