From da7f3f9a5c0cdb57435c062bf40f113100bececc Mon Sep 17 00:00:00 2001 From: Yogesh Sharma Date: Mon, 21 Oct 2024 13:35:08 +0530 Subject: [PATCH] Feature: Added Suport For Column Wise Search And Gloabal Search , Filtering Data From Frontend, Server Side Export To Different File Formats --- README.md | 85 ++++++-- composer.json | 4 +- logo.png | Bin 0 -> 14486 bytes src/AbstractDatatable.php | 320 +++++++-------------------- src/Collection.php | 5 + src/DatatableExportHandler.php | 29 +++ src/DatatableRequest.php | 34 ++- src/Eloquent.php | 5 + src/QueryBuilder.php | 8 + src/Traits/HasQueryBuilder.php | 332 +++++++++++++++++++++++++++++ src/Traits/ManagesTableColumns.php | 90 ++++++++ src/config/Datatable.php | 44 +++- 12 files changed, 682 insertions(+), 274 deletions(-) create mode 100644 logo.png create mode 100644 src/DatatableExportHandler.php create mode 100644 src/Traits/HasQueryBuilder.php create mode 100644 src/Traits/ManagesTableColumns.php diff --git a/README.md b/README.md index add8a1b..c294ef0 100755 --- a/README.md +++ b/README.md @@ -1,46 +1,89 @@ +

+

+ [![Latest Stable Version](https://poser.pugx.org/iyogesharma/datatable-laravel/v/stable)](https://packagist.org/packages/iyogesharma/datatable-laravel) [![Total Downloads](https://poser.pugx.org/iyogesharma/datatable-laravel/downloads)](https://packagist.org/packages/iyogesharma/datatable-laravel) [![License](https://poser.pugx.org/iyogesharma/datatable-laravel/license)](https://packagist.org/packages/iyogesharma/datatable-laravel) -# jQuery Datatables For Laravel 5.x +# jQuery Datatables For Laravel A simple package to ease datatable.js server side operations This package is created to handle [server-side](https://www.datatables.net/manual/server-side) and [client-side](https://www.datatables.net/manual) works of [DataTables](http://datatables.net) jQuery Plugin via [AJAX option](https://datatables.net/reference/option/ajax) by using Eloquent ORM, Query Builder or Collection. -## datatable-laravel 2.0 +## datatable-laravel 4.x -Version 2.0 continues the improvements in version 1.0.3 by introducing some new functions , improved code structure and various bug fixes. +Version 4.x continues the improvements in version 3.x by introducing some new features ## New -Introduced three new functions for the case if you know -query is instance of which class. Currently supported include: -Eloquent Query Builder, Database Query Builder and Eloquent Collection - -```php - - echo datatable()->eloquent(User::query())->init(); - echo datatable()->collection(User::query())->init(); - echo datatable()->queryBuilder(User::query())->init(); - -``` + - Added support for select raw queries + + - Auto guess column names if no columns are provided in request + + - Auto guess column names if * is provided in column names + + - Added support for group by and havig clause + + - Example + ```php + echo datatable(User::select('users.name','users.email','users.contact_no','users.role_id') + ->selectRaw(" + Max(id) as total + ") + ->groupBy('users.name', 'users.email', 'users.contact_no'))->init(); + + echo datatable(User::select('users.*'))->init(); + ``` + + + - Added Support For Data Filtering From Client Side + - Added Column Wise Search Query Support Using Below Api + - Example + ```json + { + "columns": [ + { + "data": "name", + "name": "name", + "searchable": true, + "orderable": true, + "search": { + "value": "", + "regex": false + } + } + ], + "start": 0, + "length": 10, + "search": { + "value": "Yoges", + "regex": false + }, + "filters": { + "role_id" : [1,2],// role id in 1,2 + "created_at": [date1, date2], // createde at is between date1 and date2, + "name": "iyogesh" // where name = iyogesh + } + } + + ``` ## Modified -Modified make and datatable function . Second parameter here is boolean -with default to false indicate whether you want json response or not. -If you don't pass second parameter then you need to use init() function -as we are using in previous version. +Modified datatable function to support server side export to xls,csv and json -```php +You just need to pass 2 new arguments in query-string/body `export` and ` ext ` -echo datatable()->make(User::query(),true); -echo datatable(User::query(),true); +if ` export = true ` it will return download file response +for `ext` default value is `xlsx` +```javascript + https://datatable-url?export=true&ext=xlsx ``` + ## Using Helper Function ```php diff --git a/composer.json b/composer.json index 87e19a9..c603de6 100755 --- a/composer.json +++ b/composer.json @@ -6,7 +6,7 @@ "datatable", "laravel" ], - "version": "3.6.2", + "version": "4.0", "license": "MIT", "authors": [{ "name": "Yogesh Sharma", @@ -50,7 +50,7 @@ } }, "branch-alias": { - "dev-master": "3.x-dev" + "dev-master": "4.x" } } } diff --git a/logo.png b/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..c0dd2007913ea45346912620cbfbe70d47383b7d GIT binary patch literal 14486 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 literal 0 HcmV?d00001 diff --git a/src/AbstractDatatable.php b/src/AbstractDatatable.php index 2f91c2a..9dd0c27 100755 --- a/src/AbstractDatatable.php +++ b/src/AbstractDatatable.php @@ -2,37 +2,12 @@ namespace YS\Datatable; -use Closure; +use YS\Datatable\Traits\HasQueryBuilder; +use YS\Datatable\Traits\ManagesTableColumns; abstract class AbstractDatatable implements DatatableDriverInterface { - /** - * Columns of table - * - * @var array - */ - protected $columns = []; - - /** - * Columns for where conditions - * - * @var array - */ - protected $whereColumns = []; - - /** - * Columns for having conditions - * - * @var array - */ - protected $havingColumns = []; - - /** - * Searchable Columns for where conditions - * - * @var array - */ - protected $searchColumns = []; + use ManagesTableColumns, HasQueryBuilder; /** * Represent index of ordering column @@ -71,18 +46,12 @@ abstract class AbstractDatatable implements DatatableDriverInterface */ protected $totalFiltered; - /** - * Query to fetch data from storage - * - * @var mixed - */ - protected $query; /** * Holds DatatableRequest Instance * @var DatatableRequest */ - protected $request; + protected $request; /** * Initializes new instance @@ -103,8 +72,11 @@ public function datatable($source, $json = false) { if( $this->request->isForExport() ) { - $class = "\\YS\\Export\\".$this->request->extension(); - return (new $class( $source ))->response(); + $class = config('datatable.export')[strtolower($this->request->extension())]; + + $handler = new DatatableExportHandler( $class, $source ); + + return $json ? $handler->response() : $handler; } // Set properties of class and initialize datatable $this->boot($source); @@ -123,8 +95,11 @@ public function makeDatatable($source) { if( $this->request->isForExport() ) { - $class = "\\YS\\Export\\".$this->request->extension(); - return (new $class( $source ))->response(); + $class = config('datatable.export')[strtolower($this->request->extension())]; + + $handler = new DatatableExportHandler( $class, $source ); + + return $handler->response(); } // Set properties of class and initialize datatable $this->boot($source); @@ -167,62 +142,6 @@ protected function setProperties() $this->order = $this->request->getOrderableColumnIndex(); $this->dir = $this->request->getOrderDirection(); } - - $this->setColumns(); - } - - /** - * Set column names which are displayed on datatables - * - * @return void - */ - protected function setColumns() - { - foreach ($this->request->getColumns() as $c) { - - $this->columns[] = $c['data']; - if ($c['searchable'] == 'true') { - $this->searchColumns[] = $c['data']; - } - } - } - - /** - * Set column names for where conditions of query - * - * @return void - */ - protected function setWhereColumns() - { - foreach ($this->query->columns as $c) { - if(gettype($c) === 'object'){ - $c = $c->getValue($this->query->grammar); - if (strpos($c, ' as ')) { - $column = explode(' as ', $c); - if (in_array(trim($column[1]), $this->searchColumns, true)) { - $this->havingColumns[] = trim($column[1]); - } - } - } - else if (!strpos($c, '_id')) { - if (strpos($c, ' as ')) { - $column = explode(' as ', $c); - if (in_array(trim($column[1]), $this->searchColumns, true)) { - $this->whereColumns[] = trim($column[0]); - } - - } else { - if (isset(explode('.', $c)[1])) { - if (in_array(explode('.', $c)[1], $this->searchColumns, true)) { - $this->whereColumns[] = trim($c); - } - - } else { - $this->whereColumns[] = trim($c); - } - } - } - } } /** @@ -232,6 +151,8 @@ protected function setWhereColumns() */ protected function prepareQuery() { + $this->setColumns(); + $this->checkIfQueryIsForSearchingPurpose(); $this->setTotalDataAndFiltered(); @@ -253,9 +174,10 @@ protected function prepareQuery() */ protected function checkIfQueryIsForSearchingPurpose() { - if( $this->request->isSearchable() ) + if( $this->request->isSearchable() || !empty($this->searchColumns) ) { $this->totalData = $this->query->getCountForPagination(); + $this->searchQuery(); } } @@ -281,121 +203,104 @@ protected function setTotalDataAndFiltered() { if (!empty($this->havingColumns)) { - $this->query->bindings['where'] = []; + $this->query->bindings['where'] = []; $this->query->wheres = []; - $this->havingCondition($this->request->getSearchString(), $this->havingColumns); - $this->totalFiltered = $this->query->getCountForPagination(); + $this->havingCondition($this->havingColumns); + $this->totalFiltered = $this->query->getCountForPagination(); } } } } /** - * Prepare result to return as response + * Handle datatable search operation * - * @return void */ - protected function prepareQueryWithoutOffset() + protected function searchQuery() { - $this->query = $this->query->orderBy($this->columns[$this->order],$this->dir); + //set columns that are searchable + $this->setWhereColumns(); - $this->result = $this->query->get(); + if (!empty($this->whereColumns)) { + $this->query = $this->condition( $this->whereColumns ); + } } - /** - * Prepare result to return as response - * - * @return void - */ - public function prepareQueryWithOffsetAndOrderBy() - { - $this->query = $this->query->offset($this->request->getStart()) - ->limit($this->request->getPerPage()) - ->orderBy($this->columns[$this->order],$this->dir); - $this->result = $this->query->get(); - } /** - * Prepare result to return as response + * Set filterable conditions on query * * @return void */ - public function prepareResultWithoutOffsetAndOrderBy() + protected function setFilters() { - $this->result = $this->query; + $filters = $this->request->getFilters(); + $this->query = $this->query->where($filters['basic']); + if( count($filters['array']) > 0 ) + { + $this->setArrayFilters( $filters['array']); + } } /** - * Handle datatable search operation + * set array filter conditions on query * + * @param array $filters */ - protected function searchQuery() + protected function setArrayFilters( array $filters ) { - //set columns that are searchable - $this->setWhereColumns(); - - if (!empty($this->whereColumns)) { - $this->query = $this->condition($this->request->getSearchString(), $this->whereColumns); + foreach( $filters as $k => $v ) + { + if( count($v) > 0) + { + if (strpos($k, '_at') !== false || strpos($k, 'date') !== false || strpos($k, 'time') !== false) + { + $this->query = $this->query->whereBetween($k, $v); + } + else + { + $this->query = $this->query->whereIn($k, $v); + } + } } } + - /** - * Apply conditions on query - * @param string $search - * @param array $columns + /** + * Prepare result to return as response * - * @return mixed + * @return void */ - protected function condition($search, $columns, $type = 'Where') + protected function prepareQueryWithoutOffset() { - return $this->query->where(function ($q) use ($search, $columns) { - $q->where($columns[0], 'LIKE', "%{$search}%"); - return $this->nestedWheres($q,$search); - }); - } + $this->query = $this->query->orderBy($this->columns[$this->order],$this->dir); - /** - * Apply having clause on query - * @param string $search - * @param array $columns - * - * @return mixed - */ - protected function havingCondition($search, $columns ) - { - $this->query->havingRaw("{$columns[0]} LIKE '%{$search}%'"); - return $this->nestedHaving($search); + $this->result = $this->query->get(); } /** - * Return all where conditions to be nested - * - * @param mixed $q - * @param string $search search string + * Prepare result to return as response * - * @return \Illuminate\Database\Eloquent\Builder instance + * @return void */ - protected function nestedWheres($q,$search) + public function prepareQueryWithOffsetAndOrderBy() { - for ($i = 1; $i < count($this->whereColumns); $i++) { - $q->orWhere($this->whereColumns[$i], 'LIKE', "%{$search}%"); - } - return $q; + $this->query = $this->query->offset($this->request->getStart()) + ->limit($this->request->getPerPage()) + ->orderBy($this->columns[$this->order],$this->dir); + $this->result = $this->query->get(); } /** - * Return all having clauses to be nested - * - * @param string $type search string + * Prepare result to return as response * - * @return \Illuminate\Database\Eloquent\Builder instance + * @return void */ - protected function nestedHaving($search) + public function prepareResultWithoutOffsetAndOrderBy() { - for ($i = 1; $i < count($this->havingColumns); $i++) { - $this->query->orHavingRaw("{$this->havingColumns[$i]} LIKE '%{$search}%'"); - } + $this->result = $this->query; } + /** * Initialise Datatable @@ -430,88 +335,7 @@ public function response() */ public function jsonResponse() { - return json_encode($this->response()); - } - - /** - * Add/edit column details of datatable - * - * @param string column name - * @param Closure - * - * @return $this - */ - public function add($column, Closure $closure) - { - foreach ($this->result as $r) { - $r->$column = $closure->call($this, $r); - } - return $this; - } - - /** - * Add/edit column details of datatable - * - * @param string column name - * @param Closure - * - * @return $this - */ - public function edit($column, Closure $closure) - { - return $this->add($column, $closure); - } - - /** - * remove column of datatable - * - * @param string/array - * - * @return $this - */ - public function remove($column) - { - if (is_array($column)) { - foreach ($column as $c) { - foreach ($this->result as $r) { - unset($r->$c); - } - } - } else { - foreach ($this->result as $r) { - unset($r->$column); - } - } - return $this; - } - - /** - * Add/edit details of multiple columns of datatable - * - * @param array $column - * - * @return $this - */ - public function addColumns(array $column) - { - foreach ($column as $c => $cols) { - foreach ($this->result as $r) { - $r->$c = $cols->call($this, $r); - } - } - return $this; - } - - /** - * Add/edit details of multiple columns of datatable - * - * @param array $column - * - * @return $this - */ - public function editColumns(array $column) - { - return $this->addColumns($column); + return response()->json($this->response()); } /** diff --git a/src/Collection.php b/src/Collection.php index b2ca2f8..be7c6d7 100755 --- a/src/Collection.php +++ b/src/Collection.php @@ -37,6 +37,11 @@ public function setQuery($source) { $this->query = $source; + if( $this->request->hasFilters()) + { + $this->setFilters(); + } + $this->prepareResultWithoutOffsetAndOrderBy(); } diff --git a/src/DatatableExportHandler.php b/src/DatatableExportHandler.php new file mode 100644 index 0000000..8b0a55a --- /dev/null +++ b/src/DatatableExportHandler.php @@ -0,0 +1,29 @@ +handler = (new $handler( $source )); + } + + public function init() + { + return $this->handler->response(); + } + + public function handler() + { + return $this->handler; + } + + public function response() + { + return $this->init(); + } +} \ No newline at end of file diff --git a/src/DatatableRequest.php b/src/DatatableRequest.php index 992d458..1f43d52 100644 --- a/src/DatatableRequest.php +++ b/src/DatatableRequest.php @@ -95,7 +95,7 @@ public function getPerPage() */ public function getColumns() { - return $this->request->input('columns'); + return $this->request->input('columns') ?? []; } /** @@ -113,7 +113,37 @@ public function isForExport() */ public function extension() { - return ucfirst($this->request->input('ext') ?? 'Xls'); + return ucfirst($this->request->input('ext') ?? 'xlsx'); + } + + /** + * String to search in datatable + * @return string + */ + public function hasFilters() + { + return $this->request->input('filters')&& !empty($this->request->input('filters')); + } + + /** + * Filters to be applied on table query + * @return array + */ + public function getFilters(){ + $filters = $this->request->input('filters'); + if(gettype($this->request->input('filters')) !== 'array' ) + { + $filters = json_decode($this->request->input('filters'),true) ; + } + $arrayFilters = []; + foreach($filters as $k=>$v) { + if(gettype($v) === 'array') { + $arrayFilters[$k] = $v; + unset($filters[$k]); + } + } + + return [ 'basic' => $filters, 'array' => $arrayFilters ]; } } diff --git a/src/Eloquent.php b/src/Eloquent.php index 223af1f..f663609 100755 --- a/src/Eloquent.php +++ b/src/Eloquent.php @@ -34,6 +34,11 @@ public function setQuery($source) { $this->query = $source->getQuery(); + if( $this->request->hasFilters()) + { + $this->setFilters(); + } + $this->prepareQuery(); } } diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index e2de866..0788a6d 100755 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -34,9 +34,17 @@ public function setQuery($source) { if ($source->columns) { $this->query = $source; + if( $this->request->hasFilters()) + { + $this->setFilters(); + } $this->prepareQuery(); } else { $this->query = $source->get(); + if( $this->request->hasFilters()) + { + $this->setFilters(); + } $this->prepareResultWithoutOffsetAndOrderBy(); } } diff --git a/src/Traits/HasQueryBuilder.php b/src/Traits/HasQueryBuilder.php new file mode 100644 index 0000000..c422fe4 --- /dev/null +++ b/src/Traits/HasQueryBuilder.php @@ -0,0 +1,332 @@ +query->columns) || $this->query->columns[0] === '*' ) + { + $this->query->columns = Schema::getColumnListing( $this->query->from ); + + delete_keys($this->query->columns, $skip); + } + else + { + foreach ( $this->query->columns as $k => $c ) + { + if( gettype($c) == 'string' && strpos($c,'.*')) + { + unset($this->query->columns[$k]); + + $table = explode('.*',$c)[0]; + + $columns = Schema::getColumnListing( $table ); + + delete_keys($columns, $skip); + + array_walk($columns, function(&$value)use($table) { $value = "{$table}.{$value}"; } ); + + $this->query->columns = array_merge( + $this->query->columns, + $columns + ); + } + } + } + + } + + private function identifyGlobalSerachColumnNames() { + + foreach( $this->queryColumns() as $columnName ) + { + if(gettype($columnName) != 'string') + { + $this->globalSearchColumns[] = $columnName; + } + elseif (strpos($columnName, ' as ')) + { + $column = explode(' as ',$columnName); + $this->globalSearchColumns[] = $column[1]; + } + elseif (!strpos($columnName, '_id')) + { + if (strpos($columnName, ' as ')) + { + $column = explode(' as ',$columnName); + $this->globalSearchColumns[] = $column[1]; + + } + else + { + if (isset(explode('.', $columnName)[1])) + { + $column = explode('.',$columnName); + $this->globalSearchColumns[] = $column[1]; + } + else + { + $this->globalSearchColumns[] = $columnName; + } + } + } + } + } + + /** + * Set column names which are displayed on datatables + * + * @return void + */ + protected function setColumns() + { + $this->identifyQueryColumns(); + + if(empty($this->request->getColumns())) + { + $this->identifyGlobalSerachColumnNames(); + + $this->columns = $this->globalSearchColumns; + } + else + { + foreach ($this->request->getColumns() as $c) { + $this->columns[] = $c['data']; + if ($c['searchable'] == 'true') { + $this->globalSearchColumns[] = $c['data']; + if( isset($c['search']['value']) && $c['search']['value'] != ''){ + $this->searchColumns[$c['data']] = $c['search']['value']; + } + } + } + } + } + + /** + * Convert Select Raq Query String TO array of column names/expression + * @param string querySelectString + * */ + protected function extractColumnNamesFromSelectRawQuery($querySelectString) { + return array_map(function($column) { + $column = trim($column); + + if (str_contains($column, '(') && str_contains($column, ')')) { + $column = new Expression($column); + } + return $column; + }, explode(',',$querySelectString)); + } + + /** + * Try to parse queryBuilder object and list all possible column names in array + * @return array + * */ + protected function queryColumns() + { + $columns = $this->query->columns; + + foreach( $columns as $k => $column ) + { + $columnName = $column; + + if(gettype($column) === 'object') + { + $columnName = $column->getValue($this->query->grammar); + + $rawColumns = $this->extractColumnNamesFromSelectRawQuery($columnName); + + unset($columns[$k]); + + $columns = [...$columns, ...$rawColumns]; + } + } + + return $columns; + } + + /** + * Set column names to form the where conditions of query + * + * @return void + */ + protected function setWhereColumns() + { + $columns = $this->queryColumns(); + + if( !empty($this->globalSearchColumns) && $this->request->isSearchable()) + { + $search = $this->request->getSearchString(); + + foreach ($columns as $c) + { + $this->setWhereColumn( $c, $search ); + } + } + + if( !empty($this->searchColumns)) + { + $searchColumns = $this->searchColumns; + $this->searchColumns = []; + + foreach( $columns as $column ) + { + $columnName = $column; + if(gettype($columnName) === 'object'){ $columnName = $columnName->getValue($this->query->grammar);} + foreach ($searchColumns as $key => $search) + { + if (str_contains( $columnName, $key)) + { + $this->searchColumns[] = ['name' => $column, 'search' => $search]; + } + } + } + + $searchColumns = null; + + foreach( $this->searchColumns as $column ) + { + $this->setWhereColumn( $column['name'], $column['search'], false ); + } + } + + } + + /** + * Set query where conditions based on type of column name + * + * @return void + */ + protected function setWhereColumn($columnName, $search, $globalSearch = true) + { + if(gettype($columnName) === 'object'){ + $columnName = $columnName->getValue($this->query->grammar); + if (strpos($columnName, ' as ')) { + $column = explode(' as ', $columnName); + if (!$globalSearch || in_array(trim($column[1]), $this->globalSearchColumns, true)) { + $this->havingColumns[] = [trim($column[1]), $search]; + } + } + } + elseif (!strpos($columnName, '_id')) { + if (strpos($columnName, ' as ')) { + $column = explode(' as ',$columnName); + if (!$globalSearch || in_array(trim($column[1]), $this->globalSearchColumns, true)) { + $this->whereColumns[] = [trim($column[0]), $search]; + } + + } else { + if (isset(explode('.', $columnName)[1])) { + if (!$globalSearch || in_array(explode('.', $columnName)[1], $this->globalSearchColumns, true)) { + $this->whereColumns[] = [trim($columnName), $search]; + } + } else { + $this->whereColumns[] = [trim($columnName), $search]; + } + } + } + } + + /** + * Apply conditions on query + * @param array $columns + * + * @return mixed + */ + protected function condition( $columns ) + { + return $this->query->where(function ($q) use ($columns) { + $q->where($columns[0][0], 'LIKE', "%{$columns[0][1]}%"); + return $this->nestedWheres($q); + }); + } + + /** + * Apply having clause on query + * @param array $columns + * + * @return mixed + */ + protected function havingCondition( $columns ) + { + $this->query->havingRaw("{$columns[0][0]} LIKE '%{$columns[0][1]}%'"); + + $this->nestedHaving(); + } + + /** + * Return all where conditions to be nested + * + * @param mixed $q + * + * @return \Illuminate\Database\Eloquent\Builder instance + */ + protected function nestedWheres($q) + { + for ($i = 1; $i < count($this->whereColumns); $i++) { + $q->orWhere($this->whereColumns[$i][0], 'LIKE', "%{$this->whereColumns[$i][1]}%"); + } + return $q; + } + + /** + * Return all having clauses to be nested + * + * @return \Illuminate\Database\Eloquent\Builder instance + */ + protected function nestedHaving() + { + for ($i = 1; $i < count($this->havingColumns); $i++) { + $this->query->orHavingRaw("{$this->havingColumns[$i][0]} LIKE '%{$this->havingColumns[$i][1]}%'"); + } + } + +} \ No newline at end of file diff --git a/src/Traits/ManagesTableColumns.php b/src/Traits/ManagesTableColumns.php new file mode 100644 index 0000000..adfabf0 --- /dev/null +++ b/src/Traits/ManagesTableColumns.php @@ -0,0 +1,90 @@ +result as $r) { + $r->$column = $closure->call($this, $r); + } + return $this; + } + + /** + * Add/edit column details of datatable + * + * @param string column name + * @param Closure + * + * @return $this + */ + public function edit($column, Closure $closure) + { + return $this->add($column, $closure); + } + + /** + * remove column of datatable + * + * @param string/array + * + * @return $this + */ + public function remove($column) + { + if (is_array($column)) { + foreach ($column as $c) { + foreach ($this->result as $r) { + unset($r->$c); + } + } + } else { + foreach ($this->result as $r) { + unset($r->$column); + } + } + return $this; + } + + /** + * Add/edit details of multiple columns of datatable + * + * @param array $column + * + * @return $this + */ + public function addColumns(array $column) + { + foreach ($column as $c => $cols) { + foreach ($this->result as $r) { + $r->$c = $cols->call($this, $r); + } + } + return $this; + } + + /** + * Add/edit details of multiple columns of datatable + * + * @param array $column + * + * @return $this + */ + public function editColumns(array $column) + { + return $this->addColumns($column); + } + +} \ No newline at end of file diff --git a/src/config/Datatable.php b/src/config/Datatable.php index 871ba68..f471074 100755 --- a/src/config/Datatable.php +++ b/src/config/Datatable.php @@ -11,7 +11,8 @@ | The instance returned by database query must match one of these classes | for datatable to work | - */ + */ + "drivers" => [ '\Illuminate\Database\Eloquent\Builder' => "YS\Datatable\Eloquent", @@ -22,4 +23,45 @@ '\Illuminate\Support\Collection' => 'YS\Datatable\Collection', ], + + + /* + |-------------------------------------------------------------------------- + | Skip + |-------------------------------------------------------------------------- + | + | The column names that you don't want to show in the exported file . + | Default are active and id you can add more columns here or remove + | if you want to show them on exported file + | + */ + + "skip" => [ + 'active', + 'password', + 'remember_token', + 'deleted_at', + '_token', + 'api_token' + ], + + /* + |-------------------------------------------------------------------------- + | Export + |-------------------------------------------------------------------------- + | + | Contains the drivers being used for exporting datatable data + | You can customize this array by specifying your own custom Drivers + | + | Example + | in Request body/query-string you can pass export = true and ext=custom + | and add a new key like 'custom' => Your custim class namespace here + */ + + 'export' => [ + 'csv' => \YS\Export\Csv::class, + 'xls' => \YS\Export\xls::class, + 'xlsx' => \YS\Export\xls::class, + 'json' => \YS\Export\Json::class + ] ];