Skip to content

Instantly share code, notes, and snippets.

@fukata
Last active February 12, 2022 13:31
Embed
What would you like to do?
laravel-admin の Grid\Filter を拡張して Section を付けられるようにしてみた

コレはなに

00_SAMPLE.png のようなUIが作れます。

リンクになっているsection部分はbootstrapのcollapseの動作をします。

ファイル構成

project/
├── app
│   └── Admin
│       └── Extensions
│           ├── Grid
│           │   ├── Filter
│           │   │   └── Layout
│           │   │       ├── SectionLayout.php
│           │   │       └── Section.php
│           │   └── SectionFilter.php
│           └── SectionGrid.php
└── resources
    └── admin
        └── filter
            └── container.blade.php

使い方

    protected function grid()
    {
        $grid = new SectionGrid(new SomeModel());
        $grid->filter(function (SectionFilter $filter) {
            $filter->section('基本項目', function(SectionFilter $filter) {
                $filter->expandSection();
                $filter->column(1/2, function (Grid\Filter $filter) {
                    $filter->like('email', 'メールアドレス');
                });
            });
            $filter->section('拡張項目1', function(SectionFilter $filter) {
                $filter->column(1/2, function (Grid\Filter $filter) {
                    $filter->like('name', 'お名前');
                });
            });
            $filter->section('拡張項目2', function(SectionFilter $filter) {
                $filter->column(1/2, function (Grid\Filter $filter) {
                    $filter->like('name_kana', 'ふりがな');
                });
            });
        });

        ...

        return $grid;
    }
<div class="box-header with-border {{ $expand?'':'hide' }}" id="{{ $filterID }}">
<form action="{!! $action !!}" class="form-horizontal" pjax-container method="get">
<?php if ($layout instanceof \App\Admin\Extensions\Grid\Filter\Layout\SectionLayout) { ?>
@foreach($layout->sections() as $section)
<p>
<a href="#grid-filter-section-{{ $section->id() }}" data-toggle="collapse" data-target="#grid-filter-section-{{ $section->id() }}" aria-controls="grid-filter-section-{{ $section->id() }}" aria-expanded="{{ $section->isExpand() ? "true" : "false" }}">
{{ $section->label() }}
</a>
</p>
<div class="row collapse {{ $section->isExpand() ? "in" : "" }}" id="grid-filter-section-{{ $section->id() }}">
@foreach($section->columns() as $column)
<div class="col-md-{{ $column->width() }}">
<div class="box-body">
<div class="fields-group">
@foreach($column->filters() as $filter)
{!! $filter->render() !!}
@endforeach
</div>
</div>
</div>
@endforeach
</div>
@endforeach
<?php } else { ?>
<div class="row">
@foreach($layout->columns() as $column)
<div class="col-md-{{ $column->width() }}">
<div class="box-body">
<div class="fields-group">
@foreach($column->filters() as $filter)
{!! $filter->render() !!}
@endforeach
</div>
</div>
</div>
@endforeach
</div>
<?php } ?>
<!-- /.box-body -->
<div class="box-footer">
<div class="row">
<div class="col-md-{{ $layout->columns()->first()->width() }}">
<div class="col-md-2"></div>
<div class="col-md-8">
<div class="btn-group pull-left">
<button class="btn btn-info submit btn-sm"><i
class="fa fa-search"></i>&nbsp;&nbsp;{{ trans('admin.search') }}</button>
</div>
<div class="btn-group pull-left " style="margin-left: 10px;">
<a href="{!! $action !!}" class="btn btn-default btn-sm"><i
class="fa fa-undo"></i>&nbsp;&nbsp;{{ trans('admin.reset') }}</a>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
<?php
namespace App\Admin\Extensions\Grid\Filter\Layout;
use Encore\Admin\Grid\Filter\Layout\Column;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
class Section
{
/**
* id for layout
* @var string
*/
protected $id;
/**
* @var string
*/
protected $label;
/**
* @var boolean
*/
protected $expand;
/**
* @var Collection
*/
protected $columns;
public function __construct($label)
{
$this->id = Str::random();
$this->label = $label;
$this->expand = false;
$this->columns = new Collection();
}
/**
* @return string
*/
public function id()
{
return $this->id;
}
/**
* @return string
*/
public function label()
{
return $this->label;
}
/**
* @return boolean
*/
public function isExpand()
{
return $this->expand;
}
/**
* Set expanded to true
*/
public function expand()
{
$this->expand = true;
}
/**
* @return Collection
*/
public function columns()
{
return $this->columns;
}
/**
* Add a column to layout section.
*
* @param Column $column
*/
public function addColumn(Column $column)
{
$this->columns->push($column);
}
}
<?php
namespace App\Admin\Extensions\Grid;
use App\Admin\Extensions\Grid\Filter\Layout\SectionLayout;
use Encore\Admin\Grid\Filter;
class SectionFilter extends Filter
{
protected function initLayout()
{
$this->layout = new SectionLayout($this);
}
public function section($label, \Closure $closure)
{
$this->layout->section($label, $closure);
return $this;
}
public function column($width, \Closure $closure)
{
$width = $width < 1 ? round(12 * $width) : $width;
$this->layout->column($width, $closure);
return $this;
}
public function expandSection()
{
$this->layout->expandSection();
}
}
<?php
namespace App\Admin\Extensions;
use App\Admin\Extensions\Grid\SectionFilter;
use Encore\Admin\Grid;
class SectionGrid extends Grid
{
/**
* Setup grid filter.
*
* @return $this
*/
protected function initFilter(): SectionGrid
{
$this->filter = new SectionFilter($this->model);
return $this;
}
}
<?php
namespace App\Admin\Extensions\Grid\Filter\Layout;
use Encore\Admin\Grid\Filter;
use Encore\Admin\Grid\Filter\Layout\Layout;
use Illuminate\Support\Collection;
class SectionLayout extends Layout
{
/**
* @var Collection
*/
protected $sections;
/**
* @var Section
*/
protected $current_section;
public function __construct(Filter $filter)
{
parent::__construct($filter);
$this->sections = new Collection();
}
public function sections()
{
return $this->sections;
}
public function section($label, \Closure $closure)
{
$section = new Section($label);
$this->current_section = $section;
$this->sections->push($section);
$closure($this->parent);
}
public function column($width, \Closure $closure)
{
parent::column($width, $closure);
$this->current_section->addColumn($this->current);
}
public function expandSection()
{
$this->current_section->expand();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment