From 5db7381887fd3e97705e7a7728b55d10cf620241 Mon Sep 17 00:00:00 2001 From: Dmitry Mazurov Date: Fri, 6 Dec 2019 12:32:48 +0300 Subject: [PATCH 1/6] Added multiple search --- src/CollectionDataTable.php | 51 +++++++++++++++++++++++++++++++++++++ src/DataTableAbstract.php | 19 +++++++++++++- src/Utilities/Config.php | 10 ++++++++ src/config/datatables.php | 5 ++++ 4 files changed, 84 insertions(+), 1 deletion(-) diff --git a/src/CollectionDataTable.php b/src/CollectionDataTable.php index b581cc3b..ba1e4e71 100644 --- a/src/CollectionDataTable.php +++ b/src/CollectionDataTable.php @@ -16,6 +16,13 @@ class CollectionDataTable extends DataTableAbstract */ public $collection; + /** + * Collection object. + * + * @var \Illuminate\Support\Collection + */ + public $merged; + /** * Collection object. * @@ -66,6 +73,7 @@ public function __construct(Collection $collection) $this->request = app('datatables.request'); $this->config = app('datatables.config'); $this->collection = $collection; + $this->merged = collect(); $this->original = $collection; $this->columns = array_keys($this->serialize($collection->first())); } @@ -250,6 +258,49 @@ protected function globalSearch($keyword) }); } + /** + * Perform multiple search for the given keyword. + * + * @param string $keyword + */ + protected function multiSearch($keywords) + { + if (is_array($keywords)) { + foreach ($keywords as $keyword) { + $keyword = $this->config->isCaseInsensitive() ? Str::lower($keyword) : $keyword; + + $mergedCollection = $this->collection->filter(function ($row) use ($keyword) { + $this->isFilterApplied = true; + + $data = $this->serialize($row); + foreach ($this->request->searchableColumnIndex() as $index) { + $column = $this->getColumnName($index); + $value = Arr::get($data, $column); + if (! $value || is_array($value)) { + if (! is_numeric($value)) { + continue; + } + + $value = (string) $value; + } + + $value = $this->config->isCaseInsensitive() ? Str::lower($value) : $value; + + if (Str::contains($value, $keyword)) { + return true; + } + } + + return false; + }); + + $this->merged = $this->merged->merge($mergedCollection); + } + + $this->collection = $this->merged->unique(); + } + } + /** * Perform default query orderBy clause. */ diff --git a/src/DataTableAbstract.php b/src/DataTableAbstract.php index 38e63c6c..99857a5a 100644 --- a/src/DataTableAbstract.php +++ b/src/DataTableAbstract.php @@ -655,9 +655,15 @@ public function filtering() { $keyword = $this->request->keyword(); + if ($this->config->isMultiple()) { + $this->smartMultiSearch($keyword); + + return; + } + if ($this->config->isMultiTerm()) { $this->smartGlobalSearch($keyword); - + return; } @@ -681,6 +687,17 @@ protected function smartGlobalSearch($keyword) }); } + /** + * Perform multiple search by splitting keyword into + * individual words and searches for each of them. + * + * @param string $keyword + */ + protected function smartMultiSearch($keyword) + { + $this->multiSearch(explode(' ', $keyword)); + } + /** * Perform global search for the given keyword. * diff --git a/src/Utilities/Config.php b/src/Utilities/Config.php index 67a0f393..7e23e854 100644 --- a/src/Utilities/Config.php +++ b/src/Utilities/Config.php @@ -95,6 +95,16 @@ public function isMultiTerm() return $this->repository->get('datatables.search.multi_term', true); } + /** + * Check if dataTable config uses multiple searching. + * + * @return bool + */ + public function isMultiple() + { + return $this->repository->get('datatables.search.multiple', false); + } + /** * Check if dataTable config uses starts_with searching. * diff --git a/src/config/datatables.php b/src/config/datatables.php index ed2e36f7..3c9cc75b 100644 --- a/src/config/datatables.php +++ b/src/config/datatables.php @@ -16,6 +16,11 @@ */ 'multi_term' => true, + /* + * Multiple search will explode search keyword using spaces resulting into multiple search. + */ + 'multiple' => false, + /* * Case insensitive will search the keyword in lower case format. * SQL: LOWER(column) LIKE LOWER(keyword) From c7e2a8520973a071b08b97fa5e64559184fb21e5 Mon Sep 17 00:00:00 2001 From: Dmitry Mazurov Date: Fri, 10 Jan 2020 18:37:23 +0300 Subject: [PATCH 2/6] Updated search for Collection Signed-off-by: Dmitry Mazurov --- src/CollectionDataTable.php | 62 +++++++++++++------------------------ src/DataTableAbstract.php | 9 ++++-- 2 files changed, 28 insertions(+), 43 deletions(-) diff --git a/src/CollectionDataTable.php b/src/CollectionDataTable.php index ba1e4e71..ba11d918 100644 --- a/src/CollectionDataTable.php +++ b/src/CollectionDataTable.php @@ -224,16 +224,9 @@ private function revertIndexColumn($mDataSupport) } } - /** - * Perform global search for the given keyword. - * - * @param string $keyword - */ - protected function globalSearch($keyword) + protected function search($keyword) { - $keyword = $this->config->isCaseInsensitive() ? Str::lower($keyword) : $keyword; - - $this->collection = $this->collection->filter(function ($row) use ($keyword) { + return $this->collection->filter(function ($row) use ($keyword) { $this->isFilterApplied = true; $data = $this->serialize($row); @@ -249,6 +242,7 @@ protected function globalSearch($keyword) } $value = $this->config->isCaseInsensitive() ? Str::lower($value) : $value; + if (Str::contains($value, $keyword)) { return true; } @@ -259,46 +253,34 @@ protected function globalSearch($keyword) } /** - * Perform multiple search for the given keyword. + * Perform global search for the given keyword. * * @param string $keyword */ - protected function multiSearch($keywords) + protected function globalSearch($keyword) { - if (is_array($keywords)) { - foreach ($keywords as $keyword) { - $keyword = $this->config->isCaseInsensitive() ? Str::lower($keyword) : $keyword; - - $mergedCollection = $this->collection->filter(function ($row) use ($keyword) { - $this->isFilterApplied = true; - - $data = $this->serialize($row); - foreach ($this->request->searchableColumnIndex() as $index) { - $column = $this->getColumnName($index); - $value = Arr::get($data, $column); - if (! $value || is_array($value)) { - if (! is_numeric($value)) { - continue; - } - - $value = (string) $value; - } - $value = $this->config->isCaseInsensitive() ? Str::lower($value) : $value; + $keyword = $this->config->isCaseInsensitive() ? Str::lower($keyword) : $keyword; - if (Str::contains($value, $keyword)) { - return true; - } - } + $this->collection = $this->search($keyword); + } - return false; - }); + /** + * Perform multiple search for the given keyword. + * + * @param string $keyword + */ + protected function multiSearch($keywords) + { + $keywords->each(function($keyword) { + $keyword = $this->config->isCaseInsensitive() ? Str::lower($keyword) : $keyword; + + $mergedCollection = $this->search($keyword); - $this->merged = $this->merged->merge($mergedCollection); - } + $this->merged = $this->merged->merge($mergedCollection); + }); - $this->collection = $this->merged->unique(); - } + $this->collection = $this->merged->unique(); } /** diff --git a/src/DataTableAbstract.php b/src/DataTableAbstract.php index 99857a5a..f9bb2032 100644 --- a/src/DataTableAbstract.php +++ b/src/DataTableAbstract.php @@ -657,13 +657,11 @@ public function filtering() if ($this->config->isMultiple()) { $this->smartMultiSearch($keyword); - return; } if ($this->config->isMultiTerm()) { $this->smartGlobalSearch($keyword); - return; } @@ -695,7 +693,12 @@ protected function smartGlobalSearch($keyword) */ protected function smartMultiSearch($keyword) { - $this->multiSearch(explode(' ', $keyword)); + $this->multiSearch( + collect(explode(' ', $keyword)) + ->reject(function ($keyword) { + return trim($keyword) === ''; + }) + ); } /** From e405278423064f0bd84c6619c2a4a503b92125cd Mon Sep 17 00:00:00 2001 From: Dmitry Mazurov Date: Wed, 11 Mar 2020 19:46:15 +0300 Subject: [PATCH 3/6] Adding multiple search for query bilder. Adding multiTermSearch, multipleSearch runtime set. Adding desctiption for null_last_sql for postgreSQL. --- src/DataTableAbstract.php | 26 +++++++++++++++++++ src/QueryDataTable.php | 53 +++++++++++++++++++++++++++++---------- src/config/datatables.php | 1 + 3 files changed, 67 insertions(+), 13 deletions(-) diff --git a/src/DataTableAbstract.php b/src/DataTableAbstract.php index f9bb2032..13b469af 100644 --- a/src/DataTableAbstract.php +++ b/src/DataTableAbstract.php @@ -464,6 +464,32 @@ public function startsWithSearch($state = true) return $this; } + /** + * Set multi_term search config at runtime. + * + * @param bool $state + * @return $this + */ + public function multiTermSearch($state = true) + { + $this->config->set('datatables.search.multi_term', $state); + + return $this; + } + + /** + * Set multiple search config at runtime. + * + * @param bool $state + * @return $this + */ + public function multipleSearch($state = true) + { + $this->config->set('datatables.search.multiple', $state); + + return $this; + } + /** * Set total records manually. * diff --git a/src/QueryDataTable.php b/src/QueryDataTable.php index 929654e4..87468455 100644 --- a/src/QueryDataTable.php +++ b/src/QueryDataTable.php @@ -703,14 +703,9 @@ protected function getNullsLastSql($column, $direction) ); } - /** - * Perform global search for the given keyword. - * - * @param string $keyword - */ - protected function globalSearch($keyword) + protected function search($keyword, $multiple = false) { - $this->query->where(function ($query) use ($keyword) { + $this->query->where(function ($query) use ($keyword, $multiple) { collect($this->request->searchableColumnIndex()) ->map(function ($index) { return $this->getColumnName($index); @@ -718,18 +713,50 @@ protected function globalSearch($keyword) ->reject(function ($column) { return $this->isBlacklisted($column) && ! $this->hasFilterColumn($column); }) - ->each(function ($column) use ($keyword, $query) { - if ($this->hasFilterColumn($column)) { - $this->applyFilterColumn($query, $column, $keyword, 'or'); + ->each(function ($column) use ($keyword, $query, $multiple) { + if ($multiple) { + $keyword->each(function($keyword) use ($query, $column) { + if ($this->hasFilterColumn($column)) { + $this->applyFilterColumn($query, $column, $keyword, 'or'); + } else { + $this->compileQuerySearch($query, $column, $keyword); + } + + $this->isFilterApplied = true; + }); } else { - $this->compileQuerySearch($query, $column, $keyword); - } + if ($this->hasFilterColumn($column)) { + $this->applyFilterColumn($query, $column, $keyword, 'or'); + } else { + $this->compileQuerySearch($query, $column, $keyword); + } - $this->isFilterApplied = true; + $this->isFilterApplied = true; + } }); }); } + /** + * Perform global search for the given keyword. + * + * @param string $keyword + */ + protected function globalSearch($keyword) + { + $this->search($keyword); + } + + /** + * Perform multiple search for the given keyword. + * + * @param string $keyword + */ + protected function multiSearch($keywords) + { + $this->search($keywords, true); + } + /** * Append debug parameters on output. * diff --git a/src/config/datatables.php b/src/config/datatables.php index 3c9cc75b..fccad859 100644 --- a/src/config/datatables.php +++ b/src/config/datatables.php @@ -71,6 +71,7 @@ /* * Nulls last sql pattern for PostgreSQL & Oracle. * For MySQL, use 'CASE WHEN :column IS NULL THEN 1 ELSE 0 END, :column :direction' + * For PostgreSQL & Oracle use ':column :direction NULLS LAST' */ 'nulls_last_sql' => ':column :direction NULLS LAST', From 66516861f4985d03020537f691208e5fff3216ed Mon Sep 17 00:00:00 2001 From: Dmitry Mazurov Date: Thu, 23 Apr 2020 18:44:39 +0300 Subject: [PATCH 4/6] Fix php_cs Signed-off-by: Dmitry Mazurov --- src/CollectionDataTable.php | 2 +- src/DataTableAbstract.php | 2 ++ src/QueryDataTable.php | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/CollectionDataTable.php b/src/CollectionDataTable.php index ba11d918..d7f117ae 100644 --- a/src/CollectionDataTable.php +++ b/src/CollectionDataTable.php @@ -272,7 +272,7 @@ protected function globalSearch($keyword) */ protected function multiSearch($keywords) { - $keywords->each(function($keyword) { + $keywords->each(function ($keyword) { $keyword = $this->config->isCaseInsensitive() ? Str::lower($keyword) : $keyword; $mergedCollection = $this->search($keyword); diff --git a/src/DataTableAbstract.php b/src/DataTableAbstract.php index 13b469af..9599ffea 100644 --- a/src/DataTableAbstract.php +++ b/src/DataTableAbstract.php @@ -683,11 +683,13 @@ public function filtering() if ($this->config->isMultiple()) { $this->smartMultiSearch($keyword); + return; } if ($this->config->isMultiTerm()) { $this->smartGlobalSearch($keyword); + return; } diff --git a/src/QueryDataTable.php b/src/QueryDataTable.php index 87468455..3f209dc4 100644 --- a/src/QueryDataTable.php +++ b/src/QueryDataTable.php @@ -715,13 +715,13 @@ protected function search($keyword, $multiple = false) }) ->each(function ($column) use ($keyword, $query, $multiple) { if ($multiple) { - $keyword->each(function($keyword) use ($query, $column) { + $keyword->each(function ($keyword) use ($query, $column) { if ($this->hasFilterColumn($column)) { $this->applyFilterColumn($query, $column, $keyword, 'or'); } else { $this->compileQuerySearch($query, $column, $keyword); } - + $this->isFilterApplied = true; }); } else { From 1d566e3c831904316b4a7ac65795c4b938867ff3 Mon Sep 17 00:00:00 2001 From: Dmitry Mazurov Date: Thu, 23 Apr 2020 18:45:53 +0300 Subject: [PATCH 5/6] Fix php_cs in collection Signed-off-by: Dmitry Mazurov --- src/CollectionDataTable.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/CollectionDataTable.php b/src/CollectionDataTable.php index d7f117ae..2320cdef 100644 --- a/src/CollectionDataTable.php +++ b/src/CollectionDataTable.php @@ -274,7 +274,7 @@ protected function multiSearch($keywords) { $keywords->each(function ($keyword) { $keyword = $this->config->isCaseInsensitive() ? Str::lower($keyword) : $keyword; - + $mergedCollection = $this->search($keyword); $this->merged = $this->merged->merge($mergedCollection); From 3e962ff4bda3a939ead50ddeeaa359f2fc6693d0 Mon Sep 17 00:00:00 2001 From: Dmitry Mazurov Date: Thu, 23 Apr 2020 18:46:55 +0300 Subject: [PATCH 6/6] Fix style Signed-off-by: Dmitry Mazurov --- src/CollectionDataTable.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/CollectionDataTable.php b/src/CollectionDataTable.php index 2320cdef..6c733cbc 100644 --- a/src/CollectionDataTable.php +++ b/src/CollectionDataTable.php @@ -259,7 +259,6 @@ protected function search($keyword) */ protected function globalSearch($keyword) { - $keyword = $this->config->isCaseInsensitive() ? Str::lower($keyword) : $keyword; $this->collection = $this->search($keyword);