瀏覽代碼

增加Grid\Column::valueAsFilter功能

jqh 5 年之前
父節點
當前提交
8aecab4c63

+ 3 - 0
resources/assets/dcat-admin/main.css

@@ -97,6 +97,9 @@ a {
     color: #297ec0;
     color: var(--primary-dark)
 }
+a:focus, a:hover {
+    color: #206296;
+}
 
 #app {
     padding: 12px 12px 5px;

文件差異過大導致無法顯示
+ 0 - 0
resources/assets/dcat-admin/main.min.css


+ 1 - 1
src/Controllers/ExtensionController.php

@@ -115,7 +115,7 @@ class ExtensionController extends Controller
             ->display($view)
             ->expand($this->getExpandHandler('config'))
             ->else()
-            ->showEmpty();
+            ->asEmpty();
 
         $grid->require
             ->display($view)

+ 1 - 1
src/Controllers/UserController.php

@@ -111,7 +111,7 @@ class UserController extends Controller
                     }
                 })
                 ->else()
-                ->showEmpty();
+                ->asEmpty();
 
             $grid->created_at;
             $grid->updated_at->sortable();

+ 1 - 1
src/Grid.php

@@ -23,7 +23,7 @@ use Illuminate\Support\Traits\Macroable;
 class Grid
 {
     use HasBuilderEvents,
-        Concerns\HasElementNames,
+        Concerns\HasNames,
         Concerns\HasFilter,
         Concerns\HasTools,
         Concerns\HasActions,

+ 5 - 5
src/Grid/Column.php

@@ -257,7 +257,7 @@ class Column
      *         ->display($view)
      *         ->expand(...)
      *         ->else()
-     *         ->showEmpty()
+     *         ->asEmpty()
      *
      *    $grid->config
      *         ->if(function () {
@@ -267,7 +267,7 @@ class Column
      *             $column ->display($view)->expand(...);
      *         })
      *         ->else(function (Column $column) {
-     *             $column->showEmpty();
+     *             $column->asEmpty();
      *         })
      *
      * @param \Closure $condition
@@ -482,14 +482,14 @@ class Column
      */
     public function filter(Grid\Column\Filter $filter)
     {
-        return $this->addFilter($filter);
+        return $this->addHeader($filter);
     }
 
     /**
      * Add a display callback.
      *
-     * @param \Closure $callback
-     * @param array    $params
+     * @param \Closure|string $callback
+     * @param array           $params
      *
      * @return $this
      */

+ 34 - 1
src/Grid/Column/HasDisplayers.php

@@ -10,6 +10,11 @@ use Illuminate\Support\Collection;
 
 trait HasDisplayers
 {
+    /**
+     * @var ValueFilter
+     */
+    protected $valueFilter;
+
     /**
      * Display using display abstract.
      *
@@ -203,8 +208,36 @@ trait HasDisplayers
     /**
      * @return $this
      */
-    public function showEmpty()
+    public function asEmpty()
     {
         return $this->display('');
     }
+
+    /**
+     * @param string|\Closure $operator
+     *
+     * @return $this
+     */
+    public function valueAsFilter($operator = '=')
+    {
+        $valueFilter = $this->valueFilter();
+
+        $valueFilter->setup($operator);
+
+        return $this->display(function ($value) use ($valueFilter) {
+            return $valueFilter->render($value);
+        });
+    }
+
+    /**
+     * @return ValueFilter
+     */
+    public function valueFilter()
+    {
+        if (! $this->valueFilter) {
+            $this->valueFilter = new ValueFilter($this);
+        }
+
+        return $this->valueFilter;
+    }
 }

+ 0 - 12
src/Grid/Column/HasHeader.php

@@ -72,18 +72,6 @@ trait HasHeader
         return $this->addHeader(new Help($message, $style, $placement));
     }
 
-    /**
-     * Add a filter to column header.
-     *
-     * @param \Closure $builder
-     *
-     * @return $this
-     */
-    protected function addFilter(Filter $filter)
-    {
-        return $this->addHeader($filter);
-    }
-
     /**
      * Add a binding based on filter to the model query.
      *

+ 95 - 0
src/Grid/Column/ValueFilter.php

@@ -0,0 +1,95 @@
+<?php
+
+namespace Dcat\Admin\Grid\Column;
+
+use Dcat\Admin\Admin;
+use Dcat\Admin\Grid\Column;
+use Dcat\Admin\Support\Helper;
+
+class ValueFilter
+{
+    /**
+     * @var Column
+     */
+    protected $column;
+
+    /**
+     * @var string|\Closure
+     */
+    protected $operator;
+
+    public function __construct(Column $column)
+    {
+        $this->column = $column;
+    }
+
+    public function setup($operator)
+    {
+        $this->operator = $operator;
+
+        $this->addStyle();
+        $this->addResetButton();
+        $this->addApplyFilterCallback();
+    }
+
+    protected function addStyle()
+    {
+        Admin::style('.value-filter{border-bottom:1px dashed}.value-filter:hover>span{display:inline!important}');
+    }
+
+    protected function addResetButton()
+    {
+        $this->column->grid()->filtering(function () {
+            if (! $this->value()) {
+                return;
+            }
+
+            return $this->column->addHeader("&nbsp;<a class='fa fa-undo' href='{$this->resetUrl()}'></a>");
+        });
+    }
+
+    protected function addApplyFilterCallback()
+    {
+        $this->column->grid()->filtering(function () {
+            if (! ($value = $this->value())) {
+               return;
+            }
+            $operator = $this->operator;
+            $column = $this->column->getName();
+            $model = $this->column->grid()->model();
+
+            if (is_string($operator)) {
+                $model->where($column, $operator, $value);
+            } elseif ($operator instanceof \Closure) {
+                $operator($model, $column, $value);
+            }
+        });
+    }
+
+    public function queryName()
+    {
+        $name = $this->column->grid()->getName();
+        $column = $this->column->getName();
+
+        return 'value-filter'.($name ? "-{$name}" : '')."-{$column}";
+    }
+
+    public function resetUrl()
+    {
+        return Helper::fullUrlWithoutQuery($this->queryName());
+    }
+
+    public function value()
+    {
+        return request($this->queryName());
+    }
+
+    public function render($value)
+    {
+        $original = $this->column->getOriginal();
+
+        $url = request()->fullUrlWithQuery([$this->queryName() => $original]);
+
+        return "<a class='value-filter' href='$url'>{$value}<span style='display:none'> &nbsp;<i class='fa fa-filter'></i></span></a>";
+    }
+}

+ 19 - 1
src/Grid/Concerns/HasFilter.php

@@ -15,6 +15,11 @@ trait HasFilter
      */
     protected $filter;
 
+    /**
+     * @var array
+     */
+    protected $beforeApplyFilterCallbacks = [];
+
     /**
      * Setup grid filter.
      *
@@ -36,6 +41,10 @@ trait HasFilter
     {
         $this->callBuilder();
 
+        foreach ($this->beforeApplyFilterCallbacks as $callback) {
+            $callback($this);
+        }
+
         $this->applyQuickSearch();
         $this->applyColumnFilter();
         $this->applySelectorQuery();
@@ -61,6 +70,16 @@ trait HasFilter
         return $this;
     }
 
+    /**
+     * @param Closure $callback
+     *
+     * @return void
+     */
+    public function filtering(\Closure $callback)
+    {
+        $this->beforeApplyFilterCallbacks[] = $callback;
+    }
+
     /**
      * Render the grid filter.
      *
@@ -94,7 +113,6 @@ trait HasFilter
      */
     public function disableFilter(bool $disable = true)
     {
-//        $this->tools->disableFilterButton($disable);
         $this->filter->disableCollapse($disable);
 
         return $this->option('show_filter', ! $disable);

+ 1 - 1
src/Grid/Concerns/HasElementNames.php → src/Grid/Concerns/HasNames.php

@@ -7,7 +7,7 @@ use Dcat\Admin\Grid;
 /**
  * @method Grid\Model model()
  */
-trait HasElementNames
+trait HasNames
 {
     /**
      * Grid name.

+ 3 - 29
src/Grid/Filter.php

@@ -27,6 +27,7 @@ use Dcat\Admin\Grid\Filter\Scope;
 use Dcat\Admin\Grid\Filter\StartWith;
 use Dcat\Admin\Grid\Filter\Where;
 use Dcat\Admin\Grid\Filter\Year;
+use Dcat\Admin\Support\Helper;
 use Dcat\Admin\Traits\HasBuilderEvents;
 use Illuminate\Contracts\Support\Arrayable;
 use Illuminate\Contracts\Support\Renderable;
@@ -712,7 +713,7 @@ class Filter implements Renderable
             return "{$filter->getId()}_group";
         });
 
-        return $this->fullUrlWithoutQuery(
+        return Helper::fullUrlWithoutQuery(
             $columns->merge($groupNames)
         );
     }
@@ -724,34 +725,7 @@ class Filter implements Renderable
      */
     public function urlWithoutScopes()
     {
-        return $this->fullUrlWithoutQuery(Scope::QUERY_NAME);
-    }
-
-    /**
-     * Get full url without query strings.
-     *
-     * @param Arrayable|array|string $keys
-     *
-     * @return string
-     */
-    protected function fullUrlWithoutQuery($keys)
-    {
-        if ($keys instanceof Arrayable) {
-            $keys = $keys->toArray();
-        }
-
-        $keys = (array) $keys;
-
-        $request = request();
-
-        $query = $request->query();
-        Arr::forget($query, $keys);
-
-        $question = $request->getBaseUrl().$request->getPathInfo() == '/' ? '/?' : '?';
-
-        return count($request->query()) > 0
-            ? $request->url().$question.http_build_query($query)
-            : $request->fullUrl();
+        return Helper::fullUrlWithoutQuery(Scope::QUERY_NAME);
     }
 
     /**

+ 27 - 4
src/Support/Helper.php

@@ -258,8 +258,6 @@ class Helper
     }
 
     /**
-     * 把php数据转化成文本形式.
-     *
      * @param array $array
      * @param int   $level
      *
@@ -302,8 +300,6 @@ class Helper
     }
 
     /**
-     * 把php数据转化成文本形式,并以"return"形式返回.
-     *
      * @param array $array
      *
      * @return string
@@ -329,4 +325,31 @@ class Helper
             }
         }
     }
+
+    /**
+     * Get full url without query strings.
+     *
+     * @param Arrayable|array|string $keys
+     *
+     * @return string
+     */
+    public static function fullUrlWithoutQuery($keys)
+    {
+        if ($keys instanceof Arrayable) {
+            $keys = $keys->toArray();
+        }
+
+        $keys = (array) $keys;
+
+        $request = request();
+
+        $query = $request->query();
+        Arr::forget($query, $keys);
+
+        $question = $request->getBaseUrl().$request->getPathInfo() == '/' ? '/?' : '?';
+
+        return count($request->query()) > 0
+            ? $request->url().$question.http_build_query($query)
+            : $request->fullUrl();
+    }
 }

部分文件因文件數量過多而無法顯示